package main import ( "flag" "log" "os" "path/filepath" "strings" "vppn/peer" "git.crumpington.com/lib/go/flock" ) func main() { log.SetFlags(0) name := flag.String("name", "", "network name (required)") hub := flag.String("hub", "", "hub base URL (required)") flag.Parse() if *name == "" || *hub == "" { flag.Usage() os.Exit(1) } apiKey, err := loadAPIKey(*name) if err != nil { log.Fatalf("api key: %v", err) } // Directory existence is guaranteed by the apikey file read above. lockFile, err := flock.TryLock(vppnPath(*name, "lock")) if err != nil { log.Fatalf("lock: %v", err) } if lockFile == nil { log.Fatalf("already running for network %q", *name) } defer flock.Unlock(lockFile) state, err := peer.LoadOrInit(vppnPath(*name, "state.json"), *hub, apiKey) if err != nil { log.Fatalf("init: %v", err) } ifaceName := strings.TrimSuffix(state.LocalDomain, ".local") app, err := peer.New(state, *hub, apiKey, ifaceName, state.LocalDomain, vppnPath(*name, "network.json")) if err != nil { log.Fatalf("start: %v", err) } if err := app.Run(); err != nil { log.Fatalf("run: %v", err) } } func loadAPIKey(name string) (string, error) { data, err := os.ReadFile(vppnPath(name, "apikey")) if err != nil { return "", err } return strings.TrimSpace(string(data)), nil } func vppnPath(name, file string) string { home, err := os.UserHomeDir() if err != nil { return filepath.Join(".vppn", name, file) } return filepath.Join(home, ".vppn", name, file) }