storj/private/testplanet/multinode.go

140 lines
3.4 KiB
Go
Raw Normal View History

// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information
package testplanet
import (
"context"
"fmt"
"os"
"path/filepath"
"runtime/pprof"
"strconv"
"github.com/zeebo/errs"
"go.uber.org/zap"
"storj.io/common/storj"
"storj.io/private/debug"
"storj.io/storj/multinode"
"storj.io/storj/multinode/console/server"
"storj.io/storj/multinode/multinodedb"
)
// Multinode contains all the processes needed to run a full multinode setup.
type Multinode struct {
Name string
Config multinode.Config
*multinode.Peer
}
// ID returns multinode id.
func (system *Multinode) ID() storj.NodeID { return system.Identity.ID }
// Addr returns the public address.
func (system *Multinode) Addr() string { return system.Console.Listener.Addr().String() }
// Label returns name for debugger.
func (system *Multinode) Label() string { return system.Name }
// URL returns the NodeURL as a string.
func (system *Multinode) URL() string { return system.NodeURL().String() }
// NodeURL returns the storj.NodeURL.
func (system *Multinode) NodeURL() storj.NodeURL {
return storj.NodeURL{ID: system.ID(), Address: system.Addr()}
}
// ConsoleURL returns the console URL.
func (system *Multinode) ConsoleURL() string {
return "http://" + system.Addr()
}
// newMultinodes initializes multinode dashboards.
func (planet *Planet) newMultinodes(ctx context.Context, prefix string, count int) (_ []*Multinode, err error) {
defer mon.Task()(&ctx)(&err)
var xs []*Multinode
for i := 0; i < count; i++ {
index := i
name := prefix + strconv.Itoa(index)
log := planet.log.Named(name)
var system *Multinode
var err error
pprof.Do(ctx, pprof.Labels("peer", name), func(ctx context.Context) {
system, err = planet.newMultinode(ctx, name, index, log)
})
if err != nil {
return nil, errs.Wrap(err)
}
log.Debug("id=" + system.ID().String() + " addr=" + system.Addr())
xs = append(xs, system)
planet.peers = append(planet.peers, newClosablePeer(system))
}
return xs, nil
}
func (planet *Planet) newMultinode(ctx context.Context, prefix string, index int, log *zap.Logger) (_ *Multinode, err error) {
defer mon.Task()(&ctx)(&err)
storageDir := filepath.Join(planet.directory, prefix)
if err := os.MkdirAll(storageDir, 0700); err != nil {
return nil, errs.Wrap(err)
}
identity, err := planet.NewIdentity()
if err != nil {
return nil, errs.Wrap(err)
}
config := multinode.Config{
Debug: debug.Config{
Address: "",
},
Console: server.Config{
Address: "127.0.0.1:0",
StaticDir: filepath.Join(developmentRoot, "web/multinode/"),
},
}
if planet.config.Reconfigure.Multinode != nil {
planet.config.Reconfigure.Multinode(index, &config)
}
database := fmt.Sprintf("sqlite3://file:%s/master.db", storageDir)
var db multinode.DB
db, err = multinodedb.Open(ctx, log.Named("db"), database)
if err != nil {
return nil, errs.Wrap(err)
}
if planet.config.Reconfigure.MultinodeDB != nil {
db, err = planet.config.Reconfigure.MultinodeDB(index, db, planet.log)
if err != nil {
return nil, errs.Wrap(err)
}
}
peer, err := multinode.New(log, identity, config, db)
if err != nil {
return nil, errs.Wrap(err)
}
err = db.MigrateToLatest(ctx)
if err != nil {
return nil, errs.Wrap(err)
}
planet.databases = append(planet.databases, db)
log.Debug(peer.Console.Listener.Addr().String())
return &Multinode{
Name: prefix,
Config: config,
Peer: peer,
}, nil
}