Brian Picciano
8c3e6a2845
In a world where the daemon can manage more than one network, the Daemon is really responsible only for knowing which networks are currently joined, creating/joining/leaving networks, and routing incoming RPC requests to the correct network handler as needed. The new network package, with its Network interface, inherits most of the logic that Daemon used to have, leaving Daemon only the parts needed for the functionality just described. There's a lot of cleanup done here in order to really nail down the separation of concerns between the two, especially around directory creation.
161 lines
3.8 KiB
Go
161 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"isle/daemon/daecommon"
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
)
|
|
|
|
// minio-client keeps a configuration directory which contains various pieces of
|
|
// information which may or may not be useful. Unfortunately when it initializes
|
|
// this directory it likes to print some annoying logs, so we pre-initialize in
|
|
// order to prevent it from doing so.
|
|
func initMCConfigDir(envVars daecommon.EnvVars) (string, error) {
|
|
var (
|
|
path = filepath.Join(envVars.StateDir.Path, "mc")
|
|
sharePath = filepath.Join(path, "share")
|
|
configJSONPath = filepath.Join(path, "config.json")
|
|
)
|
|
|
|
if err := os.MkdirAll(sharePath, 0700); err != nil {
|
|
return "", fmt.Errorf("creating %q: %w", sharePath, err)
|
|
}
|
|
|
|
if err := os.WriteFile(configJSONPath, []byte(`{}`), 0600); err != nil {
|
|
return "", fmt.Errorf("writing %q: %w", configJSONPath, err)
|
|
}
|
|
|
|
return path, nil
|
|
}
|
|
|
|
var subCmdGarageMC = subCmd{
|
|
name: "mc",
|
|
descr: "Runs the mc (minio-client) binary. The isle garage can be accessed under the `garage` alias",
|
|
do: func(ctx subCmdCtx) error {
|
|
|
|
flags := ctx.flagSet(true)
|
|
|
|
keyID := flags.StringP(
|
|
"key-id", "i", "",
|
|
"Optional key ID to use, defaults to that of the shared global key",
|
|
)
|
|
|
|
keySecret := flags.StringP(
|
|
"key-secret", "s", "",
|
|
"Optional key secret to use, defaults to that of the shared global key",
|
|
)
|
|
|
|
if err := flags.Parse(ctx.args); err != nil {
|
|
return fmt.Errorf("parsing flags: %w", err)
|
|
}
|
|
|
|
clientParams, err := ctx.daemonRPC.GetGarageClientParams(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("calling GetGarageClientParams: %w", err)
|
|
}
|
|
|
|
s3APIAddr := clientParams.Peer.S3APIAddr()
|
|
|
|
if *keyID == "" {
|
|
*keyID = clientParams.GlobalBucketS3APICredentials.ID
|
|
}
|
|
|
|
if *keySecret == "" {
|
|
*keySecret = clientParams.GlobalBucketS3APICredentials.Secret
|
|
}
|
|
|
|
args := flags.Args()
|
|
|
|
if i := flags.ArgsLenAtDash(); i >= 0 {
|
|
args = args[i:]
|
|
}
|
|
|
|
envVars := daecommon.GetEnvVars()
|
|
|
|
configDir, err := initMCConfigDir(envVars)
|
|
if err != nil {
|
|
return fmt.Errorf("initializing minio-client config directory: %w", err)
|
|
}
|
|
|
|
args = append([]string{
|
|
binPath("mc"),
|
|
"--config-dir", configDir,
|
|
}, args...)
|
|
|
|
var (
|
|
mcHostVar = fmt.Sprintf(
|
|
"MC_HOST_garage=http://%s:%s@%s",
|
|
*keyID, *keySecret, s3APIAddr,
|
|
)
|
|
|
|
binPath = filepath.Join(envAppDirPath, "bin/mc")
|
|
cliEnv = append(
|
|
os.Environ(),
|
|
mcHostVar,
|
|
|
|
// The garage docs say this is necessary, though nothing bad
|
|
// seems to happen if we leave it out *shrug*
|
|
"MC_REGION=garage",
|
|
)
|
|
)
|
|
|
|
if err := syscall.Exec(binPath, args, cliEnv); err != nil {
|
|
return fmt.Errorf(
|
|
"calling exec(%q, %#v, %#v): %w",
|
|
binPath, args, cliEnv, err,
|
|
)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var subCmdGarageCLI = subCmd{
|
|
name: "cli",
|
|
descr: "Runs the garage binary, automatically configured to point to the garage sub-process of a running isle daemon",
|
|
do: func(ctx subCmdCtx) error {
|
|
|
|
clientParams, err := ctx.daemonRPC.GetGarageClientParams(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("calling GetGarageClientParams: %w", err)
|
|
}
|
|
|
|
if clientParams.RPCSecret == "" {
|
|
return errors.New("this host does not have the garage RPC secret")
|
|
}
|
|
|
|
var (
|
|
binPath = binPath("garage")
|
|
args = append([]string{"garage"}, ctx.args...)
|
|
cliEnv = append(
|
|
os.Environ(),
|
|
"GARAGE_RPC_HOST="+clientParams.Peer.RPCPeerAddr(),
|
|
"GARAGE_RPC_SECRET="+clientParams.RPCSecret,
|
|
)
|
|
)
|
|
|
|
if err := syscall.Exec(binPath, args, cliEnv); err != nil {
|
|
return fmt.Errorf(
|
|
"calling exec(%q, %#v, %#v): %w",
|
|
binPath, args, cliEnv, err,
|
|
)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var subCmdGarage = subCmd{
|
|
name: "garage",
|
|
descr: "Runs the garage binary, automatically configured to point to the garage sub-process of a running isle daemon",
|
|
do: func(ctx subCmdCtx) error {
|
|
return ctx.doSubCmd(
|
|
subCmdGarageCLI,
|
|
subCmdGarageMC,
|
|
)
|
|
},
|
|
}
|