Compare commits

..

No commits in common. "da100c6170f14f30ca6099fece6e47b39ef81530" and "838c54870675fff42151e8ae75b791578f3dff5d" have entirely different histories.

14 changed files with 88 additions and 251 deletions

View File

@ -7,7 +7,7 @@
pname = "cryptic-net-entrypoint";
version = "unstable";
src = ./src;
vendorSha256 = "sha256-TTTXwztv4xwF1uXcYoSka6HwgHwU1AnClF4fguXVtK4=";
vendorSha256 = "sha256-1mHD0tmITlGjeo6F+Dvd2TdEPzxWtndy/J+uGHWKen4=";
subPackages = [
"cmd/entrypoint"
];

View File

@ -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
}

View File

@ -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,

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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)
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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

View File

@ -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=