Compare commits

..

No commits in common. "cc121f0752a483ea9e0faaf640843a58e6c0ef3c" and "c5e919dc86f84c9eefa308e9fc3660df7c22a75a" have entirely different histories.

6 changed files with 63 additions and 124 deletions

View File

@ -0,0 +1,35 @@
package bootstrap
import (
"context"
"isle/garage"
"path/filepath"
"github.com/minio/minio-go/v7"
)
// Paths within garage's global bucket.
//
// TODO this is getting moved into daemon package.
const (
garageGlobalBucketBootstrapHostsDirPath = "bootstrap/hosts"
)
// RemoveGarageBootstrapHost removes the <hostname>.json.signed for the given
// host from garage.
//
// The given client should be for the global bucket.
func RemoveGarageBootstrapHost(
ctx context.Context, client garage.S3APIClient, hostName string,
) error {
filePath := filepath.Join(
garageGlobalBucketBootstrapHostsDirPath,
hostName+".json.signed",
)
return client.RemoveObject(
ctx, garage.GlobalBucket, filePath,
minio.RemoveObjectOptions{},
)
}

View File

@ -4,9 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"isle/bootstrap" "isle/bootstrap"
"isle/daemon"
"isle/jsonutil" "isle/jsonutil"
"isle/nebula"
"os" "os"
"sort" "sort"
) )
@ -47,39 +45,39 @@ var subCmdHostsList = subCmd{
}, },
} }
var subCmdHostsRemove = subCmd{ var subCmdHostsDelete = subCmd{
name: "remove", name: "delete",
descr: "Removes a host from the network", descr: "Deletes a host from the network",
do: func(subCmdCtx subCmdCtx) error { do: func(subCmdCtx subCmdCtx) error {
var (
flags = subCmdCtx.flagSet(false)
hostName nebula.HostName
)
hostNameF := flags.VarPF( flags := subCmdCtx.flagSet(false)
textUnmarshalerFlag{&hostName},
"hostname", "h", hostName := flags.StringP(
"Name of the host to remove", "hostname", "h", "",
"Name of the host to delete",
) )
if err := flags.Parse(subCmdCtx.args); err != nil { if err := flags.Parse(subCmdCtx.args); err != nil {
return fmt.Errorf("parsing flags: %w", err) return fmt.Errorf("parsing flags: %w", err)
} }
if !hostNameF.Changed { if *hostName == "" {
return errors.New("--hostname is required") return errors.New("--hostname is required")
} }
var clientParams bootstrap.GarageClientParams
err := subCmdCtx.daemonRCPClient.Call( err := subCmdCtx.daemonRCPClient.Call(
subCmdCtx.ctx, nil, "RemoveHost", daemon.RemoveHostRequest{ subCmdCtx.ctx, &clientParams, "GetGarageClientParams", nil,
HostName: hostName,
},
) )
if err != nil { if err != nil {
return fmt.Errorf("calling RemoveHost: %w", err) return fmt.Errorf("calling GetGarageClientParams: %w", err)
} }
return nil client := clientParams.GlobalBucketS3APIClient()
// TODO do this within the daemon, along with first checking if the host
// has any assigned network resources.
return bootstrap.RemoveGarageBootstrapHost(subCmdCtx.ctx, client, *hostName)
}, },
} }
@ -88,7 +86,7 @@ var subCmdHosts = subCmd{
descr: "Sub-commands having to do with configuration of hosts in the network", descr: "Sub-commands having to do with configuration of hosts in the network",
do: func(subCmdCtx subCmdCtx) error { do: func(subCmdCtx subCmdCtx) error {
return subCmdCtx.doSubCmd( return subCmdCtx.doSubCmd(
subCmdHostsRemove, subCmdHostsDelete,
subCmdHostsList, subCmdHostsList,
) )
}, },

View File

@ -52,9 +52,6 @@ type Daemon interface {
// GetBootstraps returns the currently active Bootstrap. // GetBootstraps returns the currently active Bootstrap.
GetBootstrap(context.Context) (bootstrap.Bootstrap, error) GetBootstrap(context.Context) (bootstrap.Bootstrap, error)
// RemoveHost removes the host of the given name from the network.
RemoveHost(context.Context, nebula.HostName) error
// Shutdown blocks until all resources held or created by the daemon, // Shutdown blocks until all resources held or created by the daemon,
// including child processes it has started, have been cleaned up. // including child processes it has started, have been cleaned up.
// //
@ -150,10 +147,6 @@ func NewDaemon(
bootstrapFilePath = bootstrap.StateDirPath(d.opts.EnvVars.StateDirPath) bootstrapFilePath = bootstrap.StateDirPath(d.opts.EnvVars.StateDirPath)
) )
if err := d.opts.EnvVars.init(); err != nil {
return nil, fmt.Errorf("initializing daemon directories: %w", err)
}
currBootstrap, err := bootstrap.FromFile(bootstrapFilePath) currBootstrap, err := bootstrap.FromFile(bootstrapFilePath)
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
// daemon has never had a network created or joined // daemon has never had a network created or joined
@ -375,7 +368,7 @@ func (d *daemon) postInit(ctx context.Context) bool {
d.logger, d.logger,
"Updating host info in garage", "Updating host info in garage",
func(ctx context.Context) error { func(ctx context.Context) error {
return putGarageBoostrapHost(ctx, d.logger, d.currBootstrap) return d.putGarageBoostrapHost(ctx)
}, },
) { ) {
return false return false
@ -578,20 +571,6 @@ func (d *daemon) GetBootstrap(ctx context.Context) (bootstrap.Bootstrap, error)
}) })
} }
func (d *daemon) RemoveHost(ctx context.Context, hostName nebula.HostName) error {
// TODO RemoveHost should publish a certificate revocation for the host
// being removed.
_, err := withCurrBootstrap(d, func(
currBootstrap bootstrap.Bootstrap,
) (
struct{}, error,
) {
client := currBootstrap.GarageClientParams().GlobalBucketS3APIClient()
return struct{}{}, removeGarageBootstrapHost(ctx, client, hostName)
})
return err
}
func (d *daemon) Shutdown() error { func (d *daemon) Shutdown() error {
d.l.Lock() d.l.Lock()
defer d.l.Unlock() defer d.l.Unlock()

View File

@ -13,62 +13,17 @@ import (
"github.com/adrg/xdg" "github.com/adrg/xdg"
) )
// DEPRECATED
//
// EnvVars are variables which are derived based on the environment which the // EnvVars are variables which are derived based on the environment which the
// process is running in. // process is running in.
//
// TODO EnvVars should be private to this package.
type EnvVars struct { type EnvVars struct {
RuntimeDirPath string RuntimeDirPath string
StateDirPath string StateDirPath string
} }
func (e EnvVars) init() error {
var errs []error
mkDir := func(path string) error {
{
parentPath := filepath.Dir(path)
parentInfo, err := os.Stat(parentPath)
if err != nil {
return fmt.Errorf("checking parent path %q: %w", parentPath, err)
} else if !parentInfo.IsDir() {
return fmt.Errorf("%q is not a directory", parentPath)
}
}
info, err := os.Stat(path)
if errors.Is(err, fs.ErrNotExist) {
// fine
} else if err != nil {
return fmt.Errorf("checking path: %w", err)
} else if !info.IsDir() {
return fmt.Errorf("path is not a directory")
} else {
return nil
}
if err := os.Mkdir(path, 0700); err != nil {
return fmt.Errorf("creating directory: %w", err)
}
return nil
}
if err := mkDir(e.RuntimeDirPath); err != nil {
errs = append(errs, fmt.Errorf(
"creating runtime directory %q: %w",
e.RuntimeDirPath,
err,
))
}
if err := mkDir(e.StateDirPath); err != nil {
errs = append(errs, fmt.Errorf(
"creating state directory %q: %w",
e.StateDirPath,
err,
))
}
return errors.Join(errs...)
}
func getDefaultHTTPSocketDirPath() string { func getDefaultHTTPSocketDirPath() string {
path, err := firstExistingDir( path, err := firstExistingDir(
"/run", "/run",
@ -96,6 +51,8 @@ var HTTPSocketPath = sync.OnceValue(func() string {
) )
}) })
// DEPRECATED
//
// GetEnvVars will return the EnvVars of the current processes, as determined by // GetEnvVars will return the EnvVars of the current processes, as determined by
// the process's environment. // the process's environment.
var GetEnvVars = sync.OnceValue(func() (v EnvVars) { var GetEnvVars = sync.OnceValue(func() (v EnvVars) {

View File

@ -62,11 +62,9 @@ func garageInitializeGlobalBucket(
// putGarageBoostrapHost places the <hostname>.json.signed file for this host // putGarageBoostrapHost places the <hostname>.json.signed file for this host
// into garage so that other hosts are able to see relevant configuration for // into garage so that other hosts are able to see relevant configuration for
// it. // it.
func putGarageBoostrapHost( func (d *daemon) putGarageBoostrapHost(ctx context.Context) error {
ctx context.Context, logger *mlog.Logger, currBootstrap bootstrap.Bootstrap,
) error {
var ( var (
b = currBootstrap b = d.currBootstrap
host = b.ThisHost() host = b.ThisHost()
client = b.GarageClientParams().GlobalBucketS3APIClient() client = b.GarageClientParams().GlobalBucketS3APIClient()
) )
@ -162,17 +160,3 @@ func getGarageBootstrapHosts(
return hosts, nil return hosts, nil
} }
func removeGarageBootstrapHost(
ctx context.Context, client garage.S3APIClient, hostName nebula.HostName,
) error {
filePath := filepath.Join(
garageGlobalBucketBootstrapHostsDirPath,
string(hostName)+".json.signed",
)
return client.RemoveObject(
ctx, garage.GlobalBucket, filePath, minio.RemoveObjectOptions{},
)
}

View File

@ -86,8 +86,7 @@ func (r *RPC) GetHosts(
return GetHostsResult{hosts}, nil return GetHostsResult{hosts}, nil
} }
// GetGarageClientParams returns a GarageClientParams which can be used to // GetGarageClientParams passes through to the Daemon method of the same name.
// interact with garage.
func (r *RPC) GetGarageClientParams( func (r *RPC) GetGarageClientParams(
ctx context.Context, req struct{}, ctx context.Context, req struct{},
) ( ) (
@ -103,7 +102,6 @@ func (r *RPC) GetGarageClientParams(
return b.GarageClientParams(), nil return b.GarageClientParams(), nil
} }
// GetNebulaCAPublicCredentials returns the CAPublicCredentials for the network.
func (r *RPC) GetNebulaCAPublicCredentials( func (r *RPC) GetNebulaCAPublicCredentials(
ctx context.Context, req struct{}, ctx context.Context, req struct{},
) ( ) (
@ -118,15 +116,3 @@ func (r *RPC) GetNebulaCAPublicCredentials(
return b.CAPublicCredentials, nil return b.CAPublicCredentials, nil
} }
// RemoveHostRequest contains the arguments to the RemoveHost method.
//
// All fields are required.
type RemoveHostRequest struct {
HostName nebula.HostName
}
// RemoveHost passes the call through to the Daemon method of the same name.
func (r *RPC) RemoveHost(ctx context.Context, req RemoveHostRequest) (struct{}, error) {
return struct{}{}, r.daemon.RemoveHost(ctx, req.HostName)
}