2024-09-07 13:46:59 +00:00
|
|
|
package children
|
2024-06-17 18:51:02 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-10-27 13:31:10 +00:00
|
|
|
"errors"
|
2024-06-17 18:51:02 +00:00
|
|
|
"fmt"
|
|
|
|
"isle/bootstrap"
|
2024-09-07 13:11:04 +00:00
|
|
|
"isle/daemon/daecommon"
|
2024-06-17 18:51:02 +00:00
|
|
|
"isle/garage"
|
|
|
|
"isle/garage/garagesrv"
|
|
|
|
"net"
|
|
|
|
"path/filepath"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"code.betamike.com/micropelago/pmux/pmuxlib"
|
2024-06-22 15:49:56 +00:00
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
|
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
2024-06-17 18:51:02 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func garageAdminClientLogger(logger *mlog.Logger) *mlog.Logger {
|
|
|
|
return logger.WithNamespace("garageAdminClient")
|
|
|
|
}
|
|
|
|
|
2025-01-04 14:50:17 +00:00
|
|
|
func garageAllocAdminAddr(
|
|
|
|
host bootstrap.Host, alloc daecommon.ConfigStorageAllocation,
|
|
|
|
) string {
|
|
|
|
return net.JoinHostPort(host.IP().String(), strconv.Itoa(alloc.AdminPort))
|
|
|
|
}
|
|
|
|
|
2024-07-06 13:36:48 +00:00
|
|
|
func waitForGarage(
|
|
|
|
ctx context.Context,
|
|
|
|
logger *mlog.Logger,
|
2024-07-14 10:19:39 +00:00
|
|
|
adminToken string,
|
2025-01-04 14:50:17 +00:00
|
|
|
procs map[string]garageProc,
|
2025-01-01 11:38:16 +00:00
|
|
|
newCluster bool,
|
2024-07-06 13:36:48 +00:00
|
|
|
) error {
|
|
|
|
adminClientLogger := garageAdminClientLogger(logger)
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2025-01-04 14:50:17 +00:00
|
|
|
for _, proc := range procs {
|
2024-06-17 18:51:02 +00:00
|
|
|
adminClient := garage.NewAdminClient(
|
2025-01-04 14:50:17 +00:00
|
|
|
adminClientLogger, proc.adminAddr, adminToken,
|
2024-06-17 18:51:02 +00:00
|
|
|
)
|
|
|
|
|
2024-10-27 13:31:10 +00:00
|
|
|
ctx := mctx.Annotate(
|
2025-01-04 14:50:17 +00:00
|
|
|
ctx,
|
|
|
|
"garageAdminAddr", proc.adminAddr,
|
|
|
|
"garageDataPath", proc.alloc.DataPath,
|
2024-10-27 13:31:10 +00:00
|
|
|
)
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2025-01-04 14:50:17 +00:00
|
|
|
logger.Info(ctx, "Waiting for garage instance to be healthy")
|
2024-10-07 19:12:47 +00:00
|
|
|
|
2025-01-04 14:50:17 +00:00
|
|
|
err := adminClient.Wait(ctx, !newCluster)
|
2024-10-07 19:12:47 +00:00
|
|
|
adminClient.Close()
|
2025-01-04 14:50:17 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf(
|
|
|
|
"waiting for garage instance %q to start up: %w",
|
|
|
|
proc.adminAddr,
|
|
|
|
err,
|
|
|
|
)
|
|
|
|
}
|
2024-06-17 18:51:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func garageWriteChildConfig(
|
2024-10-27 13:31:10 +00:00
|
|
|
ctx context.Context,
|
|
|
|
logger *mlog.Logger,
|
2024-07-14 10:19:39 +00:00
|
|
|
rpcSecret, runtimeDirPath, adminToken string,
|
2024-06-17 18:51:02 +00:00
|
|
|
hostBootstrap bootstrap.Bootstrap,
|
2024-09-07 13:11:04 +00:00
|
|
|
alloc daecommon.ConfigStorageAllocation,
|
2024-06-17 18:51:02 +00:00
|
|
|
) (
|
2025-01-01 12:07:35 +00:00
|
|
|
string, error,
|
2024-06-17 18:51:02 +00:00
|
|
|
) {
|
2024-10-27 13:31:10 +00:00
|
|
|
var (
|
|
|
|
thisHost = hostBootstrap.ThisHost()
|
|
|
|
id = daecommon.BootstrapGarageHostForAlloc(thisHost, alloc).ID
|
|
|
|
|
2024-11-08 16:46:44 +00:00
|
|
|
node = garage.LocalNode{
|
|
|
|
RemoteNode: garage.RemoteNode{
|
2024-10-27 13:31:10 +00:00
|
|
|
ID: id,
|
|
|
|
IP: thisHost.IP().String(),
|
|
|
|
RPCPort: alloc.RPCPort,
|
|
|
|
S3APIPort: alloc.S3APIPort,
|
|
|
|
},
|
|
|
|
AdminPort: alloc.AdminPort,
|
|
|
|
}
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2024-10-27 13:31:10 +00:00
|
|
|
garageTomlPath = filepath.Join(
|
|
|
|
runtimeDirPath, fmt.Sprintf("garage-%d.toml", alloc.RPCPort),
|
|
|
|
)
|
2024-06-17 18:51:02 +00:00
|
|
|
)
|
|
|
|
|
2024-12-26 19:37:00 +00:00
|
|
|
dbEngine, err := garagesrv.GetDBEngine(alloc.MetaPath)
|
|
|
|
if err != nil {
|
2025-01-01 12:07:35 +00:00
|
|
|
return "", fmt.Errorf("getting alloc db engine: %w", err)
|
2024-12-26 19:37:00 +00:00
|
|
|
}
|
|
|
|
|
2025-01-01 12:07:35 +00:00
|
|
|
err = garagesrv.WriteGarageTomlFile(
|
2024-10-27 13:31:10 +00:00
|
|
|
ctx,
|
|
|
|
logger,
|
|
|
|
garageTomlPath,
|
|
|
|
garagesrv.GarageTomlData{
|
|
|
|
MetaPath: alloc.MetaPath,
|
|
|
|
DataPath: alloc.DataPath,
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2024-10-27 13:31:10 +00:00
|
|
|
RPCSecret: rpcSecret,
|
|
|
|
AdminToken: adminToken,
|
2024-12-26 19:37:00 +00:00
|
|
|
DBEngine: dbEngine,
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2024-11-08 16:46:44 +00:00
|
|
|
LocalNode: node,
|
|
|
|
BootstrapPeers: hostBootstrap.GarageNodes(),
|
2024-10-27 13:31:10 +00:00
|
|
|
},
|
|
|
|
)
|
2024-06-17 18:51:02 +00:00
|
|
|
|
|
|
|
if err != nil {
|
2025-01-01 12:07:35 +00:00
|
|
|
return "", fmt.Errorf(
|
2024-10-27 13:31:10 +00:00
|
|
|
"creating garage.toml file at %q: %w", garageTomlPath, err,
|
|
|
|
)
|
2024-06-17 18:51:02 +00:00
|
|
|
}
|
|
|
|
|
2025-01-01 12:07:35 +00:00
|
|
|
return garageTomlPath, nil
|
2024-10-27 13:31:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func garagePmuxProcName(alloc daecommon.ConfigStorageAllocation) string {
|
|
|
|
return fmt.Sprintf("garage-%d", alloc.RPCPort)
|
2024-06-17 18:51:02 +00:00
|
|
|
}
|
|
|
|
|
2024-10-29 14:11:13 +00:00
|
|
|
func garagePmuxProc(
|
|
|
|
ctx context.Context,
|
|
|
|
logger *mlog.Logger,
|
|
|
|
binDirPath string,
|
|
|
|
procName string,
|
|
|
|
childConfigPath string,
|
|
|
|
) *pmuxlib.Process {
|
|
|
|
cfg := pmuxlib.ProcessConfig{
|
|
|
|
Cmd: filepath.Join(binDirPath, "garage"),
|
|
|
|
Args: []string{"-c", childConfigPath, "server"},
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg = withPmuxLoggers(ctx, logger, procName, cfg)
|
|
|
|
|
|
|
|
return pmuxlib.NewProcess(cfg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func garagePmuxProcs(
|
2024-07-13 12:34:06 +00:00
|
|
|
ctx context.Context,
|
2024-07-06 13:36:48 +00:00
|
|
|
logger *mlog.Logger,
|
2024-07-13 12:34:06 +00:00
|
|
|
rpcSecret, runtimeDirPath, binDirPath string,
|
2024-09-10 20:51:33 +00:00
|
|
|
networkConfig daecommon.NetworkConfig,
|
2024-07-14 10:19:39 +00:00
|
|
|
adminToken string,
|
2024-07-06 13:36:48 +00:00
|
|
|
hostBootstrap bootstrap.Bootstrap,
|
2024-06-17 18:51:02 +00:00
|
|
|
) (
|
2025-01-04 14:50:17 +00:00
|
|
|
map[string]garageProc, error,
|
2024-06-17 18:51:02 +00:00
|
|
|
) {
|
2024-07-13 12:34:06 +00:00
|
|
|
var (
|
2025-01-04 14:50:17 +00:00
|
|
|
procs = map[string]garageProc{}
|
|
|
|
allocs = networkConfig.Storage.Allocations
|
|
|
|
thisHost = hostBootstrap.ThisHost()
|
2024-07-13 12:34:06 +00:00
|
|
|
)
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2024-07-13 12:34:06 +00:00
|
|
|
if len(allocs) > 0 && rpcSecret == "" {
|
2024-10-27 13:31:10 +00:00
|
|
|
return nil, errors.New("Storage allocations defined, but garage RPC secret is not available")
|
2024-07-13 12:34:06 +00:00
|
|
|
}
|
2024-06-17 18:51:02 +00:00
|
|
|
|
2024-07-13 12:34:06 +00:00
|
|
|
for _, alloc := range allocs {
|
2025-01-01 12:07:35 +00:00
|
|
|
childConfigPath, err := garageWriteChildConfig(
|
2024-10-27 13:31:10 +00:00
|
|
|
ctx,
|
|
|
|
logger,
|
|
|
|
rpcSecret, runtimeDirPath, adminToken,
|
|
|
|
hostBootstrap,
|
|
|
|
alloc,
|
2024-06-17 18:51:02 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("writing child config file for alloc %+v: %w", alloc, err)
|
|
|
|
}
|
|
|
|
|
2024-10-27 13:31:10 +00:00
|
|
|
procName := garagePmuxProcName(alloc)
|
2025-01-04 14:50:17 +00:00
|
|
|
procs[procName] = garageProc{
|
|
|
|
Process: garagePmuxProc(
|
|
|
|
ctx, logger, binDirPath, procName, childConfigPath,
|
|
|
|
),
|
|
|
|
alloc: alloc,
|
|
|
|
adminAddr: garageAllocAdminAddr(thisHost, alloc),
|
|
|
|
}
|
2024-06-17 18:51:02 +00:00
|
|
|
}
|
|
|
|
|
2025-01-04 14:50:17 +00:00
|
|
|
return procs, nil
|
2024-06-17 18:51:02 +00:00
|
|
|
}
|