diff --git a/.gitignore b/.gitignore index 15e9ba7..d5f19d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ node_modules package-lock.json -golink diff --git a/build.sh b/build.sh index 4e5f2a3..a5abcae 100755 --- a/build.sh +++ b/build.sh @@ -8,7 +8,7 @@ export PATH=$(readlink -f $(dirname $0)/../../tool):$PATH go run github.com/tailscale/mkctr \ --target="flyio" \ --base="alpine:3.15" \ - --gopaths="tailscale.io/cmd/golink:/tsgo" \ + --gopaths="github.com/tailscale/golink/cmd/golink:/tsgo" \ --tags="latest" \ --repos="registry.fly.io/tsgo" \ --push \ diff --git a/link-snapshot.json b/cmd/golink/link-snapshot.json similarity index 100% rename from link-snapshot.json rename to cmd/golink/link-snapshot.json diff --git a/cmd/golink/main.go b/cmd/golink/main.go new file mode 100644 index 0000000..d766a48 --- /dev/null +++ b/cmd/golink/main.go @@ -0,0 +1,19 @@ +// The golink server runs http://go/, a private shortlink service for tailnets. +package main + +import ( + _ "embed" + "log" + + "github.com/tailscale/golink" +) + +//go:embed link-snapshot.json +var lastSnapshot []byte + +func main() { + golink.LastSnapshot = lastSnapshot + if err := golink.Run(); err != nil { + log.Fatal(err) + } +} diff --git a/db.go b/db.go index 97309de..11bd82a 100644 --- a/db.go +++ b/db.go @@ -1,4 +1,4 @@ -package main +package golink import ( "context" diff --git a/db_test.go b/db_test.go index 099a1ec..b267b77 100644 --- a/db_test.go +++ b/db_test.go @@ -1,4 +1,4 @@ -package main +package golink import ( "path" diff --git a/golink.go b/golink.go index 697be55..1b26d5f 100644 --- a/golink.go +++ b/golink.go @@ -1,5 +1,5 @@ // The golink server runs http://go/, a private shortlink service for tailnets. -package main +package golink import ( "bufio" @@ -43,8 +43,9 @@ var stats struct { dirty ClickStats } -//go:embed link-snapshot.json -var lastSnapshot []byte +// LastSnapshot is the data snapshot (as returned by the /.export handler) +// that will be loaded on startup. +var LastSnapshot []byte //go:embed static tmpl/*.html var embeddedFS embed.FS @@ -54,25 +55,25 @@ var db *SQLiteDB var localClient *tailscale.LocalClient -func main() { +func Run() error { flag.Parse() if *sqlitefile == "" { if devMode() { tmpdir, err := ioutil.TempDir("", "golink_dev_*") if err != nil { - log.Fatal(err) + return err } *sqlitefile = filepath.Join(tmpdir, "golink.db") log.Printf("Dev mode temp db: %s", *sqlitefile) } else { - log.Fatalf("--sqlitedb is required") + return errors.New("--sqlitedb is required") } } var err error if db, err = NewSQLiteDB(*sqlitefile); err != nil { - log.Fatalf("NewSQLiteDB(%q): %v", *sqlitefile, err) + return fmt.Errorf("NewSQLiteDB(%q): %w", *sqlitefile, err) } if err := restoreLastSnapshot(); err != nil { @@ -105,19 +106,20 @@ func main() { srv.Logf = log.Printf } if err := srv.Start(); err != nil { - log.Fatal(err) + return err } localClient, _ = srv.LocalClient() l80, err := srv.Listen("tcp", ":80") if err != nil { - log.Fatal(err) + return err } log.Printf("Serving http://go/ ...") if err := http.Serve(l80, nil); err != nil { - log.Fatal(err) + return err } + return nil } var ( @@ -520,7 +522,7 @@ func serveExport(w http.ResponseWriter, r *http.Request) { } func restoreLastSnapshot() error { - bs := bufio.NewScanner(bytes.NewReader(lastSnapshot)) + bs := bufio.NewScanner(bytes.NewReader(LastSnapshot)) var restored int for bs.Scan() { link := new(Link) diff --git a/golink_test.go b/golink_test.go index 6f0de30..788896e 100644 --- a/golink_test.go +++ b/golink_test.go @@ -1,4 +1,4 @@ -package main +package golink import ( "testing"