Compare commits
No commits in common. "da100c6170f14f30ca6099fece6e47b39ef81530" and "838c54870675fff42151e8ae75b791578f3dff5d" have entirely different histories.
da100c6170
...
838c548706
@ -7,7 +7,7 @@
|
||||
pname = "cryptic-net-entrypoint";
|
||||
version = "unstable";
|
||||
src = ./src;
|
||||
vendorSha256 = "sha256-TTTXwztv4xwF1uXcYoSka6HwgHwU1AnClF4fguXVtK4=";
|
||||
vendorSha256 = "sha256-1mHD0tmITlGjeo6F+Dvd2TdEPzxWtndy/J+uGHWKen4=";
|
||||
subPackages = [
|
||||
"cmd/entrypoint"
|
||||
];
|
||||
|
@ -6,11 +6,10 @@ import (
|
||||
"cryptic-net/garage"
|
||||
"cryptic-net/nebula"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@ -86,7 +85,6 @@ func RemoveGarageBootstrapHost(
|
||||
// stored in garage.
|
||||
func (b Bootstrap) GetGarageBootstrapHosts(
|
||||
ctx context.Context,
|
||||
logger *mlog.Logger,
|
||||
) (
|
||||
map[string]Host, error,
|
||||
) {
|
||||
@ -105,8 +103,6 @@ func (b Bootstrap) GetGarageBootstrapHosts(
|
||||
|
||||
for objInfo := range objInfoCh {
|
||||
|
||||
ctx := mctx.Annotate(ctx, "object-key", objInfo.Key)
|
||||
|
||||
if objInfo.Err != nil {
|
||||
return nil, fmt.Errorf("listing objects: %w", objInfo.Err)
|
||||
}
|
||||
@ -136,7 +132,7 @@ func (b Bootstrap) GetGarageBootstrapHosts(
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Warn(ctx, "unwrapping signed public creds", err)
|
||||
fmt.Fprintf(os.Stderr, "unwrapping signed public creds for %q: %v\n", objInfo.Key, err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -147,20 +143,20 @@ func (b Bootstrap) GetGarageBootstrapHosts(
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Warn(ctx, "invalid signed public creds", err)
|
||||
fmt.Fprintf(os.Stderr, "invalid signed public creds for %q: %v\n", objInfo.Key, err)
|
||||
continue
|
||||
}
|
||||
|
||||
var hostPublicCreds nebula.HostPublicCredentials
|
||||
if err := yaml.Unmarshal(hostPublicCredsB, &hostPublicCreds); err != nil {
|
||||
logger.Warn(ctx, "yaml unmarshaling signed public creds", err)
|
||||
fmt.Fprintf(os.Stderr, "yaml unmarshaling signed public creds for %q: %v\n", objInfo.Key, err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = nebula.ValidateSignature(hostPublicCreds.SigningKeyPEM, hostB, hostSig)
|
||||
|
||||
if err != nil {
|
||||
logger.Warn(ctx, "invalid host data", err)
|
||||
fmt.Fprintf(os.Stderr, "invalid host data for %q: %v\n", objInfo.Key, err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.betamike.com/cryptic-io/pmux/pmuxlib"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
)
|
||||
|
||||
func randStr(l int) string {
|
||||
@ -85,17 +84,10 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
"Name of this host, which will be the first host in the network",
|
||||
)
|
||||
|
||||
logLevelStr := flags.StringP(
|
||||
"log-level", "l", "info",
|
||||
`Maximum log level which should be output. Values can be "debug", "info", "warn", "error", "fatal". Does not apply to sub-processes`,
|
||||
)
|
||||
|
||||
if err := flags.Parse(subCmdCtx.args); err != nil {
|
||||
return fmt.Errorf("parsing flags: %w", err)
|
||||
}
|
||||
|
||||
ctx := subCmdCtx.ctx
|
||||
|
||||
if *dumpConfig {
|
||||
return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
|
||||
}
|
||||
@ -104,13 +96,6 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
return errors.New("--name, --domain, --ip-net, and --hostname are required")
|
||||
}
|
||||
|
||||
logLevel := mlog.LevelFromString(*logLevelStr)
|
||||
if logLevel == nil {
|
||||
return fmt.Errorf("couldn't parse log level %q", *logLevelStr)
|
||||
}
|
||||
|
||||
logger := subCmdCtx.logger.WithMaxLevel(logLevel.Int())
|
||||
|
||||
*domain = strings.TrimRight(strings.TrimLeft(*domain, "."), ".")
|
||||
|
||||
ip, subnet, err := net.ParseCIDR(*ipNetStr)
|
||||
@ -122,7 +107,7 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
return fmt.Errorf("invalid hostname %q: %w", *hostName, err)
|
||||
}
|
||||
|
||||
runtimeDirCleanup, err := setupAndLockRuntimeDir(ctx, logger)
|
||||
runtimeDirCleanup, err := setupAndLockRuntimeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up runtime directory: %w", err)
|
||||
}
|
||||
@ -206,10 +191,10 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
),
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
ctx, cancel := context.WithCancel(subCmdCtx.ctx)
|
||||
pmuxDoneCh := make(chan struct{})
|
||||
|
||||
logger.Info(ctx, "starting child processes")
|
||||
fmt.Fprintln(os.Stderr, "starting child processes")
|
||||
go func() {
|
||||
// NOTE both stdout and stderr are sent to stderr, so that the user
|
||||
// can pipe the resulting admin.yml to stdout.
|
||||
@ -219,22 +204,22 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
|
||||
defer func() {
|
||||
cancel()
|
||||
logger.Info(ctx, "waiting for child processes to exit")
|
||||
fmt.Fprintln(os.Stderr, "waiting for child processes to exit")
|
||||
<-pmuxDoneCh
|
||||
}()
|
||||
|
||||
logger.Info(ctx, "waiting for garage instances to come online")
|
||||
if err := waitForGarageAndNebula(ctx, logger, hostBootstrap, daemonConfig); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "waiting for garage instances to come online")
|
||||
if err := waitForGarageAndNebula(ctx, hostBootstrap, daemonConfig); err != nil {
|
||||
return fmt.Errorf("waiting for garage to start up: %w", err)
|
||||
}
|
||||
|
||||
logger.Info(ctx, "applying initial garage layout")
|
||||
if err := garageApplyLayout(ctx, logger, hostBootstrap, daemonConfig); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "applying initial garage layout")
|
||||
if err := garageApplyLayout(ctx, hostBootstrap, daemonConfig); err != nil {
|
||||
return fmt.Errorf("applying initial garage layout: %w", err)
|
||||
}
|
||||
|
||||
logger.Info(ctx, "initializing garage shared global bucket")
|
||||
err = garageInitializeGlobalBucket(ctx, logger, hostBootstrap, daemonConfig)
|
||||
fmt.Fprintln(os.Stderr, "initializing garage shared global bucket")
|
||||
err = garageInitializeGlobalBucket(ctx, hostBootstrap, daemonConfig)
|
||||
|
||||
if cErr := (garage.AdminClientError{}); errors.As(err, &cErr) && cErr.StatusCode == 409 {
|
||||
return fmt.Errorf("shared global bucket has already been created, are the storage allocations from a previously initialized cryptic-net being used?")
|
||||
@ -243,7 +228,7 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
return fmt.Errorf("initializing garage shared global bucket: %w", err)
|
||||
}
|
||||
|
||||
logger.Info(ctx, "cluster initialized successfully, writing admin.yml to stdout")
|
||||
fmt.Fprintln(os.Stderr, "cluster initialized successfully, writing admin.yml to stdout")
|
||||
|
||||
adm := admin.Admin{
|
||||
CreationParams: adminCreationParams,
|
||||
|
@ -14,8 +14,6 @@ import (
|
||||
"cryptic-net/daemon"
|
||||
|
||||
"code.betamike.com/cryptic-io/pmux/pmuxlib"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
)
|
||||
|
||||
// The daemon sub-command deals with starting an actual cryptic-net daemon
|
||||
@ -42,7 +40,6 @@ import (
|
||||
// is overwritten and true is returned.
|
||||
func reloadBootstrap(
|
||||
ctx context.Context,
|
||||
logger *mlog.Logger,
|
||||
hostBootstrap bootstrap.Bootstrap,
|
||||
) (
|
||||
bootstrap.Bootstrap, bool, error,
|
||||
@ -50,7 +47,7 @@ func reloadBootstrap(
|
||||
|
||||
thisHost := hostBootstrap.ThisHost()
|
||||
|
||||
newHosts, err := hostBootstrap.GetGarageBootstrapHosts(ctx, logger)
|
||||
newHosts, err := hostBootstrap.GetGarageBootstrapHosts(ctx)
|
||||
if err != nil {
|
||||
return bootstrap.Bootstrap{}, false, fmt.Errorf("getting hosts from garage: %w", err)
|
||||
}
|
||||
@ -88,7 +85,6 @@ func reloadBootstrap(
|
||||
// updated boostrap info.
|
||||
func runDaemonPmuxOnce(
|
||||
ctx context.Context,
|
||||
logger *mlog.Logger,
|
||||
hostBootstrap bootstrap.Bootstrap,
|
||||
daemonConfig daemon.Config,
|
||||
) (
|
||||
@ -120,6 +116,8 @@ func runDaemonPmuxOnce(
|
||||
),
|
||||
}
|
||||
|
||||
doneCh := ctx.Done()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
defer wg.Wait()
|
||||
|
||||
@ -132,28 +130,18 @@ func runDaemonPmuxOnce(
|
||||
pmuxlib.Run(ctx, os.Stdout, os.Stderr, pmuxConfig)
|
||||
}()
|
||||
|
||||
if err := waitForGarageAndNebula(ctx, logger, hostBootstrap, daemonConfig); err != nil {
|
||||
return bootstrap.Bootstrap{}, fmt.Errorf("waiting for nebula/garage to start up: %w", err)
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
err = doOnce(ctx, func(ctx context.Context) error {
|
||||
if err := hostBootstrap.PutGarageBoostrapHost(ctx); err != nil {
|
||||
logger.Error(ctx, "updating host info in garage", err)
|
||||
return err
|
||||
if err := waitForGarageAndNebula(ctx, hostBootstrap, daemonConfig); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "aborted waiting for garage instances to be accessible: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return bootstrap.Bootstrap{}, fmt.Errorf("updating host info in garage: %w", err)
|
||||
}
|
||||
|
||||
if len(daemonConfig.Storage.Allocations) > 0 {
|
||||
|
||||
err := doOnce(ctx, func(ctx context.Context) error {
|
||||
if err := garageApplyLayout(ctx, logger, hostBootstrap, daemonConfig); err != nil {
|
||||
logger.Error(ctx, "applying garage layout", err)
|
||||
if err := hostBootstrap.PutGarageBoostrapHost(ctx); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "updating host info in garage: %v\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -161,8 +149,33 @@ func runDaemonPmuxOnce(
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return bootstrap.Bootstrap{}, fmt.Errorf("applying garage layout: %w", err)
|
||||
fmt.Fprintf(os.Stderr, "aborted updating host info in garage: %v\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if len(daemonConfig.Storage.Allocations) > 0 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := waitForGarageAndNebula(ctx, hostBootstrap, daemonConfig); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "aborted waiting for garage instances to be accessible: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err := doOnce(ctx, func(ctx context.Context) error {
|
||||
if err := garageApplyLayout(ctx, hostBootstrap, daemonConfig); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "applying garage layout: %v\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "aborted applying garage layout: %v\n", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(3 * time.Minute)
|
||||
@ -171,7 +184,7 @@ func runDaemonPmuxOnce(
|
||||
for {
|
||||
select {
|
||||
|
||||
case <-ctx.Done():
|
||||
case <-doneCh:
|
||||
return bootstrap.Bootstrap{}, ctx.Err()
|
||||
|
||||
case <-ticker.C:
|
||||
@ -183,7 +196,7 @@ func runDaemonPmuxOnce(
|
||||
err error
|
||||
)
|
||||
|
||||
if hostBootstrap, changed, err = reloadBootstrap(ctx, logger, hostBootstrap); err != nil {
|
||||
if hostBootstrap, changed, err = reloadBootstrap(ctx, hostBootstrap); err != nil {
|
||||
return bootstrap.Bootstrap{}, fmt.Errorf("reloading bootstrap: %w", err)
|
||||
|
||||
} else if changed {
|
||||
@ -216,29 +229,15 @@ var subCmdDaemon = subCmd{
|
||||
`Path to a bootstrap.yml file. This only needs to be provided the first time the daemon is started, after that it is ignored. If the cryptic-net binary has a bootstrap built into it then this argument is always optional.`,
|
||||
)
|
||||
|
||||
logLevelStr := flags.StringP(
|
||||
"log-level", "l", "info",
|
||||
`Maximum log level which should be output. Values can be "debug", "info", "warn", "error", "fatal". Does not apply to sub-processes`,
|
||||
)
|
||||
|
||||
if err := flags.Parse(subCmdCtx.args); err != nil {
|
||||
return fmt.Errorf("parsing flags: %w", err)
|
||||
}
|
||||
|
||||
ctx := subCmdCtx.ctx
|
||||
|
||||
if *dumpConfig {
|
||||
return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
|
||||
}
|
||||
|
||||
logLevel := mlog.LevelFromString(*logLevelStr)
|
||||
if logLevel == nil {
|
||||
return fmt.Errorf("couldn't parse log level %q", *logLevelStr)
|
||||
}
|
||||
|
||||
logger := subCmdCtx.logger.WithMaxLevel(logLevel.Int())
|
||||
|
||||
runtimeDirCleanup, err := setupAndLockRuntimeDir(ctx, logger)
|
||||
runtimeDirCleanup, err := setupAndLockRuntimeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up runtime directory: %w", err)
|
||||
}
|
||||
@ -267,11 +266,7 @@ var subCmdDaemon = subCmd{
|
||||
return false
|
||||
}
|
||||
|
||||
logger.Info(
|
||||
mctx.Annotate(ctx, "bootstrap-file-path", path),
|
||||
"bootstrap file found",
|
||||
)
|
||||
|
||||
fmt.Fprintf(os.Stderr, "bootstrap file found at %q\n", path)
|
||||
hostBootstrapPath = path
|
||||
return true
|
||||
}
|
||||
@ -311,7 +306,7 @@ var subCmdDaemon = subCmd{
|
||||
|
||||
for {
|
||||
|
||||
hostBootstrap, err = runDaemonPmuxOnce(ctx, logger, hostBootstrap, daemonConfig)
|
||||
hostBootstrap, err = runDaemonPmuxOnce(subCmdCtx.ctx, hostBootstrap, daemonConfig)
|
||||
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return nil
|
||||
|
@ -58,6 +58,6 @@ func doOnce(ctx context.Context, fn func(context.Context) error) error {
|
||||
return ctxErr
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
@ -11,19 +11,12 @@ import (
|
||||
"strconv"
|
||||
|
||||
"code.betamike.com/cryptic-io/pmux/pmuxlib"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
)
|
||||
|
||||
func garageAdminClientLogger(logger *mlog.Logger) *mlog.Logger {
|
||||
return logger.WithNamespace("garage-admin-client")
|
||||
}
|
||||
|
||||
// newGarageAdminClient will return an AdminClient for a local garage instance,
|
||||
// or it will _panic_ if there is no local instance configured.
|
||||
func newGarageAdminClient(
|
||||
logger *mlog.Logger,
|
||||
hostBootstrap bootstrap.Bootstrap,
|
||||
daemonConfig daemon.Config,
|
||||
hostBootstrap bootstrap.Bootstrap, daemonConfig daemon.Config,
|
||||
) *garage.AdminClient {
|
||||
|
||||
thisHost := hostBootstrap.ThisHost()
|
||||
@ -34,31 +27,23 @@ func newGarageAdminClient(
|
||||
strconv.Itoa(daemonConfig.Storage.Allocations[0].AdminPort),
|
||||
),
|
||||
hostBootstrap.Garage.AdminToken,
|
||||
garageAdminClientLogger(logger),
|
||||
)
|
||||
}
|
||||
|
||||
func waitForGarageAndNebula(
|
||||
ctx context.Context,
|
||||
logger *mlog.Logger,
|
||||
hostBootstrap bootstrap.Bootstrap,
|
||||
daemonConfig daemon.Config,
|
||||
) error {
|
||||
|
||||
if err := waitForNebula(ctx, hostBootstrap); err != nil {
|
||||
return fmt.Errorf("waiting for nebula to start: %w", err)
|
||||
}
|
||||
|
||||
allocs := daemonConfig.Storage.Allocations
|
||||
|
||||
// if this host doesn't have any allocations specified then fall back to
|
||||
// waiting for nebula
|
||||
if len(allocs) == 0 {
|
||||
return nil
|
||||
return waitForNebula(ctx, hostBootstrap)
|
||||
}
|
||||
|
||||
logger = garageAdminClientLogger(logger)
|
||||
|
||||
for _, alloc := range allocs {
|
||||
|
||||
adminAddr := net.JoinHostPort(
|
||||
@ -69,11 +54,10 @@ func waitForGarageAndNebula(
|
||||
adminClient := garage.NewAdminClient(
|
||||
adminAddr,
|
||||
hostBootstrap.Garage.AdminToken,
|
||||
logger,
|
||||
)
|
||||
|
||||
if err := adminClient.Wait(ctx); err != nil {
|
||||
return fmt.Errorf("waiting for garage instance %q to start up: %w", adminAddr, err)
|
||||
return fmt.Errorf("waiting for instance %q to start up: %w", adminAddr, err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,13 +161,12 @@ func garagePmuxProcConfigs(
|
||||
|
||||
func garageInitializeGlobalBucket(
|
||||
ctx context.Context,
|
||||
logger *mlog.Logger,
|
||||
hostBootstrap bootstrap.Bootstrap,
|
||||
daemonConfig daemon.Config,
|
||||
) error {
|
||||
|
||||
var (
|
||||
adminClient = newGarageAdminClient(logger, hostBootstrap, daemonConfig)
|
||||
adminClient = newGarageAdminClient(hostBootstrap, daemonConfig)
|
||||
globalBucketCreds = hostBootstrap.Garage.GlobalBucketS3APICredentials
|
||||
)
|
||||
|
||||
@ -240,13 +223,12 @@ func garageInitializeGlobalBucket(
|
||||
|
||||
func garageApplyLayout(
|
||||
ctx context.Context,
|
||||
logger *mlog.Logger,
|
||||
hostBootstrap bootstrap.Bootstrap,
|
||||
daemonConfig daemon.Config,
|
||||
) error {
|
||||
|
||||
var (
|
||||
adminClient = newGarageAdminClient(logger, hostBootstrap, daemonConfig)
|
||||
adminClient = newGarageAdminClient(hostBootstrap, daemonConfig)
|
||||
thisHost = hostBootstrap.ThisHost()
|
||||
hostName = thisHost.Name
|
||||
allocs = daemonConfig.Storage.Allocations
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"regexp"
|
||||
"sort"
|
||||
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@ -29,32 +28,12 @@ var subCmdHostsList = subCmd{
|
||||
checkLock: true,
|
||||
do: func(subCmdCtx subCmdCtx) error {
|
||||
|
||||
flags := subCmdCtx.flagSet(false)
|
||||
|
||||
logLevelStr := flags.StringP(
|
||||
"log-level", "l", "info",
|
||||
`Maximum log level which should be output. Values can be "debug", "info", "warn", "error", "fatal". Does not apply to sub-processes`,
|
||||
)
|
||||
|
||||
if err := flags.Parse(subCmdCtx.args); err != nil {
|
||||
return fmt.Errorf("parsing flags: %w", err)
|
||||
}
|
||||
|
||||
ctx := subCmdCtx.ctx
|
||||
|
||||
logLevel := mlog.LevelFromString(*logLevelStr)
|
||||
if logLevel == nil {
|
||||
return fmt.Errorf("couldn't parse log level %q", *logLevelStr)
|
||||
}
|
||||
|
||||
logger := subCmdCtx.logger.WithMaxLevel(logLevel.Int())
|
||||
|
||||
hostBootstrap, err := loadHostBootstrap()
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading host bootstrap: %w", err)
|
||||
}
|
||||
|
||||
hostsMap, err := hostBootstrap.GetGarageBootstrapHosts(ctx, logger)
|
||||
hostsMap, err := hostBootstrap.GetGarageBootstrapHosts(subCmdCtx.ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("retrieving hosts from garage: %w", err)
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
)
|
||||
|
||||
type logMsgHandler struct {
|
||||
stderr *os.File
|
||||
l sync.Mutex
|
||||
}
|
||||
|
||||
func newLogMsgHandler() mlog.MessageHandler {
|
||||
return &logMsgHandler{
|
||||
stderr: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *logMsgHandler) Sync() error {
|
||||
return h.stderr.Sync()
|
||||
}
|
||||
|
||||
func (h *logMsgHandler) Handle(msg mlog.FullMessage) error {
|
||||
h.l.Lock()
|
||||
defer h.l.Unlock()
|
||||
|
||||
var namespaceStr string
|
||||
|
||||
if len(msg.Namespace) > 0 {
|
||||
namespaceStr = "[" + path.Join(msg.Namespace...) + "] "
|
||||
}
|
||||
|
||||
var annotationsStr string
|
||||
|
||||
if m := mctx.EvaluateAnnotations(msg.Context, nil).StringMap(); len(m) > 0 {
|
||||
|
||||
for k, v := range m {
|
||||
annotationsStr += fmt.Sprintf(" %q=%q", k, v)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(
|
||||
h.stderr, "%s %s%s%s\n",
|
||||
msg.Level.String(),
|
||||
namespaceStr,
|
||||
msg.Description,
|
||||
annotationsStr,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
@ -2,14 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/adrg/xdg"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
)
|
||||
|
||||
// The purpose of this binary is to act as the entrypoint of the cryptic-net
|
||||
@ -33,12 +32,6 @@ var (
|
||||
|
||||
func main() {
|
||||
|
||||
logger := mlog.NewLogger(&mlog.LoggerOpts{
|
||||
MessageHandler: newLogMsgHandler(),
|
||||
MaxLevel: mlog.LevelInfo.Int(),
|
||||
})
|
||||
defer logger.Close()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
signalCh := make(chan os.Signal, 2)
|
||||
@ -47,20 +40,18 @@ func main() {
|
||||
go func() {
|
||||
sig := <-signalCh
|
||||
cancel()
|
||||
|
||||
ctx := mctx.Annotate(ctx, "signal", sig.String())
|
||||
logger.Info(ctx, "got signal, exiting gracefully")
|
||||
fmt.Fprintf(os.Stderr, "got signal %v, will exit gracefully\n", sig)
|
||||
|
||||
sig = <-signalCh
|
||||
fmt.Fprintf(os.Stderr, "second interrupt signal %v received, force quitting, there may be zombie children left behind, good luck!\n", sig)
|
||||
|
||||
ctx = mctx.Annotate(ctx, "signal", sig.String())
|
||||
logger.FatalString(ctx, "second signal received, force quitting, there may be zombie children left behind, good luck!")
|
||||
os.Stderr.Sync()
|
||||
os.Exit(1)
|
||||
}()
|
||||
|
||||
err := subCmdCtx{
|
||||
args: os.Args[1:],
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
args: os.Args[1:],
|
||||
ctx: ctx,
|
||||
}.doSubCmd(
|
||||
subCmdAdmin,
|
||||
subCmdDaemon,
|
||||
@ -70,6 +61,6 @@ func main() {
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Fatal(ctx, "error running command", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
"github.com/shirou/gopsutil/process"
|
||||
)
|
||||
|
||||
@ -47,10 +44,9 @@ func writeLock() error {
|
||||
}
|
||||
|
||||
// returns a cleanup function which will clean up the created runtime directory.
|
||||
func setupAndLockRuntimeDir(ctx context.Context, logger *mlog.Logger) (func(), error) {
|
||||
func setupAndLockRuntimeDir() (func(), error) {
|
||||
|
||||
ctx = mctx.Annotate(ctx, "runtime-dir-path", envRuntimeDirPath)
|
||||
logger.Info(ctx, "will use runtime directory for temporary state")
|
||||
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", envRuntimeDirPath)
|
||||
|
||||
if err := os.MkdirAll(envRuntimeDirPath, 0700); err != nil {
|
||||
return nil, fmt.Errorf("creating directory %q: %w", envRuntimeDirPath, err)
|
||||
@ -60,9 +56,9 @@ func setupAndLockRuntimeDir(ctx context.Context, logger *mlog.Logger) (func(), e
|
||||
}
|
||||
|
||||
return func() {
|
||||
logger.Info(ctx, "cleaning up runtime directory")
|
||||
fmt.Fprintf(os.Stderr, "cleaning up runtime directory %q\n", envRuntimeDirPath)
|
||||
if err := os.RemoveAll(envRuntimeDirPath); err != nil {
|
||||
logger.Error(ctx, "removing temporary directory", err)
|
||||
fmt.Fprintf(os.Stderr, "error removing temporary directory %q: %v", envRuntimeDirPath, err)
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
@ -16,8 +15,7 @@ type subCmdCtx struct {
|
||||
args []string // command-line arguments, excluding the subCmd itself.
|
||||
subCmdNames []string // names of subCmds so far, including this one
|
||||
|
||||
ctx context.Context
|
||||
logger *mlog.Logger
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type subCmd struct {
|
||||
@ -112,7 +110,6 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
|
||||
args: args,
|
||||
subCmdNames: append(ctx.subCmdNames, subCmdName),
|
||||
ctx: ctx.ctx,
|
||||
logger: ctx.logger,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
@ -7,10 +7,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"time"
|
||||
|
||||
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
||||
)
|
||||
|
||||
// AdminClientError gets returned from AdminClient's Do method for non-200
|
||||
@ -30,21 +27,17 @@ type AdminClient struct {
|
||||
c *http.Client
|
||||
addr string
|
||||
adminToken string
|
||||
logger *mlog.Logger
|
||||
}
|
||||
|
||||
// NewAdminClient initializes and returns an AdminClient which will use the
|
||||
// given address and adminToken for all requests made.
|
||||
//
|
||||
// If Logger is nil then logs will be suppressed.
|
||||
func NewAdminClient(addr, adminToken string, logger *mlog.Logger) *AdminClient {
|
||||
func NewAdminClient(addr, adminToken string) *AdminClient {
|
||||
return &AdminClient{
|
||||
c: &http.Client{
|
||||
Transport: http.DefaultTransport.(*http.Transport).Clone(),
|
||||
},
|
||||
addr: addr,
|
||||
adminToken: adminToken,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,31 +68,11 @@ func (c *AdminClient) Do(
|
||||
|
||||
req.Header.Set("Authorization", "Bearer "+c.adminToken)
|
||||
|
||||
if c.logger.MaxLevel() >= mlog.LevelDebug.Int() {
|
||||
|
||||
reqB, err := httputil.DumpRequestOut(req, true)
|
||||
if err != nil {
|
||||
c.logger.Error(ctx, "failed to dump http request", err)
|
||||
} else {
|
||||
c.logger.Debug(ctx, "------ request ------\n"+string(reqB)+"\n")
|
||||
}
|
||||
}
|
||||
|
||||
res, err := c.c.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("performing http request: %w", err)
|
||||
}
|
||||
|
||||
if c.logger.MaxLevel() >= mlog.LevelDebug.Int() {
|
||||
|
||||
resB, err := httputil.DumpResponse(res, true)
|
||||
if err != nil {
|
||||
c.logger.Error(ctx, "failed to dump http response", err)
|
||||
} else {
|
||||
c.logger.Debug(ctx, "------ response ------\n"+string(resB)+"\n")
|
||||
}
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
@ -130,12 +103,7 @@ func (c *AdminClient) Do(
|
||||
// ReplicationFactor-1 other garage instances. If the context is canceled it
|
||||
// will return the context error.
|
||||
func (c *AdminClient) Wait(ctx context.Context) error {
|
||||
|
||||
for first := true; ; first = false {
|
||||
|
||||
if !first {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
}
|
||||
for {
|
||||
|
||||
var clusterStatus struct {
|
||||
KnownNodes map[string]struct {
|
||||
@ -164,5 +132,6 @@ func (c *AdminClient) Wait(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ require (
|
||||
code.betamike.com/cryptic-io/pmux v0.0.0-20221025185405-29241f144a2d
|
||||
github.com/adrg/xdg v0.4.0
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/mediocregopher/mediocre-go-lib/v2 v2.0.0-beta.1.0.20221113151154-07f3889a705b
|
||||
github.com/minio/minio-go/v7 v7.0.28
|
||||
github.com/nlepage/go-tarfs v1.1.0
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/slackhq/nebula v1.6.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
|
@ -1,3 +1,5 @@
|
||||
code.betamike.com/cryptic-io/pmux v0.0.0-20221020185531-7a7868003822 h1:c7Eu2h8gXOpOfhC1LvSYLNfiSsWTyvdI1XVpUuqMFHE=
|
||||
code.betamike.com/cryptic-io/pmux v0.0.0-20221020185531-7a7868003822/go.mod h1:cBuEN/rkaM/GH24uQroX/++qDmte+mLudDUqMt6XJWs=
|
||||
code.betamike.com/cryptic-io/pmux v0.0.0-20221025185405-29241f144a2d h1:s6nDTg23o9ujZZnl8ohZBDoG4SqPUyFfvod9DQjwmNU=
|
||||
code.betamike.com/cryptic-io/pmux v0.0.0-20221025185405-29241f144a2d/go.mod h1:cBuEN/rkaM/GH24uQroX/++qDmte+mLudDUqMt6XJWs=
|
||||
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
||||
@ -34,8 +36,6 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mediocregopher/mediocre-go-lib/v2 v2.0.0-beta.1.0.20221113151154-07f3889a705b h1:A+IqPY72GXChyCje7YqnZrb8Q4ajUqft/etsmIOobu4=
|
||||
github.com/mediocregopher/mediocre-go-lib/v2 v2.0.0-beta.1.0.20221113151154-07f3889a705b/go.mod h1:wOZVlnKYvIbkzyCJ3dxy1k40XkirvCd1pisX2O91qoQ=
|
||||
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio-go/v7 v7.0.28 h1:VMr3K5qGIEt+/KW3poopRh8mzi5RwuCjmrmstK196Fg=
|
||||
@ -49,6 +49,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/nlepage/go-tarfs v1.1.0 h1:bsACOiZMB/zFjYG/sE01070i9Fl26MnRpw0L6WuyfVs=
|
||||
github.com/nlepage/go-tarfs v1.1.0/go.mod h1:IhxRcLhLkawBetnwu/JNuoPkq/6cclAllhgEa6SmzS8=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
@ -69,6 +71,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
|
Loading…
Reference in New Issue
Block a user