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