5452b59a2e
* Update go-libp2p to v0.22.0 * Testing with go1.19 * build(deps): bump github.com/multiformats/go-multicodec Bumps [github.com/multiformats/go-multicodec](https://github.com/multiformats/go-multicodec) from 0.5.0 to 0.6.0. - [Release notes](https://github.com/multiformats/go-multicodec/releases) - [Commits](https://github.com/multiformats/go-multicodec/compare/v0.5.0...v0.6.0) --- updated-dependencies: - dependency-name: github.com/multiformats/go-multicodec dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ipld/go-car from 0.4.0 to 0.5.0 Bumps [github.com/ipld/go-car](https://github.com/ipld/go-car) from 0.4.0 to 0.5.0. - [Release notes](https://github.com/ipld/go-car/releases) - [Commits](https://github.com/ipld/go-car/compare/v0.4.0...v0.5.0) --- updated-dependencies: - dependency-name: github.com/ipld/go-car dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/prometheus/client_golang Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.2 to 1.13.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.12.2...v1.13.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/hashicorp/go-hclog from 1.2.1 to 1.3.0 Bumps [github.com/hashicorp/go-hclog](https://github.com/hashicorp/go-hclog) from 1.2.1 to 1.3.0. - [Release notes](https://github.com/hashicorp/go-hclog/releases) - [Commits](https://github.com/hashicorp/go-hclog/compare/v1.2.1...v1.3.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/go-hclog dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/ipfs/go-ds-crdt from 0.3.6 to 0.3.7 Bumps [github.com/ipfs/go-ds-crdt](https://github.com/ipfs/go-ds-crdt) from 0.3.6 to 0.3.7. - [Release notes](https://github.com/ipfs/go-ds-crdt/releases) - [Commits](https://github.com/ipfs/go-ds-crdt/compare/v0.3.6...v0.3.7) --- updated-dependencies: - dependency-name: github.com/ipfs/go-ds-crdt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/urfave/cli/v2 from 2.10.2 to 2.14.1 Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.10.2 to 2.14.1. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.10.2...v2.14.1) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/libp2p/go-libp2p-http from 0.3.0 to 0.4.0 Bumps [github.com/libp2p/go-libp2p-http](https://github.com/libp2p/go-libp2p-http) from 0.3.0 to 0.4.0. - [Release notes](https://github.com/libp2p/go-libp2p-http/releases) - [Commits](https://github.com/libp2p/go-libp2p-http/compare/v0.3.0...v0.4.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-http dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/libp2p/go-libp2p-gorpc from 0.4.0 to 0.5.0 Bumps [github.com/libp2p/go-libp2p-gorpc](https://github.com/libp2p/go-libp2p-gorpc) from 0.4.0 to 0.5.0. - [Release notes](https://github.com/libp2p/go-libp2p-gorpc/releases) - [Commits](https://github.com/libp2p/go-libp2p-gorpc/compare/v0.4.0...v0.5.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-gorpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump contrib.go.opencensus.io/exporter/prometheus Bumps [contrib.go.opencensus.io/exporter/prometheus](https://github.com/census-ecosystem/opencensus-go-exporter-prometheus) from 0.4.1 to 0.4.2. - [Release notes](https://github.com/census-ecosystem/opencensus-go-exporter-prometheus/releases) - [Commits](https://github.com/census-ecosystem/opencensus-go-exporter-prometheus/compare/v0.4.1...v0.4.2) --- updated-dependencies: - dependency-name: contrib.go.opencensus.io/exporter/prometheus dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/libp2p/go-libp2p-raft from 0.1.8 to 0.2.0 Bumps [github.com/libp2p/go-libp2p-raft](https://github.com/libp2p/go-libp2p-raft) from 0.1.8 to 0.2.0. - [Release notes](https://github.com/libp2p/go-libp2p-raft/releases) - [Commits](https://github.com/libp2p/go-libp2p-raft/compare/v0.1.8...v0.2.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-raft dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump github.com/urfave/cli from 1.22.9 to 1.22.10 Bumps [github.com/urfave/cli](https://github.com/urfave/cli) from 1.22.9 to 1.22.10. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v1.22.9...v1.22.10) --- updated-dependencies: - dependency-name: github.com/urfave/cli dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Fix checker/linter/staticcheck warnings Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
208 lines
4.9 KiB
Go
208 lines
4.9 KiB
Go
// Package cmdutils contains utilities to facilitate building of command line
|
|
// applications launching cluster peers.
|
|
package cmdutils
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/ipfs/go-datastore"
|
|
ipfscluster "github.com/ipfs-cluster/ipfs-cluster"
|
|
ipfshttp "github.com/ipfs-cluster/ipfs-cluster/ipfsconn/ipfshttp"
|
|
host "github.com/libp2p/go-libp2p/core/host"
|
|
dual "github.com/libp2p/go-libp2p-kad-dht/dual"
|
|
ma "github.com/multiformats/go-multiaddr"
|
|
"github.com/pkg/errors"
|
|
"go.uber.org/multierr"
|
|
)
|
|
|
|
// RandomizePorts replaces TCP and UDP ports with random, but valid port
|
|
// values, on the given multiaddresses
|
|
func RandomizePorts(addrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
|
results := make([]ma.Multiaddr, 0, len(addrs))
|
|
|
|
for _, m := range addrs {
|
|
var prev string
|
|
var err error
|
|
components := []ma.Multiaddr{}
|
|
ma.ForEach(m, func(c ma.Component) bool {
|
|
code := c.Protocol().Code
|
|
|
|
if code != ma.P_TCP && code != ma.P_UDP {
|
|
components = append(components, &c)
|
|
prev = c.Value()
|
|
return true
|
|
}
|
|
|
|
var ln io.Closer
|
|
var port int
|
|
|
|
ip := prev
|
|
if strings.Contains(ip, ":") { // ipv6 needs bracketing
|
|
ip = "[" + ip + "]"
|
|
}
|
|
|
|
if c.Protocol().Code == ma.P_UDP {
|
|
ln, port, err = listenUDP(c.Protocol().Name, ip)
|
|
} else {
|
|
ln, port, err = listenTCP(c.Protocol().Name, ip)
|
|
}
|
|
if err != nil {
|
|
return false
|
|
}
|
|
defer ln.Close()
|
|
|
|
var c1 *ma.Component
|
|
c1, err = ma.NewComponent(c.Protocol().Name, fmt.Sprintf("%d", port))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
components = append(components, c1)
|
|
prev = c.Value()
|
|
|
|
return true
|
|
})
|
|
if err != nil {
|
|
return results, err
|
|
}
|
|
results = append(results, ma.Join(components...))
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
// returns the listener so it can be closed later and port
|
|
func listenTCP(name, ip string) (io.Closer, int, error) {
|
|
ln, err := net.Listen(name, ip+":0")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return ln, ln.Addr().(*net.TCPAddr).Port, nil
|
|
}
|
|
|
|
// returns the listener so it can be cloesd later and port
|
|
func listenUDP(name, ip string) (io.Closer, int, error) {
|
|
ln, err := net.ListenPacket(name, ip+":0")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return ln, ln.LocalAddr().(*net.UDPAddr).Port, nil
|
|
}
|
|
|
|
// HandleSignals orderly shuts down an IPFS Cluster peer
|
|
// on SIGINT, SIGTERM, SIGHUP. It forces command termination
|
|
// on the 3rd-signal count.
|
|
func HandleSignals(
|
|
ctx context.Context,
|
|
cancel context.CancelFunc,
|
|
cluster *ipfscluster.Cluster,
|
|
host host.Host,
|
|
dht *dual.DHT,
|
|
store datastore.Datastore,
|
|
) error {
|
|
signalChan := make(chan os.Signal, 20)
|
|
signal.Notify(
|
|
signalChan,
|
|
syscall.SIGINT,
|
|
syscall.SIGTERM,
|
|
syscall.SIGHUP,
|
|
)
|
|
|
|
var ctrlcCount int
|
|
for {
|
|
select {
|
|
case <-signalChan:
|
|
ctrlcCount++
|
|
handleCtrlC(ctx, cluster, ctrlcCount)
|
|
case <-cluster.Done():
|
|
cancel()
|
|
return multierr.Combine(
|
|
dht.Close(),
|
|
host.Close(),
|
|
store.Close(),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleCtrlC(ctx context.Context, cluster *ipfscluster.Cluster, ctrlcCount int) {
|
|
switch ctrlcCount {
|
|
case 1:
|
|
go func() {
|
|
if err := cluster.Shutdown(ctx); err != nil {
|
|
ErrorOut("error shutting down cluster: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
}()
|
|
case 2:
|
|
ErrorOut(`
|
|
|
|
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
Shutdown is taking too long! Press Ctrl-c again to manually kill cluster.
|
|
Note that this may corrupt the local cluster state.
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
`)
|
|
case 3:
|
|
ErrorOut("exiting cluster NOW")
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// ErrorOut formats something and prints it to sdterr.
|
|
func ErrorOut(m string, a ...interface{}) {
|
|
fmt.Fprintf(os.Stderr, m, a...)
|
|
}
|
|
|
|
// WaitForIPFS hangs until IPFS API becomes available or the given context is
|
|
// canceled. The IPFS API location is determined by the default ipfshttp
|
|
// component configuration and can be overridden using environment variables
|
|
// that affect that configuration. Note that we have to do this in the blind,
|
|
// since we want to wait for IPFS before we even fetch the IPFS component
|
|
// configuration (because the configuration might be hosted on IPFS itself)
|
|
func WaitForIPFS(ctx context.Context) error {
|
|
ipfshttpCfg := ipfshttp.Config{}
|
|
ipfshttpCfg.Default()
|
|
ipfshttpCfg.ApplyEnvVars()
|
|
ipfshttpCfg.ConnectSwarmsDelay = 0
|
|
ipfshttpCfg.Tracing = false
|
|
ipfscluster.SetFacilityLogLevel("ipfshttp", "critical")
|
|
defer ipfscluster.SetFacilityLogLevel("ipfshttp", "info")
|
|
ipfs, err := ipfshttp.NewConnector(&ipfshttpCfg)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error creating an ipfshttp instance to wait for IPFS")
|
|
}
|
|
|
|
i := 0
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
default:
|
|
if i%10 == 0 {
|
|
fmt.Printf("waiting for IPFS to become available on %s...\n", ipfshttpCfg.NodeAddr)
|
|
}
|
|
i++
|
|
time.Sleep(time.Second)
|
|
_, err := ipfs.ID(ctx)
|
|
if err == nil {
|
|
// sleep an extra second and quit
|
|
time.Sleep(time.Second)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|