2022-10-20 19:59:46 +00:00
package main
2021-04-20 21:31:37 +00:00
import (
2024-07-13 12:34:06 +00:00
"errors"
2021-04-20 21:31:37 +00:00
"fmt"
2024-09-09 14:34:00 +00:00
"isle/daemon/daecommon"
2021-04-20 21:31:37 +00:00
"os"
2022-11-08 13:54:31 +00:00
"path/filepath"
2021-04-20 21:31:37 +00:00
"syscall"
)
2023-09-04 19:38:28 +00:00
// 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.
2024-09-09 14:34:00 +00:00
func initMCConfigDir ( envVars daecommon . EnvVars ) ( string , error ) {
2023-09-04 19:38:28 +00:00
var (
2024-09-09 14:34:00 +00:00
path = filepath . Join ( envVars . StateDir . Path , "mc" )
2023-09-04 19:38:28 +00:00
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
}
2021-04-20 21:31:37 +00:00
var subCmdGarageMC = subCmd {
2024-12-10 21:07:25 +00:00
name : "mc" ,
descr : "Runs the mc (minio-client) binary. The isle garage can be accessed under the `garage` alias" ,
2024-09-04 20:35:29 +00:00
do : func ( ctx subCmdCtx ) error {
2024-09-23 18:50:45 +00:00
keyID := ctx . flags . StringP (
2021-04-20 21:31:37 +00:00
"key-id" , "i" , "" ,
2023-08-07 20:12:51 +00:00
"Optional key ID to use, defaults to that of the shared global key" ,
2021-04-20 21:31:37 +00:00
)
2024-09-23 18:50:45 +00:00
keySecret := ctx . flags . StringP (
2021-04-20 21:31:37 +00:00
"key-secret" , "s" , "" ,
2023-08-07 20:12:51 +00:00
"Optional key secret to use, defaults to that of the shared global key" ,
2021-04-20 21:31:37 +00:00
)
2024-12-10 21:07:25 +00:00
ctx , err := ctx . withParsedFlags ( & withParsedFlagsOpts {
passthroughArgs : true ,
} )
2024-09-23 18:50:45 +00:00
if err != nil {
2021-04-20 21:31:37 +00:00
return fmt . Errorf ( "parsing flags: %w" , err )
}
2024-12-16 13:59:11 +00:00
daemonRPC , err := ctx . newDaemonRPC ( )
if err != nil {
return fmt . Errorf ( "creating daemon RPC client: %w" , err )
}
defer daemonRPC . Close ( )
clientParams , err := daemonRPC . GetGarageClientParams ( ctx )
2022-10-26 22:23:39 +00:00
if err != nil {
2024-07-12 14:03:37 +00:00
return fmt . Errorf ( "calling GetGarageClientParams: %w" , err )
2022-10-26 22:23:39 +00:00
}
2024-11-08 16:46:44 +00:00
s3APIAddr := clientParams . Node . S3APIAddr ( )
2021-04-20 21:31:37 +00:00
2022-11-13 19:14:16 +00:00
if * keyID == "" {
2024-07-12 14:03:37 +00:00
* keyID = clientParams . GlobalBucketS3APICredentials . ID
2022-11-13 19:14:16 +00:00
}
2021-04-20 21:31:37 +00:00
2022-11-13 19:14:16 +00:00
if * keySecret == "" {
2024-07-12 14:03:37 +00:00
* keySecret = clientParams . GlobalBucketS3APICredentials . Secret
2021-04-20 21:31:37 +00:00
}
2024-09-23 18:50:45 +00:00
args := ctx . flags . Args ( )
2021-04-20 21:31:37 +00:00
2024-09-23 18:50:45 +00:00
if i := ctx . flags . ArgsLenAtDash ( ) ; i >= 0 {
2021-04-20 21:31:37 +00:00
args = args [ i : ]
}
2024-09-09 14:34:00 +00:00
envVars := daecommon . GetEnvVars ( )
configDir , err := initMCConfigDir ( envVars )
2023-09-04 19:38:28 +00:00
if err != nil {
return fmt . Errorf ( "initializing minio-client config directory: %w" , err )
}
args = append ( [ ] string {
binPath ( "mc" ) ,
"--config-dir" , configDir ,
} , args ... )
2021-04-20 21:31:37 +00:00
var (
2022-11-13 19:14:16 +00:00
mcHostVar = fmt . Sprintf (
"MC_HOST_garage=http://%s:%s@%s" ,
* keyID , * keySecret , s3APIAddr ,
)
2024-09-24 09:22:00 +00:00
binPath = binPath ( "mc" )
2021-04-20 21:31:37 +00:00
cliEnv = append (
os . Environ ( ) ,
2022-11-13 19:14:16 +00:00
mcHostVar ,
2021-04-20 21:31:37 +00:00
// 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 {
2024-12-10 21:07:25 +00:00
name : "cli" ,
descr : "Runs the garage binary, automatically configured to point to the garage sub-process of a running isle daemon" ,
2024-09-04 20:35:29 +00:00
do : func ( ctx subCmdCtx ) error {
2025-01-01 11:38:16 +00:00
rpcNodeAddr := ctx . flags . String ( "rpc-node-addr" , "" , "RPC address of the garage instance to hit in the form 'id@host:port'. Will default to a local garage instance if not given, or some random garage instance in the cluster if no local instance is configured." )
2024-12-10 21:07:25 +00:00
ctx , err := ctx . withParsedFlags ( & withParsedFlagsOpts {
passthroughArgs : true ,
} )
2024-09-23 18:50:45 +00:00
if err != nil {
return fmt . Errorf ( "parsing flags: %w" , err )
}
2021-04-20 21:31:37 +00:00
2024-12-16 13:59:11 +00:00
daemonRPC , err := ctx . newDaemonRPC ( )
if err != nil {
return fmt . Errorf ( "creating daemon RPC client: %w" , err )
}
defer daemonRPC . Close ( )
clientParams , err := daemonRPC . GetGarageClientParams ( ctx )
2022-10-26 22:23:39 +00:00
if err != nil {
2024-07-12 14:03:37 +00:00
return fmt . Errorf ( "calling GetGarageClientParams: %w" , err )
2022-10-26 22:23:39 +00:00
}
2024-07-13 12:34:06 +00:00
if clientParams . RPCSecret == "" {
return errors . New ( "this host does not have the garage RPC secret" )
}
2025-01-01 11:38:16 +00:00
chosenRPCNodeAddr := clientParams . Node . RPCNodeAddr ( )
if * rpcNodeAddr != "" {
chosenRPCNodeAddr = * rpcNodeAddr
}
2021-04-20 21:31:37 +00:00
var (
2023-04-23 14:30:47 +00:00
binPath = binPath ( "garage" )
2024-11-14 20:49:35 +00:00
args = append ( [ ] string { "garage" } , ctx . opts . args ... )
2021-04-20 21:31:37 +00:00
cliEnv = append (
os . Environ ( ) ,
2025-01-01 11:38:16 +00:00
"GARAGE_RPC_HOST=" + chosenRPCNodeAddr ,
2024-07-12 14:03:37 +00:00
"GARAGE_RPC_SECRET=" + clientParams . RPCSecret ,
2021-04-20 21:31:37 +00:00
)
)
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" ,
2023-08-05 21:53:17 +00:00
descr : "Runs the garage binary, automatically configured to point to the garage sub-process of a running isle daemon" ,
2024-09-04 20:35:29 +00:00
do : func ( ctx subCmdCtx ) error {
return ctx . doSubCmd (
2021-04-20 21:31:37 +00:00
subCmdGarageCLI ,
subCmdGarageMC ,
)
} ,
}