From 73af69fa04ff3d1eca4465c01d70f0627a3446cb Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Mon, 16 Dec 2024 14:59:11 +0100 Subject: [PATCH] Simplify socket file path selection, only use /tmp --- go/cmd/entrypoint/daemon_util.go | 16 ++++- go/cmd/entrypoint/garage.go | 16 ++++- go/cmd/entrypoint/host.go | 24 ++++++- go/cmd/entrypoint/main.go | 19 +----- go/cmd/entrypoint/main_test.go | 3 +- go/cmd/entrypoint/network.go | 37 ++++++++--- go/cmd/entrypoint/storage_allocation.go | 28 ++++++-- go/cmd/entrypoint/sub_cmd.go | 59 ++++++++++++---- go/cmd/entrypoint/vpn.go | 8 ++- go/cmd/entrypoint/vpn_firewall.go | 43 ++++++++++-- go/cmd/entrypoint/vpn_public_addr.go | 28 ++++++-- go/daemon/config.go | 74 --------------------- go/daemon/daecommon/env.go | 15 +---- go/toolkit/env.go | 12 ++++ tasks/v0.0.3/code/audit-http-socket-dirs.md | 17 ----- 15 files changed, 232 insertions(+), 167 deletions(-) create mode 100644 go/toolkit/env.go delete mode 100644 tasks/v0.0.3/code/audit-http-socket-dirs.md diff --git a/go/cmd/entrypoint/daemon_util.go b/go/cmd/entrypoint/daemon_util.go index 3f415b5..044636f 100644 --- a/go/cmd/entrypoint/daemon_util.go +++ b/go/cmd/entrypoint/daemon_util.go @@ -6,6 +6,7 @@ import ( "fmt" "io/fs" "isle/daemon" + "isle/toolkit" "net" "net/http" "os" @@ -14,14 +15,25 @@ import ( "dev.mediocregopher.com/mediocre-go-lib.git/mlog" ) -const daemonHTTPRPCPath = "/rpc/v0.json" +const ( + daemonHTTPSocketDefaultPath = "/tmp/isle-daemon.sock" + daemonHTTPSocketPathEnvVar = "ISLE_DAEMON_HTTP_SOCKET_PATH" + daemonHTTPRPCPath = "/rpc/v0.json" +) + +func httpSocketPath() string { + return toolkit.EnvOr( + daemonHTTPSocketPathEnvVar, + func() string { return daemonHTTPSocketDefaultPath }, + ) +} func newHTTPServer( ctx context.Context, logger *mlog.Logger, daemonInst *daemon.Daemon, ) ( *http.Server, error, ) { - socketPath := daemon.HTTPSocketPath() + socketPath := httpSocketPath() ctx = mctx.Annotate(ctx, "socketPath", socketPath) if err := os.Remove(socketPath); errors.Is(err, fs.ErrNotExist) { diff --git a/go/cmd/entrypoint/garage.go b/go/cmd/entrypoint/garage.go index 314ca33..7d6c3f9 100644 --- a/go/cmd/entrypoint/garage.go +++ b/go/cmd/entrypoint/garage.go @@ -52,7 +52,13 @@ var subCmdGarageMC = subCmd{ return fmt.Errorf("parsing flags: %w", err) } - clientParams, err := ctx.daemonRPC.GetGarageClientParams(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + clientParams, err := daemonRPC.GetGarageClientParams(ctx) if err != nil { return fmt.Errorf("calling GetGarageClientParams: %w", err) } @@ -124,7 +130,13 @@ var subCmdGarageCLI = subCmd{ return fmt.Errorf("parsing flags: %w", err) } - clientParams, err := ctx.daemonRPC.GetGarageClientParams(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + clientParams, err := daemonRPC.GetGarageClientParams(ctx) if err != nil { return fmt.Errorf("calling GetGarageClientParams: %w", err) } diff --git a/go/cmd/entrypoint/host.go b/go/cmd/entrypoint/host.go index 318f90b..03a4ba2 100644 --- a/go/cmd/entrypoint/host.go +++ b/go/cmd/entrypoint/host.go @@ -40,7 +40,13 @@ var subCmdHostCreate = subCmd{ return errors.New("--hostname is required") } - res, err := ctx.daemonRPC.CreateHost( + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + res, err := daemonRPC.CreateHost( ctx, hostName.V, network.CreateHostOpts{ IP: ip.V, CanCreateHosts: *canCreateHosts, @@ -63,7 +69,13 @@ var subCmdHostList = subCmd{ return nil, fmt.Errorf("parsing flags: %w", err) } - currBoostrap, err := ctx.daemonRPC.GetBootstrap(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return nil, fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + currBoostrap, err := daemonRPC.GetBootstrap(ctx) if err != nil { return nil, fmt.Errorf("calling GetBootstrap: %w", err) } @@ -131,7 +143,13 @@ var subCmdHostRemove = subCmd{ return errors.New("--hostname is required") } - if err := ctx.daemonRPC.RemoveHost(ctx, hostName.V); err != nil { + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + if err := daemonRPC.RemoveHost(ctx, hostName.V); err != nil { return fmt.Errorf("calling RemoveHost: %w", err) } diff --git a/go/cmd/entrypoint/main.go b/go/cmd/entrypoint/main.go index c6121b3..1c8b65c 100644 --- a/go/cmd/entrypoint/main.go +++ b/go/cmd/entrypoint/main.go @@ -3,8 +3,6 @@ package main import ( "context" "fmt" - "isle/daemon" - "isle/daemon/jsonrpc2" "isle/toolkit" "os" "os/signal" @@ -66,10 +64,9 @@ var rootCmd = subCmd{ func doRootCmd( ctx context.Context, logger *mlog.Logger, - daemonRPC daemon.RPC, opts *subCmdCtxOpts, ) error { - subCmdCtx := newSubCmdCtx(ctx, logger, daemonRPC, rootCmd, opts) + subCmdCtx := newSubCmdCtx(ctx, logger, rootCmd, opts) return subCmdCtx.subCmd.do(subCmdCtx) } @@ -95,19 +92,7 @@ func main() { 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 { + if err := doRootCmd(ctx, logger, nil); err != nil { fmt.Fprintln(os.Stderr, err) } } diff --git a/go/cmd/entrypoint/main_test.go b/go/cmd/entrypoint/main_test.go index 4adb7d0..9d44c7d 100644 --- a/go/cmd/entrypoint/main_test.go +++ b/go/cmd/entrypoint/main_test.go @@ -58,10 +58,11 @@ func (h *runHarness) run(t *testing.T, args ...string) error { jsonrpc2.NewHTTPClient(httpClient, h.daemonRPCServer.URL), ) - return doRootCmd(h.ctx, h.logger, daemonRPCClient, &subCmdCtxOpts{ + return doRootCmd(h.ctx, h.logger, &subCmdCtxOpts{ args: args, stdout: h.stdout, changeStager: h.changeStager, + daemonRPC: daemonRPCClient, }) } diff --git a/go/cmd/entrypoint/network.go b/go/cmd/entrypoint/network.go index 291eb03..a17333f 100644 --- a/go/cmd/entrypoint/network.go +++ b/go/cmd/entrypoint/network.go @@ -58,7 +58,13 @@ var subCmdNetworkCreate = subCmd{ return errors.New("--name, --domain, --ip-net, and --hostname are required") } - err = ctx.daemonRPC.CreateNetwork( + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + err = daemonRPC.CreateNetwork( ctx, *name, *domain, ipNet.V, hostName.V, ) if err != nil { @@ -95,7 +101,13 @@ var subCmdNetworkJoin = subCmd{ ) } - return ctx.daemonRPC.JoinNetwork(ctx, newBootstrap) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + return daemonRPC.JoinNetwork(ctx, newBootstrap) }, } @@ -110,7 +122,13 @@ var subCmdNetworkList = subCmd{ return nil, fmt.Errorf("parsing flags: %w", err) } - networkCreationParams, err := ctx.daemonRPC.GetNetworks(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return nil, fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + networkCreationParams, err := daemonRPC.GetNetworks(ctx) if err != nil { return nil, fmt.Errorf("calling GetNetworks: %w", err) } @@ -127,10 +145,7 @@ var subCmdNetworkList = subCmd{ Lighthouses []lighthouseView `yaml:"lighthouses"` } - var ( - daemonRPC = ctx.daemonRPC - networkViews = make([]networkView, len(networkCreationParams)) - ) + networkViews := make([]networkView, len(networkCreationParams)) for i, creationParams := range networkCreationParams { ctx := daemon.WithNetwork(ctx, creationParams.ID) @@ -191,7 +206,13 @@ var subCmdNetworkGetConfig = subCmd{ return nil, fmt.Errorf("parsing flags: %w", err) } - return ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return nil, fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + return daemonRPC.GetConfig(ctx) }), } diff --git a/go/cmd/entrypoint/storage_allocation.go b/go/cmd/entrypoint/storage_allocation.go index de2d969..d332c2a 100644 --- a/go/cmd/entrypoint/storage_allocation.go +++ b/go/cmd/entrypoint/storage_allocation.go @@ -98,14 +98,20 @@ var subCmdStorageAllocationAdd = subCmd{ ) } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return fmt.Errorf("getting network config: %w", err) } config.Storage.Allocations = append(config.Storage.Allocations, alloc) - if err := ctx.daemonRPC.SetConfig(ctx, config); err != nil { + if err := daemonRPC.SetConfig(ctx, config); err != nil { return fmt.Errorf("updating the network config: %w", err) } @@ -122,7 +128,13 @@ var subCmdStorageAllocationList = subCmd{ return nil, fmt.Errorf("parsing flags: %w", err) } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return nil, fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return nil, fmt.Errorf("getting network config: %w", err) } @@ -152,7 +164,13 @@ var subCmdStorageAllocationRemove = subCmd{ return errors.New("At least one --index must be specified") } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return fmt.Errorf("getting network config: %w", err) } @@ -186,7 +204,7 @@ var subCmdStorageAllocationRemove = subCmd{ ) config.Storage.Allocations = newAllocs - if err := ctx.daemonRPC.SetConfig(ctx, config); err != nil { + if err := daemonRPC.SetConfig(ctx, config); err != nil { return fmt.Errorf("updating the network config: %w", err) } diff --git a/go/cmd/entrypoint/sub_cmd.go b/go/cmd/entrypoint/sub_cmd.go index a479b5b..63017dc 100644 --- a/go/cmd/entrypoint/sub_cmd.go +++ b/go/cmd/entrypoint/sub_cmd.go @@ -6,7 +6,9 @@ import ( "fmt" "io" "isle/daemon" + "isle/daemon/jsonrpc2" "isle/jsonutil" + "isle/toolkit" "os" "strings" @@ -37,6 +39,7 @@ type subCmdCtxOpts struct { subCmdNames []string // names of subCmds so far, including this one stdout io.Writer changeStager *changeStager + daemonRPC daemon.RPC } func (o *subCmdCtxOpts) withDefaults() *subCmdCtxOpts { @@ -58,10 +61,9 @@ func (o *subCmdCtxOpts) withDefaults() *subCmdCtxOpts { // subCmdCtx contains all information available to a subCmd's do method. type subCmdCtx struct { context.Context - logger *mlog.Logger - daemonRPC daemon.RPC - subCmd subCmd // the subCmd itself - opts *subCmdCtxOpts + logger *mlog.Logger + subCmd subCmd // the subCmd itself + opts *subCmdCtxOpts flags *pflag.FlagSet } @@ -69,22 +71,55 @@ type subCmdCtx struct { func newSubCmdCtx( ctx context.Context, logger *mlog.Logger, - daemonRPC daemon.RPC, subCmd subCmd, opts *subCmdCtxOpts, ) subCmdCtx { opts = opts.withDefaults() return subCmdCtx{ - Context: ctx, - logger: logger, - daemonRPC: daemonRPC, - subCmd: subCmd, - opts: opts, - flags: pflag.NewFlagSet(subCmd.name, pflag.ExitOnError), + Context: ctx, + logger: logger, + subCmd: subCmd, + opts: opts, + flags: pflag.NewFlagSet(subCmd.name, pflag.ExitOnError), } } +type daemonRPCCloser struct { + daemon.RPC + Close func() error +} + +func (ctx subCmdCtx) newDaemonRPC() (*daemonRPCCloser, error) { + if ctx.opts.daemonRPC != nil { + return &daemonRPCCloser{ + ctx.opts.daemonRPC, func() error { return nil }, + }, nil + } + + socketPath := httpSocketPath() + if stat, err := os.Stat(socketPath); err != nil { + return nil, fmt.Errorf("checking http socket file: %w", err) + } else if stat.Mode().Type() != os.ModeSocket { + return nil, fmt.Errorf("%q exists but is not a socket", socketPath) + } + + httpClient, baseURL := toolkit.NewUnixHTTPClient( + ctx.logger.WithNamespace("http-client"), + socketPath, + ) + + baseURL.Path = daemonHTTPRPCPath + + daemonRPC := daemon.RPCFromClient( + jsonrpc2.NewHTTPClient(httpClient, baseURL.String()), + ) + + return &daemonRPCCloser{ + daemonRPC, func() error { return httpClient.Close() }, + }, nil +} + func (ctx subCmdCtx) getChangeStager() *changeStager { if ctx.opts.changeStager != nil { return ctx.opts.changeStager @@ -258,7 +293,7 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error { nextSubCmdCtxOpts.subCmdNames = append(ctx.opts.subCmdNames, subCmdName) nextSubCmdCtx := newSubCmdCtx( - ctx.Context, ctx.logger, ctx.daemonRPC, subCmd, &nextSubCmdCtxOpts, + ctx.Context, ctx.logger, subCmd, &nextSubCmdCtxOpts, ) if err := subCmd.do(nextSubCmdCtx); err != nil { diff --git a/go/cmd/entrypoint/vpn.go b/go/cmd/entrypoint/vpn.go index 75e27af..06faa70 100644 --- a/go/cmd/entrypoint/vpn.go +++ b/go/cmd/entrypoint/vpn.go @@ -43,7 +43,13 @@ var subCmdVPNCreateCert = subCmd{ return fmt.Errorf("unmarshaling public key as PEM: %w", err) } - res, err := ctx.daemonRPC.CreateNebulaCertificate( + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + res, err := daemonRPC.CreateNebulaCertificate( ctx, hostName.V, hostPub, ) if err != nil { diff --git a/go/cmd/entrypoint/vpn_firewall.go b/go/cmd/entrypoint/vpn_firewall.go index 5250f1f..05357fd 100644 --- a/go/cmd/entrypoint/vpn_firewall.go +++ b/go/cmd/entrypoint/vpn_firewall.go @@ -3,6 +3,7 @@ package main import ( "errors" "fmt" + "isle/daemon" "isle/daemon/daecommon" "slices" "strings" @@ -14,8 +15,12 @@ const vpnFirewallConfigChangeStagerName = "vpn-firewall-config" // vpnFirewallGetConfigWithStaged returns the network config along with any // staged firewall configuration changes, if there are any. -func vpnFirewallGetConfig(ctx subCmdCtx) (daecommon.NetworkConfig, error) { - config, err := ctx.daemonRPC.GetConfig(ctx) +func vpnFirewallGetConfig( + ctx subCmdCtx, daemonRPC daemon.RPC, +) ( + daecommon.NetworkConfig, error, +) { + config, err := daemonRPC.GetConfig(ctx) if err != nil { return daecommon.NetworkConfig{}, err } @@ -110,7 +115,13 @@ var subCmdVPNFirewallAdd = subCmd{ rule.Host = "any" } - config, err := vpnFirewallGetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := vpnFirewallGetConfig(ctx, daemonRPC) if err != nil { return fmt.Errorf("getting network config: %w", err) } @@ -151,14 +162,20 @@ var subCmdVPNFirewallCommit = subCmd{ return errors.New("no changes staged, use 'add' or 'remove' to stage changes") } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return fmt.Errorf("getting network config: %w", err) } config.VPN.Firewall = firewallConfig - return ctx.daemonRPC.SetConfig(ctx, config) + return daemonRPC.SetConfig(ctx, config) }, } @@ -192,6 +209,12 @@ var subCmdVPNFirewallRemove = subCmd{ return fmt.Errorf("invalid --from value %q: %w", *from, err) } + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + indexSet := map[int]struct{}{} for _, index := range *indexes { if index < 0 { @@ -200,7 +223,7 @@ var subCmdVPNFirewallRemove = subCmd{ indexSet[index] = struct{}{} } - config, err := vpnFirewallGetConfig(ctx) + config, err := vpnFirewallGetConfig(ctx, daemonRPC) if err != nil { return fmt.Errorf("getting network config: %w", err) } @@ -309,7 +332,13 @@ var subCmdVPNFirewallShow = subCmd{ } if !foundStaged { - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return nil, fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return nil, fmt.Errorf("getting network config: %w", err) } diff --git a/go/cmd/entrypoint/vpn_public_addr.go b/go/cmd/entrypoint/vpn_public_addr.go index d51d357..109eafc 100644 --- a/go/cmd/entrypoint/vpn_public_addr.go +++ b/go/cmd/entrypoint/vpn_public_addr.go @@ -15,7 +15,13 @@ var subCmdVPNPublicAddressGet = subCmd{ return nil, fmt.Errorf("parsing flags: %w", err) } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return nil, fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return nil, fmt.Errorf("getting network config: %w", err) } @@ -49,14 +55,20 @@ var subCmdVPNPublicAddressSet = subCmd{ return fmt.Errorf("invalid --public-addr: %w", err) } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return fmt.Errorf("getting network config: %w", err) } config.VPN.PublicAddr = *publicAddr - return ctx.daemonRPC.SetConfig(ctx, config) + return daemonRPC.SetConfig(ctx, config) }, } @@ -69,14 +81,20 @@ var subCmdVPNPublicAddressUnset = subCmd{ return fmt.Errorf("parsing flags: %w", err) } - config, err := ctx.daemonRPC.GetConfig(ctx) + daemonRPC, err := ctx.newDaemonRPC() + if err != nil { + return fmt.Errorf("creating daemon RPC client: %w", err) + } + defer daemonRPC.Close() + + config, err := daemonRPC.GetConfig(ctx) if err != nil { return fmt.Errorf("getting network config: %w", err) } config.VPN.PublicAddr = "" - return ctx.daemonRPC.SetConfig(ctx, config) + return daemonRPC.SetConfig(ctx, config) }, } diff --git a/go/daemon/config.go b/go/daemon/config.go index 8097f39..b717eb1 100644 --- a/go/daemon/config.go +++ b/go/daemon/config.go @@ -2,46 +2,12 @@ package daemon import ( "context" - "errors" "fmt" - "io/fs" "isle/bootstrap" "isle/daemon/daecommon" "isle/daemon/network" - "os" - "path/filepath" - "slices" - "strings" - "sync" ) -func getDefaultHTTPSocketDirPath() string { - path, err := firstExistingDir( - "/tmp", - "/run", - "/var/run", - "/dev/shm", - ) - if err != nil { - panic(fmt.Sprintf("Failed to find directory for HTTP socket: %v", err)) - } - - return path -} - -// HTTPSocketPath returns the path to the daemon's HTTP socket which is used for -// RPC and other functionality. -var HTTPSocketPath = sync.OnceValue(func() string { - return envOr( - "ISLE_DAEMON_HTTP_SOCKET_PATH", - func() string { - return filepath.Join( - getDefaultHTTPSocketDirPath(), "isle-daemon.sock", - ) - }, - ) -}) - func pickNetworkConfig( networkConfigs map[string]daecommon.NetworkConfig, creationParams bootstrap.CreationParams, @@ -88,43 +54,3 @@ func validateConfig( return daemonConfig.Validate() } - -//////////////////////////////////////////////////////////////////////////////// -// Jigs - -func envOr(name string, fallback func() string) string { - if v := os.Getenv(name); v != "" { - return v - } - return fallback() -} - -func firstExistingDir(paths ...string) (string, error) { - var errs []error - for _, path := range paths { - stat, err := os.Stat(path) - switch { - case errors.Is(err, fs.ErrExist): - continue - case err != nil: - errs = append( - errs, fmt.Errorf("checking if path %q exists: %w", path, err), - ) - case !stat.IsDir(): - errs = append( - errs, fmt.Errorf("path %q exists but is not a directory", path), - ) - default: - return path, nil - } - } - - err := fmt.Errorf( - "no directory found at any of the following paths: %s", - strings.Join(paths, ", "), - ) - if len(errs) > 0 { - err = errors.Join(slices.Insert(errs, 0, err)...) - } - return "", err -} diff --git a/go/daemon/daecommon/env.go b/go/daemon/daecommon/env.go index ec5bdaf..4136984 100644 --- a/go/daemon/daecommon/env.go +++ b/go/daemon/daecommon/env.go @@ -2,7 +2,6 @@ package daecommon import ( "isle/toolkit" - "os" "path/filepath" "sync" @@ -25,12 +24,12 @@ var GetEnvVars = sync.OnceValue(func() EnvVars { var ( res EnvVars - stateDirPath = envOr( + stateDirPath = toolkit.EnvOr( "STATE_DIRECTORY", func() string { return filepath.Join(xdg.StateHome, "isle") }, ) - runtimeDirPath = envOr( + runtimeDirPath = toolkit.EnvOr( "RUNTIME_DIRECTORY", func() string { return filepath.Join(xdg.RuntimeDir, "isle") }, ) @@ -46,13 +45,3 @@ var GetEnvVars = sync.OnceValue(func() EnvVars { return res }) - -//////////////////////////////////////////////////////////////////////////////// -// Jigs - -func envOr(name string, fallback func() string) string { - if v := os.Getenv(name); v != "" { - return v - } - return fallback() -} diff --git a/go/toolkit/env.go b/go/toolkit/env.go new file mode 100644 index 0000000..11f08f2 --- /dev/null +++ b/go/toolkit/env.go @@ -0,0 +1,12 @@ +package toolkit + +import "os" + +// EnvOr returns the value of the given environment variable, or the return of +// the given callback if the environment variable isn't set. +func EnvOr(name string, fallback func() string) string { + if v := os.Getenv(name); v != "" { + return v + } + return fallback() +} diff --git a/tasks/v0.0.3/code/audit-http-socket-dirs.md b/tasks/v0.0.3/code/audit-http-socket-dirs.md deleted file mode 100644 index 85ce8aa..0000000 --- a/tasks/v0.0.3/code/audit-http-socket-dirs.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -type: task ---- - -# Audit HTTP Socket Directory Search Options - -We are currently searching these directories for the first writeable one, within -which to create the socket file: - -- /tmp -- /run -- /var/run -- /dev/shm - -It would be ideal to not default to `/tmp`, but it seems that some of the others -aren't necessarily available always, or aren't readable/writeable by the `isle` -user.