Skip to content

Commit

Permalink
feat: preliminary implementation os sites 2.0 (#1417)
Browse files Browse the repository at this point in the history
Server initialization and lots of other details.

---------

Co-authored-by: juligasa <[email protected]>
Co-authored-by: Eric Vicenti <[email protected]>
  • Loading branch information
3 people authored Sep 20, 2023
1 parent c377cfd commit c04b67a
Show file tree
Hide file tree
Showing 151 changed files with 4,752 additions and 9,966 deletions.
2 changes: 1 addition & 1 deletion .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export VITE_BACKEND_HTTP_PORT='55002'
export VITE_BACKEND_GRPC_PORT="56002"
export VITE_BACKEND_P2P_PORT="56003"

export NEXT_PUBLIC_GRPC_HOST="https://gateway.mintter.com"
export NEXT_PUBLIC_GRPC_HOST="http://localhost:57001"
# export NEXT_PUBLIC_GRPC_HOST="http://localhost:56001"
export NEXT_PUBLIC_LN_HOST="https://ln.mintter.com"
export MINTTER_IS_GATEWAY="1"
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/generate-docker-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push mintter-site
uses: docker/build-push-action@v4
with:
push: true
file: backend/cmd/mintter-site/Dockerfile
tags: mintter/mintter-site:latest
- name: Build and push mintterd
uses: docker/build-push-action@v4
with:
Expand Down
16 changes: 10 additions & 6 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ issues:
exclude-rules:
# Unused parameter warnings are annoying in tests.
- path: _test\.go
linters: ['revive']
text: 'unused-parameter'
linters: ["revive"]
text: "unused-parameter"
# For test helpers it's often convenient to pass *testing.T as the first parameter.
# We don't care if context is not the first argument here.
- path: _test\.go
text: 'context-as-argument'
linters: ['revive']
text: "context-as-argument"
linters: ["revive"]
# In tests we can use math/rand instead of crypto/rand.
- path: _test\.go
text: 'weak random number generator'
linters: ['gosec']
text: "weak random number generator"
linters: ["gosec"]
# Get rid of the annoying "if-return" rule.
# It gets in the way as soon as you decide to wrap the last error instead of returning it.
- text: "if-return"
linters: ["revive"]
include:
# Include revive rules that check comments on exported identifiers. These rules
# are excluded by default, and IMHO this doesn't serve well the Go community.
Expand Down
2 changes: 1 addition & 1 deletion backend/BUILD.plz
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ go_binary(
["**/*.go"],
exclude = ["**/*_test.go"],
) + [
"//backend/cmd/mintter-site/sitesql:go_library",
"//backend/daemon/storage:go_library",
"//backend/hyper/hypersql:go_library",
"//backend/lndhub/lndhubsql:go_library",
"//backend/mttnet/sitesql:go_library",
"//backend/wallet/walletsql:go_library",
],
out = "mintterd-" + target_platform_triple(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Build from the root with `docker build . -f ./backend/cmd/minttergw/Dockerfile`.
# Build from the root with `docker build . -f ./backend/cmd/mintter-site/Dockerfile`.
FROM golang:1.20-alpine AS builder
WORKDIR /code
COPY go.mod go.sum ./
COPY third_party ./third_party
RUN go mod download
COPY backend ./backend
RUN apk add build-base
RUN go install ./backend/cmd/minttergw/
RUN go install ./backend/cmd/mintter-site/

FROM alpine:latest
COPY --from=builder /go/bin/minttergw /usr/local/bin/minttergw
COPY --from=builder /go/bin/mintter-site /usr/local/bin/mintter-site
EXPOSE 55000 55001 55002
CMD ["/usr/local/bin/minttergw"]
CMD ["/usr/local/bin/mintter-site"]
77 changes: 77 additions & 0 deletions backend/cmd/mintter-site/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Program mintter-site implements the Hypermedia Site server.
package main

import (
"context"
"errors"
"flag"
"fmt"
"os"

"mintter/backend/cmd/mintter-site/sites"
"mintter/backend/daemon"

"github.com/burdiyan/go/mainutil"
"github.com/peterbourgon/ff/v3"
)

func main() {
const envVarPrefix = "MINTTER"

mainutil.Run(func() error {
ctx := mainutil.TrapSignals()

fs := flag.NewFlagSet("mintter-site", flag.ExitOnError)
fs.Usage = func() {
fmt.Fprintf(fs.Output(), `Usage: %s ADDRESS [flags]
This program is similar to our main mintterd program in a lot of ways, but has more suitable defaults for running on a server as site.
It requires one positional argument ADDRESS, which has to be a Web network address this site is supposed to be available at.
The address can be a DNS name, or an IP address, and it has to be a URL with a scheme and port (if applicable).
Examples:
- http://127.0.0.1:42542
- https://mintter.com
- http://example.com
Flags:
`, fs.Name())
fs.PrintDefaults()
}

cfg := sites.DefaultConfig()
cfg.BindFlags(fs)
if err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarPrefix(envVarPrefix)); err != nil {
return err
}

if len(os.Args) < 2 {
fs.Usage()
fmt.Fprintf(fs.Output(), "Error: Positional argument ADDRESS is missing.\n")
os.Exit(1)
}

rawURL := os.Args[1]

if err := cfg.Base.ExpandDataDir(); err != nil {
return err
}

dir, err := daemon.InitRepo(cfg.Base.DataDir, nil)
if err != nil {
return err
}

app, err := sites.Load(ctx, rawURL, cfg, dir)
if err != nil {
return err
}

err = app.Wait()
if errors.Is(err, context.Canceled) {
return nil
}

return err
})
}
14 changes: 14 additions & 0 deletions backend/cmd/mintter-site/sites/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package sites

import "mintter/backend/config"

// DefaultConfig for sites.
func DefaultConfig() config.Config {
cfg := config.Default()
cfg.DataDir = "~/.mintter-site"
cfg.Syncing.Disabled = true
cfg.P2P.ForceReachabilityPublic = true
cfg.P2P.NoRelay = true

return cfg
}
106 changes: 106 additions & 0 deletions backend/cmd/mintter-site/sites/daemon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package sites

import (
"context"
"errors"
"fmt"
"mintter/backend/config"
"mintter/backend/core"
"mintter/backend/daemon"
"mintter/backend/daemon/storage"
accounts "mintter/backend/genproto/accounts/v1alpha"
"mintter/backend/ipfs"
"mintter/backend/mttnet"
"mintter/backend/pkg/future"
"mintter/backend/pkg/must"
"net/url"

"crawshaw.io/sqlite/sqlitex"
)

// App is the site daemon app.
type App struct {
*daemon.App

Website *Website
Address *url.URL
Config config.Config
}

// Load the site daemon.
func Load(ctx context.Context, address string, cfg config.Config, dir *storage.Dir) (*App, error) {
u, err := url.Parse(address)
if err != nil {
return nil, fmt.Errorf("failed to parse address: %w", err)
}

if u.Scheme != "http" && u.Scheme != "https" {
return nil, fmt.Errorf("address URL only supports http or https: got %q", address)
}

if u.Path != "" {
return nil, fmt.Errorf("address URL must not have a path: %s", address)
}

cfg.P2P.AnnounceAddrs = must.Do2(
ipfs.ParseMultiaddrs(
ipfs.DefaultListenAddrsDNS(u.Hostname(), cfg.P2P.Port)))

nf := future.New[*mttnet.Node]()
ndb := future.New[*sqlitex.Pool]()
site := NewServer(address, nf.ReadOnly, ndb.ReadOnly)

app, err := daemon.Load(ctx, cfg, dir, site, daemon.GenericHandler{
Path: "/.well-known/hypermedia-site",
Handler: site,
Mode: daemon.RouteNav,
})
if err != nil {
return nil, err
}

// This is some ugly stuff. Site server needs some stuff that are passed from the daemon.
go func() {
if err := ndb.Resolve(app.DB); err != nil {
panic(err)
}

node, err := app.Net.Await(ctx)
if err != nil && !errors.Is(err, context.Canceled) {
panic(err)
}

if err := nf.Resolve(node); err != nil {
panic(err)
}
}()

if _, ok := dir.Identity().Get(); !ok {
account, err := core.NewKeyPairRandom()
if err != nil {
return nil, fmt.Errorf("failed to generate random account key pair: %w", err)
}

if err := app.RPC.Daemon.RegisterAccount(ctx, account); err != nil {
return nil, fmt.Errorf("failed to create registration: %w", err)
}
}

if _, err := app.RPC.Accounts.UpdateProfile(ctx, &accounts.Profile{
Alias: address,
Bio: "Hypermedia Site. Powered by Mintter.",
}); err != nil {
return nil, fmt.Errorf("failed to update profile: %w", err)
}

setupURL := site.GetSetupURL(ctx)

fmt.Println("Site Invitation secret token: " + setupURL)

return &App{
App: app,
Website: site,
Address: u,
Config: cfg,
}, nil
}
Loading

0 comments on commit c04b67a

Please sign in to comment.