package main import ( "context" "fmt" "isle/daemon" "isle/daemon/jsonrpc2" "isle/toolkit" "os" "os/signal" "path/filepath" "sync" "syscall" "dev.mediocregopher.com/mediocre-go-lib.git/mctx" "dev.mediocregopher.com/mediocre-go-lib.git/mlog" "github.com/adrg/xdg" ) func getAppDirPath() string { appDirPath := os.Getenv("APPDIR") if appDirPath == "" { appDirPath = "." } return appDirPath } var ( envAppDirPath = getAppDirPath() envBinDirPath = filepath.Join(envAppDirPath, "bin") envCacheDir = sync.OnceValue(func() toolkit.Dir { cacheHome, err := toolkit.MkDir(xdg.CacheHome, true) if err != nil { panic(fmt.Errorf("creating cache directory %q: %w", xdg.CacheHome, err)) } cacheDir, err := cacheHome.MkChildDir("isle", true) if err != nil { panic(fmt.Errorf("creating isle cache directory: %w", err)) } return cacheDir }) ) func binPath(name string) string { return filepath.Join(envBinDirPath, name) } var rootCmd = subCmd{ name: "isle", descr: "All Isle sub-commands", noNetwork: true, do: func(ctx subCmdCtx) error { return ctx.doSubCmd( subCmdDaemon, subCmdGarage, subCmdHost, subCmdNetwork, subCmdStorage, subCmdVersion, subCmdVPN, ) }, } func doRootCmd( ctx context.Context, logger *mlog.Logger, daemonRPC daemon.RPC, opts *subCmdCtxOpts, ) error { subCmdCtx := newSubCmdCtx(ctx, logger, daemonRPC, rootCmd, opts) return subCmdCtx.subCmd.do(subCmdCtx) } func main() { logger := mlog.NewLogger(nil) defer logger.Close() ctx, cancel := context.WithCancel(context.Background()) signalCh := make(chan os.Signal, 2) signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-signalCh cancel() ctx := mctx.Annotate(ctx, "signal", sig.String()) logger.Info(ctx, "got signal, exiting gracefully") sig = <-signalCh ctx = mctx.Annotate(ctx, "signal", sig.String()) logger.FatalString(ctx, "second signal received, force quitting, there may be zombie children left behind, good luck!") }() httpClient, baseURL := toolkit.NewUnixHTTPClient( logger.WithNamespace("http-client"), daemon.HTTPSocketPath(), ) defer httpClient.Close() baseURL.Path = daemonHTTPRPCPath daemonRPC := daemon.RPCFromClient( jsonrpc2.NewHTTPClient(httpClient, baseURL.String()), ) if err := doRootCmd(ctx, logger, daemonRPC, nil); err != nil { fmt.Fprintln(os.Stderr, err) } }