Factor out crypticnet.Env completely

This commit is contained in:
Brian Picciano 2022-10-27 00:37:03 +02:00
parent b23a4cafa6
commit 28159608c8
13 changed files with 88 additions and 140 deletions

View File

@ -84,10 +84,8 @@ var subCmdAdminCreateNetwork = subCmd{
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
env := subCmdCtx.env
if *dumpConfig { if *dumpConfig {
return daemon.CopyDefaultConfig(os.Stdout, env.AppDirPath) return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
} }
if *domain == "" || *subnetStr == "" || *hostName == "" { if *domain == "" || *subnetStr == "" || *hostName == "" {
@ -111,7 +109,7 @@ var subCmdAdminCreateNetwork = subCmd{
} }
{ {
runtimeDirPath := env.RuntimeDirPath runtimeDirPath := envRuntimeDirPath
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath) fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath)
@ -129,7 +127,7 @@ var subCmdAdminCreateNetwork = subCmd{
}() }()
} }
daemonConfig, err := daemon.LoadConfig(env.AppDirPath, *daemonConfigPath) daemonConfig, err := daemon.LoadConfig(envAppDirPath, *daemonConfigPath)
if err != nil { if err != nil {
return fmt.Errorf("loading daemon config: %w", err) return fmt.Errorf("loading daemon config: %w", err)
} }
@ -165,16 +163,16 @@ var subCmdAdminCreateNetwork = subCmd{
GarageGlobalBucketS3APICredentials: garage.NewS3APICredentials(), GarageGlobalBucketS3APICredentials: garage.NewS3APICredentials(),
} }
if hostBootstrap, err = mergeDaemonConfigIntoBootstrap(env, hostBootstrap, daemonConfig); err != nil { if hostBootstrap, err = mergeDaemonConfigIntoBootstrap(hostBootstrap, daemonConfig); err != nil {
return fmt.Errorf("merging daemon config into bootstrap data: %w", err) return fmt.Errorf("merging daemon config into bootstrap data: %w", err)
} }
nebulaPmuxProcConfig, err := nebulaPmuxProcConfig(env, hostBootstrap, daemonConfig) nebulaPmuxProcConfig, err := nebulaPmuxProcConfig(hostBootstrap, daemonConfig)
if err != nil { if err != nil {
return fmt.Errorf("generating nebula config: %w", err) return fmt.Errorf("generating nebula config: %w", err)
} }
garagePmuxProcConfigs, err := garagePmuxProcConfigs(env, hostBootstrap, daemonConfig) garagePmuxProcConfigs, err := garagePmuxProcConfigs(hostBootstrap, daemonConfig)
if err != nil { if err != nil {
return fmt.Errorf("generating garage configs: %w", err) return fmt.Errorf("generating garage configs: %w", err)
} }
@ -188,7 +186,7 @@ var subCmdAdminCreateNetwork = subCmd{
), ),
} }
ctx, cancel := context.WithCancel(env.Context) ctx, cancel := context.WithCancel(subCmdCtx.ctx)
pmuxDoneCh := make(chan struct{}) pmuxDoneCh := make(chan struct{})
fmt.Fprintln(os.Stderr, "starting child processes") fmt.Fprintln(os.Stderr, "starting child processes")
@ -269,9 +267,7 @@ var subCmdAdminMakeBootstrap = subCmd{
return errors.New("--name and --admin-path are required") return errors.New("--name and --admin-path are required")
} }
env := subCmdCtx.env hostBootstrap, err := loadHostBootstrap()
hostBootstrap, err := loadHostBootstrap(env.DataDirPath)
if err != nil { if err != nil {
return fmt.Errorf("loading host bootstrap: %w", err) return fmt.Errorf("loading host bootstrap: %w", err)
} }
@ -287,7 +283,7 @@ var subCmdAdminMakeBootstrap = subCmd{
// command for this host has been run recently then it might not have // command for this host has been run recently then it might not have
// made it into the bootstrap file yet, and so won't be in // made it into the bootstrap file yet, and so won't be in
// `hostBootstrap`. // `hostBootstrap`.
hosts, err := bootstrap.GetGarageBootstrapHosts(env.Context, client) hosts, err := bootstrap.GetGarageBootstrapHosts(subCmdCtx.ctx, client)
if err != nil { if err != nil {
return fmt.Errorf("retrieving host info from garage: %w", err) return fmt.Errorf("retrieving host info from garage: %w", err)
} }

View File

@ -9,9 +9,9 @@ import (
"path/filepath" "path/filepath"
) )
func loadHostBootstrap(dataDirPath string) (bootstrap.Bootstrap, error) { func loadHostBootstrap() (bootstrap.Bootstrap, error) {
dataDirPath = bootstrap.DataDirPath(dataDirPath) dataDirPath := bootstrap.DataDirPath(envDataDirPath)
hostBootstrap, err := bootstrap.FromFile(dataDirPath) hostBootstrap, err := bootstrap.FromFile(dataDirPath)
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
@ -24,9 +24,9 @@ func loadHostBootstrap(dataDirPath string) (bootstrap.Bootstrap, error) {
return hostBootstrap, nil return hostBootstrap, nil
} }
func writeBootstrapToDataDir(dataDirPath string, hostBootstrap bootstrap.Bootstrap) error { func writeBootstrapToDataDir(hostBootstrap bootstrap.Bootstrap) error {
path := bootstrap.DataDirPath(dataDirPath) path := bootstrap.DataDirPath(envDataDirPath)
dirPath := filepath.Dir(path) dirPath := filepath.Dir(path)
if err := os.MkdirAll(dirPath, 0700); err != nil { if err := os.MkdirAll(dirPath, 0700); err != nil {

View File

@ -41,14 +41,14 @@ import (
// the new bootstrap file is different than the existing one, the existing one // the new bootstrap file is different than the existing one, the existing one
// is overwritten and true is returned. // is overwritten and true is returned.
func reloadBootstrap( func reloadBootstrap(
env crypticnet.Env, ctx context.Context,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
s3Client garage.S3APIClient, s3Client garage.S3APIClient,
) ( ) (
bootstrap.Bootstrap, bool, error, bootstrap.Bootstrap, bool, error,
) { ) {
newHosts, err := bootstrap.GetGarageBootstrapHosts(env.Context, s3Client) newHosts, err := bootstrap.GetGarageBootstrapHosts(ctx, s3Client)
if err != nil { if err != nil {
return bootstrap.Bootstrap{}, false, fmt.Errorf("getting hosts from garage: %w", err) return bootstrap.Bootstrap{}, false, fmt.Errorf("getting hosts from garage: %w", err)
} }
@ -69,7 +69,7 @@ func reloadBootstrap(
newHostBootstrap := hostBootstrap.WithHosts(newHosts) newHostBootstrap := hostBootstrap.WithHosts(newHosts)
if err := writeBootstrapToDataDir(env.DataDirPath, newHostBootstrap); err != nil { if err := writeBootstrapToDataDir(newHostBootstrap); err != nil {
return bootstrap.Bootstrap{}, false, fmt.Errorf("writing new bootstrap.tgz to data dir: %w", err) return bootstrap.Bootstrap{}, false, fmt.Errorf("writing new bootstrap.tgz to data dir: %w", err)
} }
@ -81,7 +81,7 @@ func reloadBootstrap(
// until the spawned pmux has returned, and returns a copy of hostBootstrap with // until the spawned pmux has returned, and returns a copy of hostBootstrap with
// updated boostrap info. // updated boostrap info.
func runDaemonPmuxOnce( func runDaemonPmuxOnce(
env crypticnet.Env, ctx context.Context,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
daemonConfig daemon.Config, daemonConfig daemon.Config,
) ( ) (
@ -96,17 +96,17 @@ func runDaemonPmuxOnce(
// endpoint. // endpoint.
s3Client := hostBootstrap.GlobalBucketS3APIClient() s3Client := hostBootstrap.GlobalBucketS3APIClient()
nebulaPmuxProcConfig, err := nebulaPmuxProcConfig(env, hostBootstrap, daemonConfig) nebulaPmuxProcConfig, err := nebulaPmuxProcConfig(hostBootstrap, daemonConfig)
if err != nil { if err != nil {
return bootstrap.Bootstrap{}, fmt.Errorf("generating nebula config: %w", err) return bootstrap.Bootstrap{}, fmt.Errorf("generating nebula config: %w", err)
} }
dnsmasqPmuxProcConfig, err := dnsmasqPmuxProcConfig(env, hostBootstrap, daemonConfig) dnsmasqPmuxProcConfig, err := dnsmasqPmuxProcConfig(hostBootstrap, daemonConfig)
if err != nil { if err != nil {
return bootstrap.Bootstrap{}, fmt.Errorf("generating dnsmasq config: %w", err) return bootstrap.Bootstrap{}, fmt.Errorf("generating dnsmasq config: %w", err)
} }
garagePmuxProcConfigs, err := garagePmuxProcConfigs(env, hostBootstrap, daemonConfig) garagePmuxProcConfigs, err := garagePmuxProcConfigs(hostBootstrap, daemonConfig)
if err != nil { if err != nil {
return bootstrap.Bootstrap{}, fmt.Errorf("generating garage children configs: %w", err) return bootstrap.Bootstrap{}, fmt.Errorf("generating garage children configs: %w", err)
} }
@ -121,12 +121,12 @@ func runDaemonPmuxOnce(
), ),
} }
doneCh := env.Context.Done() doneCh := ctx.Done()
var wg sync.WaitGroup var wg sync.WaitGroup
defer wg.Wait() defer wg.Wait()
ctx, cancel := context.WithCancel(env.Context) ctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()
wg.Add(1) wg.Add(1)
@ -184,7 +184,7 @@ func runDaemonPmuxOnce(
select { select {
case <-doneCh: case <-doneCh:
return bootstrap.Bootstrap{}, env.Context.Err() return bootstrap.Bootstrap{}, ctx.Err()
case <-ticker.C: case <-ticker.C:
@ -195,7 +195,7 @@ func runDaemonPmuxOnce(
err error err error
) )
if hostBootstrap, changed, err = reloadBootstrap(env, hostBootstrap, s3Client); err != nil { if hostBootstrap, changed, err = reloadBootstrap(ctx, hostBootstrap, s3Client); err != nil {
return bootstrap.Bootstrap{}, fmt.Errorf("reloading bootstrap: %w", err) return bootstrap.Bootstrap{}, fmt.Errorf("reloading bootstrap: %w", err)
} else if changed { } else if changed {
@ -232,13 +232,11 @@ var subCmdDaemon = subCmd{
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
env := subCmdCtx.env
if *dumpConfig { if *dumpConfig {
return daemon.CopyDefaultConfig(os.Stdout, env.AppDirPath) return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
} }
runtimeDirPath := env.RuntimeDirPath runtimeDirPath := envRuntimeDirPath
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath) fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath)
@ -260,8 +258,8 @@ var subCmdDaemon = subCmd{
}() }()
var ( var (
bootstrapDataDirPath = bootstrap.DataDirPath(env.DataDirPath) bootstrapDataDirPath = bootstrap.DataDirPath(envDataDirPath)
bootstrapAppDirPath = bootstrap.AppDirPath(env.AppDirPath) bootstrapAppDirPath = bootstrap.AppDirPath(envAppDirPath)
hostBootstrapPath string hostBootstrapPath string
hostBootstrap bootstrap.Bootstrap hostBootstrap bootstrap.Bootstrap
@ -302,12 +300,12 @@ var subCmdDaemon = subCmd{
// If the bootstrap file is not being stored in the data dir, copy // If the bootstrap file is not being stored in the data dir, copy
// it there, so it can be loaded from there next time. // it there, so it can be loaded from there next time.
if err := writeBootstrapToDataDir(env.DataDirPath, hostBootstrap); err != nil { if err := writeBootstrapToDataDir(hostBootstrap); err != nil {
return fmt.Errorf("writing bootstrap.tgz to data dir: %w", err) return fmt.Errorf("writing bootstrap.tgz to data dir: %w", err)
} }
} }
daemonConfig, err := daemon.LoadConfig(env.AppDirPath, *daemonConfigPath) daemonConfig, err := daemon.LoadConfig(envAppDirPath, *daemonConfigPath)
if err != nil { if err != nil {
return fmt.Errorf("loading daemon config: %w", err) return fmt.Errorf("loading daemon config: %w", err)
} }
@ -317,13 +315,13 @@ var subCmdDaemon = subCmd{
// up-to-date possible bootstrap. This updated bootstrap will later get // up-to-date possible bootstrap. This updated bootstrap will later get
// updated in garage using bootstrap.PutGarageBoostrapHost, so other // updated in garage using bootstrap.PutGarageBoostrapHost, so other
// hosts will see it as well. // hosts will see it as well.
if hostBootstrap, err = mergeDaemonConfigIntoBootstrap(env, hostBootstrap, daemonConfig); err != nil { if hostBootstrap, err = mergeDaemonConfigIntoBootstrap(hostBootstrap, daemonConfig); err != nil {
return fmt.Errorf("merging daemon config into bootstrap data: %w", err) return fmt.Errorf("merging daemon config into bootstrap data: %w", err)
} }
for { for {
hostBootstrap, err = runDaemonPmuxOnce(env, hostBootstrap, daemonConfig) hostBootstrap, err = runDaemonPmuxOnce(subCmdCtx.ctx, hostBootstrap, daemonConfig)
if errors.Is(err, context.Canceled) { if errors.Is(err, context.Canceled) {
return nil return nil

View File

@ -2,7 +2,6 @@ package main
import ( import (
"context" "context"
crypticnet "cryptic-net"
"cryptic-net/bootstrap" "cryptic-net/bootstrap"
"cryptic-net/daemon" "cryptic-net/daemon"
"fmt" "fmt"
@ -10,7 +9,6 @@ import (
) )
func mergeDaemonConfigIntoBootstrap( func mergeDaemonConfigIntoBootstrap(
env crypticnet.Env,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
daemonConfig daemon.Config, daemonConfig daemon.Config,
) ( ) (
@ -36,7 +34,7 @@ func mergeDaemonConfigIntoBootstrap(
hostBootstrap.Hosts[host.Name] = host hostBootstrap.Hosts[host.Name] = host
if err := writeBootstrapToDataDir(env.DataDirPath, hostBootstrap); err != nil { if err := writeBootstrapToDataDir(hostBootstrap); err != nil {
return bootstrap.Bootstrap{}, fmt.Errorf("writing bootstrap file: %w", err) return bootstrap.Bootstrap{}, fmt.Errorf("writing bootstrap file: %w", err)
} }

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
crypticnet "cryptic-net"
"cryptic-net/bootstrap" "cryptic-net/bootstrap"
"cryptic-net/daemon" "cryptic-net/daemon"
"cryptic-net/dnsmasq" "cryptic-net/dnsmasq"
@ -13,14 +12,13 @@ import (
) )
func dnsmasqPmuxProcConfig( func dnsmasqPmuxProcConfig(
env crypticnet.Env,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
daemonConfig daemon.Config, daemonConfig daemon.Config,
) ( ) (
pmuxlib.ProcessConfig, error, pmuxlib.ProcessConfig, error,
) { ) {
confPath := filepath.Join(env.RuntimeDirPath, "dnsmasq.conf") confPath := filepath.Join(envRuntimeDirPath, "dnsmasq.conf")
hostsSlice := make([]bootstrap.Host, 0, len(hostBootstrap.Hosts)) hostsSlice := make([]bootstrap.Host, 0, len(hostBootstrap.Hosts))
for _, host := range hostBootstrap.Hosts { for _, host := range hostBootstrap.Hosts {

View File

@ -28,9 +28,7 @@ var subCmdGarageMC = subCmd{
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
env := subCmdCtx.env hostBootstrap, err := loadHostBootstrap()
hostBootstrap, err := loadHostBootstrap(env.DataDirPath)
if err != nil { if err != nil {
return fmt.Errorf("loading host bootstrap: %w", err) return fmt.Errorf("loading host bootstrap: %w", err)
} }
@ -88,9 +86,7 @@ var subCmdGarageCLI = subCmd{
checkLock: true, checkLock: true,
do: func(subCmdCtx subCmdCtx) error { do: func(subCmdCtx subCmdCtx) error {
env := subCmdCtx.env hostBootstrap, err := loadHostBootstrap()
hostBootstrap, err := loadHostBootstrap(env.DataDirPath)
if err != nil { if err != nil {
return fmt.Errorf("loading host bootstrap: %w", err) return fmt.Errorf("loading host bootstrap: %w", err)
} }

View File

@ -2,7 +2,6 @@ package main
import ( import (
"context" "context"
crypticnet "cryptic-net"
"cryptic-net/bootstrap" "cryptic-net/bootstrap"
"cryptic-net/daemon" "cryptic-net/daemon"
"cryptic-net/garage" "cryptic-net/garage"
@ -68,7 +67,6 @@ func waitForGarageAndNebula(
} }
func garageWriteChildConfig( func garageWriteChildConfig(
env crypticnet.Env,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
alloc daemon.ConfigStorageAllocation, alloc daemon.ConfigStorageAllocation,
) ( ) (
@ -100,7 +98,7 @@ func garageWriteChildConfig(
} }
garageTomlPath := filepath.Join( garageTomlPath := filepath.Join(
env.RuntimeDirPath, fmt.Sprintf("garage-%d.toml", alloc.RPCPort), envRuntimeDirPath, fmt.Sprintf("garage-%d.toml", alloc.RPCPort),
) )
err := garage.WriteGarageTomlFile(garageTomlPath, garage.GarageTomlData{ err := garage.WriteGarageTomlFile(garageTomlPath, garage.GarageTomlData{
@ -125,7 +123,6 @@ func garageWriteChildConfig(
} }
func garagePmuxProcConfigs( func garagePmuxProcConfigs(
env crypticnet.Env,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
daemonConfig daemon.Config, daemonConfig daemon.Config,
) ( ) (
@ -136,7 +133,7 @@ func garagePmuxProcConfigs(
for _, alloc := range daemonConfig.Storage.Allocations { for _, alloc := range daemonConfig.Storage.Allocations {
childConfigPath, err := garageWriteChildConfig(env, hostBootstrap, alloc) childConfigPath, err := garageWriteChildConfig(hostBootstrap, alloc)
if err != nil { if err != nil {
return nil, fmt.Errorf("writing child config file for alloc %+v: %w", alloc, err) return nil, fmt.Errorf("writing child config file for alloc %+v: %w", alloc, err)

View File

@ -59,9 +59,7 @@ var subCmdHostsAdd = subCmd{
// TODO validate that the IP is in the correct CIDR // TODO validate that the IP is in the correct CIDR
env := subCmdCtx.env hostBootstrap, err := loadHostBootstrap()
hostBootstrap, err := loadHostBootstrap(env.DataDirPath)
if err != nil { if err != nil {
return fmt.Errorf("loading host bootstrap: %w", err) return fmt.Errorf("loading host bootstrap: %w", err)
} }
@ -75,7 +73,7 @@ var subCmdHostsAdd = subCmd{
}, },
} }
return bootstrap.PutGarageBoostrapHost(env.Context, client, host) return bootstrap.PutGarageBoostrapHost(subCmdCtx.ctx, client, host)
}, },
} }
@ -85,16 +83,14 @@ var subCmdHostsList = subCmd{
checkLock: true, checkLock: true,
do: func(subCmdCtx subCmdCtx) error { do: func(subCmdCtx subCmdCtx) error {
env := subCmdCtx.env hostBootstrap, err := loadHostBootstrap()
hostBootstrap, err := loadHostBootstrap(env.DataDirPath)
if err != nil { if err != nil {
return fmt.Errorf("loading host bootstrap: %w", err) return fmt.Errorf("loading host bootstrap: %w", err)
} }
client := hostBootstrap.GlobalBucketS3APIClient() client := hostBootstrap.GlobalBucketS3APIClient()
hostsMap, err := bootstrap.GetGarageBootstrapHosts(env.Context, client) hostsMap, err := bootstrap.GetGarageBootstrapHosts(subCmdCtx.ctx, client)
if err != nil { if err != nil {
return fmt.Errorf("retrieving hosts from garage: %w", err) return fmt.Errorf("retrieving hosts from garage: %w", err)
} }
@ -131,16 +127,14 @@ var subCmdHostsDelete = subCmd{
return errors.New("--name is required") return errors.New("--name is required")
} }
env := subCmdCtx.env hostBootstrap, err := loadHostBootstrap()
hostBootstrap, err := loadHostBootstrap(env.DataDirPath)
if err != nil { if err != nil {
return fmt.Errorf("loading host bootstrap: %w", err) return fmt.Errorf("loading host bootstrap: %w", err)
} }
client := hostBootstrap.GlobalBucketS3APIClient() client := hostBootstrap.GlobalBucketS3APIClient()
return bootstrap.RemoveGarageBootstrapHost(env.Context, client, *name) return bootstrap.RemoveGarageBootstrapHost(subCmdCtx.ctx, client, *name)
}, },
} }

View File

@ -1,9 +1,14 @@
package main package main
import ( import (
"context"
"fmt"
"os" "os"
"os/signal"
"path/filepath"
"syscall"
crypticnet "cryptic-net" "github.com/adrg/xdg"
) )
// The purpose of this binary is to act as the entrypoint of the cryptic-net // The purpose of this binary is to act as the entrypoint of the cryptic-net
@ -11,13 +16,42 @@ import (
// then passes execution along to an appropriate binary housed in AppDir/bin // then passes execution along to an appropriate binary housed in AppDir/bin
// (usually a bash script, which is more versatile than a go program). // (usually a bash script, which is more versatile than a go program).
func getAppDirPath() string {
appDirPath := os.Getenv("APPDIR")
if appDirPath == "" {
appDirPath = "."
}
return appDirPath
}
var (
envAppDirPath = getAppDirPath()
envRuntimeDirPath = filepath.Join(xdg.RuntimeDir, "cryptic-net")
envDataDirPath = filepath.Join(xdg.DataHome, "cryptic-net")
)
func main() { func main() {
env := crypticnet.NewEnv() ctx, cancel := context.WithCancel(context.Background())
signalCh := make(chan os.Signal, 2)
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-signalCh
cancel()
fmt.Fprintf(os.Stderr, "got signal %v, will exit gracefully\n", sig)
sig = <-signalCh
fmt.Fprintf(os.Stderr, "second interrupt signal %v received, force quitting, there may be zombie children left behind, good luck!\n", sig)
os.Stderr.Sync()
os.Exit(1)
}()
err := subCmdCtx{ err := subCmdCtx{
args: os.Args[1:], args: os.Args[1:],
env: env, ctx: ctx,
}.doSubCmd( }.doSubCmd(
subCmdAdmin, subCmdAdmin,
subCmdDaemon, subCmdDaemon,

View File

@ -2,7 +2,6 @@ package main
import ( import (
"context" "context"
crypticnet "cryptic-net"
"cryptic-net/bootstrap" "cryptic-net/bootstrap"
"cryptic-net/daemon" "cryptic-net/daemon"
"cryptic-net/yamlutil" "cryptic-net/yamlutil"
@ -36,7 +35,6 @@ func waitForNebula(ctx context.Context, hostBootstrap bootstrap.Bootstrap) error
} }
func nebulaPmuxProcConfig( func nebulaPmuxProcConfig(
env crypticnet.Env,
hostBootstrap bootstrap.Bootstrap, hostBootstrap bootstrap.Bootstrap,
daemonConfig daemon.Config, daemonConfig daemon.Config,
) ( ) (
@ -105,7 +103,7 @@ func nebulaPmuxProcConfig(
} }
} }
nebulaYmlPath := filepath.Join(env.RuntimeDirPath, "nebula.yml") nebulaYmlPath := filepath.Join(envRuntimeDirPath, "nebula.yml")
if err := yamlutil.WriteYamlFile(config, nebulaYmlPath); err != nil { if err := yamlutil.WriteYamlFile(config, nebulaYmlPath); err != nil {
return pmuxlib.ProcessConfig{}, fmt.Errorf("writing nebula.yml to %q: %w", nebulaYmlPath, err) return pmuxlib.ProcessConfig{}, fmt.Errorf("writing nebula.yml to %q: %w", nebulaYmlPath, err)

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"context"
crypticnet "cryptic-net" crypticnet "cryptic-net"
"fmt" "fmt"
"os" "os"
@ -14,7 +15,8 @@ type subCmdCtx struct {
subCmd subCmd // the subCmd itself subCmd subCmd // the subCmd itself
args []string // command-line arguments, excluding the subCmd itself. args []string // command-line arguments, excluding the subCmd itself.
subCmdNames []string // names of subCmds so far, including this one subCmdNames []string // names of subCmds so far, including this one
env crypticnet.Env
ctx context.Context
} }
type subCmd struct { type subCmd struct {
@ -99,7 +101,7 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
if subCmd.checkLock { if subCmd.checkLock {
err := crypticnet.NewProcLock(ctx.env.RuntimeDirPath).AssertLock() err := crypticnet.NewProcLock(envRuntimeDirPath).AssertLock()
if err != nil { if err != nil {
return fmt.Errorf("checking lock file: %w", err) return fmt.Errorf("checking lock file: %w", err)
@ -110,7 +112,7 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
subCmd: subCmd, subCmd: subCmd,
args: args, args: args,
subCmdNames: append(ctx.subCmdNames, subCmdName), subCmdNames: append(ctx.subCmdNames, subCmdName),
env: ctx.env, ctx: ctx.ctx,
}) })
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ var subCmdVersion = subCmd{
descr: "Dumps version and build info to stdout", descr: "Dumps version and build info to stdout",
do: func(subCmdCtx subCmdCtx) error { do: func(subCmdCtx subCmdCtx) error {
versionPath := filepath.Join(subCmdCtx.env.AppDirPath, "share/version") versionPath := filepath.Join(envAppDirPath, "share/version")
version, err := os.ReadFile(versionPath) version, err := os.ReadFile(versionPath)

View File

@ -1,63 +0,0 @@
package crypticnet
import (
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
"github.com/adrg/xdg"
)
// Env contains the values of environment variables, as well as other entities
// which are useful across all processes.
type Env struct {
Context context.Context
AppDirPath string
RuntimeDirPath string
DataDirPath string
}
func getAppDirPath() string {
appDirPath := os.Getenv("APPDIR")
if appDirPath == "" {
appDirPath = "."
}
return appDirPath
}
// NewEnv calculates an Env instance based on the APPDIR and XDG envvars.
func NewEnv() Env {
runtimeDirPath := filepath.Join(xdg.RuntimeDir, "cryptic-net")
appDirPath := getAppDirPath()
env := Env{
AppDirPath: appDirPath,
RuntimeDirPath: runtimeDirPath,
DataDirPath: filepath.Join(xdg.DataHome, "cryptic-net"),
}
var cancel context.CancelFunc
env.Context, cancel = context.WithCancel(context.Background())
signalCh := make(chan os.Signal, 2)
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-signalCh
cancel()
fmt.Fprintf(os.Stderr, "got signal %v, will exit gracefully\n", sig)
sig = <-signalCh
fmt.Fprintf(os.Stderr, "second interrupt signal %v received, force quitting, there may be zombie children left behind, good luck!\n", sig)
os.Stderr.Sync()
os.Exit(1)
}()
return env
}