Simplify socket file path selection, only use /tmp
This commit is contained in:
parent
4151fe8f17
commit
73af69fa04
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"isle/daemon"
|
"isle/daemon"
|
||||||
|
"isle/toolkit"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -14,14 +15,25 @@ import (
|
|||||||
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
"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(
|
func newHTTPServer(
|
||||||
ctx context.Context, logger *mlog.Logger, daemonInst *daemon.Daemon,
|
ctx context.Context, logger *mlog.Logger, daemonInst *daemon.Daemon,
|
||||||
) (
|
) (
|
||||||
*http.Server, error,
|
*http.Server, error,
|
||||||
) {
|
) {
|
||||||
socketPath := daemon.HTTPSocketPath()
|
socketPath := httpSocketPath()
|
||||||
ctx = mctx.Annotate(ctx, "socketPath", socketPath)
|
ctx = mctx.Annotate(ctx, "socketPath", socketPath)
|
||||||
|
|
||||||
if err := os.Remove(socketPath); errors.Is(err, fs.ErrNotExist) {
|
if err := os.Remove(socketPath); errors.Is(err, fs.ErrNotExist) {
|
||||||
|
@ -52,7 +52,13 @@ var subCmdGarageMC = subCmd{
|
|||||||
return fmt.Errorf("parsing flags: %w", err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("calling GetGarageClientParams: %w", err)
|
return fmt.Errorf("calling GetGarageClientParams: %w", err)
|
||||||
}
|
}
|
||||||
@ -124,7 +130,13 @@ var subCmdGarageCLI = subCmd{
|
|||||||
return fmt.Errorf("parsing flags: %w", err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("calling GetGarageClientParams: %w", err)
|
return fmt.Errorf("calling GetGarageClientParams: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,13 @@ var subCmdHostCreate = subCmd{
|
|||||||
return errors.New("--hostname is required")
|
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{
|
ctx, hostName.V, network.CreateHostOpts{
|
||||||
IP: ip.V,
|
IP: ip.V,
|
||||||
CanCreateHosts: *canCreateHosts,
|
CanCreateHosts: *canCreateHosts,
|
||||||
@ -63,7 +69,13 @@ var subCmdHostList = subCmd{
|
|||||||
return nil, fmt.Errorf("parsing flags: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("calling GetBootstrap: %w", err)
|
return nil, fmt.Errorf("calling GetBootstrap: %w", err)
|
||||||
}
|
}
|
||||||
@ -131,7 +143,13 @@ var subCmdHostRemove = subCmd{
|
|||||||
return errors.New("--hostname is required")
|
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)
|
return fmt.Errorf("calling RemoveHost: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"isle/daemon"
|
|
||||||
"isle/daemon/jsonrpc2"
|
|
||||||
"isle/toolkit"
|
"isle/toolkit"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -66,10 +64,9 @@ var rootCmd = subCmd{
|
|||||||
func doRootCmd(
|
func doRootCmd(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
daemonRPC daemon.RPC,
|
|
||||||
opts *subCmdCtxOpts,
|
opts *subCmdCtxOpts,
|
||||||
) error {
|
) error {
|
||||||
subCmdCtx := newSubCmdCtx(ctx, logger, daemonRPC, rootCmd, opts)
|
subCmdCtx := newSubCmdCtx(ctx, logger, rootCmd, opts)
|
||||||
return subCmdCtx.subCmd.do(subCmdCtx)
|
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!")
|
logger.FatalString(ctx, "second signal received, force quitting, there may be zombie children left behind, good luck!")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
httpClient, baseURL := toolkit.NewUnixHTTPClient(
|
if err := doRootCmd(ctx, logger, nil); err != nil {
|
||||||
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)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,11 @@ func (h *runHarness) run(t *testing.T, args ...string) error {
|
|||||||
jsonrpc2.NewHTTPClient(httpClient, h.daemonRPCServer.URL),
|
jsonrpc2.NewHTTPClient(httpClient, h.daemonRPCServer.URL),
|
||||||
)
|
)
|
||||||
|
|
||||||
return doRootCmd(h.ctx, h.logger, daemonRPCClient, &subCmdCtxOpts{
|
return doRootCmd(h.ctx, h.logger, &subCmdCtxOpts{
|
||||||
args: args,
|
args: args,
|
||||||
stdout: h.stdout,
|
stdout: h.stdout,
|
||||||
changeStager: h.changeStager,
|
changeStager: h.changeStager,
|
||||||
|
daemonRPC: daemonRPCClient,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,13 @@ var subCmdNetworkCreate = subCmd{
|
|||||||
return errors.New("--name, --domain, --ip-net, and --hostname are required")
|
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,
|
ctx, *name, *domain, ipNet.V, hostName.V,
|
||||||
)
|
)
|
||||||
if err != nil {
|
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)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("calling GetNetworks: %w", err)
|
return nil, fmt.Errorf("calling GetNetworks: %w", err)
|
||||||
}
|
}
|
||||||
@ -127,10 +145,7 @@ var subCmdNetworkList = subCmd{
|
|||||||
Lighthouses []lighthouseView `yaml:"lighthouses"`
|
Lighthouses []lighthouseView `yaml:"lighthouses"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
networkViews := make([]networkView, len(networkCreationParams))
|
||||||
daemonRPC = ctx.daemonRPC
|
|
||||||
networkViews = make([]networkView, len(networkCreationParams))
|
|
||||||
)
|
|
||||||
|
|
||||||
for i, creationParams := range networkCreationParams {
|
for i, creationParams := range networkCreationParams {
|
||||||
ctx := daemon.WithNetwork(ctx, creationParams.ID)
|
ctx := daemon.WithNetwork(ctx, creationParams.ID)
|
||||||
@ -191,7 +206,13 @@ var subCmdNetworkGetConfig = subCmd{
|
|||||||
return nil, fmt.Errorf("parsing flags: %w", err)
|
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)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
return fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Storage.Allocations = append(config.Storage.Allocations, alloc)
|
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)
|
return fmt.Errorf("updating the network config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +128,13 @@ var subCmdStorageAllocationList = subCmd{
|
|||||||
return nil, fmt.Errorf("parsing flags: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getting network config: %w", err)
|
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")
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
return fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
@ -186,7 +204,7 @@ var subCmdStorageAllocationRemove = subCmd{
|
|||||||
)
|
)
|
||||||
|
|
||||||
config.Storage.Allocations = newAllocs
|
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)
|
return fmt.Errorf("updating the network config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"isle/daemon"
|
"isle/daemon"
|
||||||
|
"isle/daemon/jsonrpc2"
|
||||||
"isle/jsonutil"
|
"isle/jsonutil"
|
||||||
|
"isle/toolkit"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -37,6 +39,7 @@ type subCmdCtxOpts struct {
|
|||||||
subCmdNames []string // names of subCmds so far, including this one
|
subCmdNames []string // names of subCmds so far, including this one
|
||||||
stdout io.Writer
|
stdout io.Writer
|
||||||
changeStager *changeStager
|
changeStager *changeStager
|
||||||
|
daemonRPC daemon.RPC
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *subCmdCtxOpts) withDefaults() *subCmdCtxOpts {
|
func (o *subCmdCtxOpts) withDefaults() *subCmdCtxOpts {
|
||||||
@ -59,7 +62,6 @@ func (o *subCmdCtxOpts) withDefaults() *subCmdCtxOpts {
|
|||||||
type subCmdCtx struct {
|
type subCmdCtx struct {
|
||||||
context.Context
|
context.Context
|
||||||
logger *mlog.Logger
|
logger *mlog.Logger
|
||||||
daemonRPC daemon.RPC
|
|
||||||
subCmd subCmd // the subCmd itself
|
subCmd subCmd // the subCmd itself
|
||||||
opts *subCmdCtxOpts
|
opts *subCmdCtxOpts
|
||||||
|
|
||||||
@ -69,7 +71,6 @@ type subCmdCtx struct {
|
|||||||
func newSubCmdCtx(
|
func newSubCmdCtx(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
logger *mlog.Logger,
|
||||||
daemonRPC daemon.RPC,
|
|
||||||
subCmd subCmd,
|
subCmd subCmd,
|
||||||
opts *subCmdCtxOpts,
|
opts *subCmdCtxOpts,
|
||||||
) subCmdCtx {
|
) subCmdCtx {
|
||||||
@ -78,13 +79,47 @@ func newSubCmdCtx(
|
|||||||
return subCmdCtx{
|
return subCmdCtx{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
daemonRPC: daemonRPC,
|
|
||||||
subCmd: subCmd,
|
subCmd: subCmd,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
flags: pflag.NewFlagSet(subCmd.name, pflag.ExitOnError),
|
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 {
|
func (ctx subCmdCtx) getChangeStager() *changeStager {
|
||||||
if ctx.opts.changeStager != nil {
|
if ctx.opts.changeStager != nil {
|
||||||
return ctx.opts.changeStager
|
return ctx.opts.changeStager
|
||||||
@ -258,7 +293,7 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
|
|||||||
nextSubCmdCtxOpts.subCmdNames = append(ctx.opts.subCmdNames, subCmdName)
|
nextSubCmdCtxOpts.subCmdNames = append(ctx.opts.subCmdNames, subCmdName)
|
||||||
|
|
||||||
nextSubCmdCtx := newSubCmdCtx(
|
nextSubCmdCtx := newSubCmdCtx(
|
||||||
ctx.Context, ctx.logger, ctx.daemonRPC, subCmd, &nextSubCmdCtxOpts,
|
ctx.Context, ctx.logger, subCmd, &nextSubCmdCtxOpts,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := subCmd.do(nextSubCmdCtx); err != nil {
|
if err := subCmd.do(nextSubCmdCtx); err != nil {
|
||||||
|
@ -43,7 +43,13 @@ var subCmdVPNCreateCert = subCmd{
|
|||||||
return fmt.Errorf("unmarshaling public key as PEM: %w", err)
|
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,
|
ctx, hostName.V, hostPub,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"isle/daemon"
|
||||||
"isle/daemon/daecommon"
|
"isle/daemon/daecommon"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
@ -14,8 +15,12 @@ const vpnFirewallConfigChangeStagerName = "vpn-firewall-config"
|
|||||||
|
|
||||||
// vpnFirewallGetConfigWithStaged returns the network config along with any
|
// vpnFirewallGetConfigWithStaged returns the network config along with any
|
||||||
// staged firewall configuration changes, if there are any.
|
// staged firewall configuration changes, if there are any.
|
||||||
func vpnFirewallGetConfig(ctx subCmdCtx) (daecommon.NetworkConfig, error) {
|
func vpnFirewallGetConfig(
|
||||||
config, err := ctx.daemonRPC.GetConfig(ctx)
|
ctx subCmdCtx, daemonRPC daemon.RPC,
|
||||||
|
) (
|
||||||
|
daecommon.NetworkConfig, error,
|
||||||
|
) {
|
||||||
|
config, err := daemonRPC.GetConfig(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return daecommon.NetworkConfig{}, err
|
return daecommon.NetworkConfig{}, err
|
||||||
}
|
}
|
||||||
@ -110,7 +115,13 @@ var subCmdVPNFirewallAdd = subCmd{
|
|||||||
rule.Host = "any"
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
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")
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
return fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.VPN.Firewall = firewallConfig
|
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)
|
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{}{}
|
indexSet := map[int]struct{}{}
|
||||||
for _, index := range *indexes {
|
for _, index := range *indexes {
|
||||||
if index < 0 {
|
if index < 0 {
|
||||||
@ -200,7 +223,7 @@ var subCmdVPNFirewallRemove = subCmd{
|
|||||||
indexSet[index] = struct{}{}
|
indexSet[index] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := vpnFirewallGetConfig(ctx)
|
config, err := vpnFirewallGetConfig(ctx, daemonRPC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
return fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
@ -309,7 +332,13 @@ var subCmdVPNFirewallShow = subCmd{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !foundStaged {
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getting network config: %w", err)
|
return nil, fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,13 @@ var subCmdVPNPublicAddressGet = subCmd{
|
|||||||
return nil, fmt.Errorf("parsing flags: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getting network config: %w", err)
|
return nil, fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
@ -49,14 +55,20 @@ var subCmdVPNPublicAddressSet = subCmd{
|
|||||||
return fmt.Errorf("invalid --public-addr: %w", err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
return fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.VPN.PublicAddr = *publicAddr
|
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)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("getting network config: %w", err)
|
return fmt.Errorf("getting network config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.VPN.PublicAddr = ""
|
config.VPN.PublicAddr = ""
|
||||||
|
|
||||||
return ctx.daemonRPC.SetConfig(ctx, config)
|
return daemonRPC.SetConfig(ctx, config)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,46 +2,12 @@ package daemon
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
|
||||||
"isle/bootstrap"
|
"isle/bootstrap"
|
||||||
"isle/daemon/daecommon"
|
"isle/daemon/daecommon"
|
||||||
"isle/daemon/network"
|
"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(
|
func pickNetworkConfig(
|
||||||
networkConfigs map[string]daecommon.NetworkConfig,
|
networkConfigs map[string]daecommon.NetworkConfig,
|
||||||
creationParams bootstrap.CreationParams,
|
creationParams bootstrap.CreationParams,
|
||||||
@ -88,43 +54,3 @@ func validateConfig(
|
|||||||
|
|
||||||
return daemonConfig.Validate()
|
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
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,6 @@ package daecommon
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"isle/toolkit"
|
"isle/toolkit"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -25,12 +24,12 @@ var GetEnvVars = sync.OnceValue(func() EnvVars {
|
|||||||
var (
|
var (
|
||||||
res EnvVars
|
res EnvVars
|
||||||
|
|
||||||
stateDirPath = envOr(
|
stateDirPath = toolkit.EnvOr(
|
||||||
"STATE_DIRECTORY",
|
"STATE_DIRECTORY",
|
||||||
func() string { return filepath.Join(xdg.StateHome, "isle") },
|
func() string { return filepath.Join(xdg.StateHome, "isle") },
|
||||||
)
|
)
|
||||||
|
|
||||||
runtimeDirPath = envOr(
|
runtimeDirPath = toolkit.EnvOr(
|
||||||
"RUNTIME_DIRECTORY",
|
"RUNTIME_DIRECTORY",
|
||||||
func() string { return filepath.Join(xdg.RuntimeDir, "isle") },
|
func() string { return filepath.Join(xdg.RuntimeDir, "isle") },
|
||||||
)
|
)
|
||||||
@ -46,13 +45,3 @@ var GetEnvVars = sync.OnceValue(func() EnvVars {
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Jigs
|
|
||||||
|
|
||||||
func envOr(name string, fallback func() string) string {
|
|
||||||
if v := os.Getenv(name); v != "" {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return fallback()
|
|
||||||
}
|
|
||||||
|
12
go/toolkit/env.go
Normal file
12
go/toolkit/env.go
Normal file
@ -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()
|
||||||
|
}
|
@ -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.
|
|
Loading…
Reference in New Issue
Block a user