Skip to content

Commit

Permalink
Merge branch 'main' into static-ports-by-default
Browse files Browse the repository at this point in the history
  • Loading branch information
felipemadero committed Sep 26, 2022
2 parents 7605888 + 30b1a20 commit 173abf7
Show file tree
Hide file tree
Showing 14 changed files with 560 additions and 439 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,7 @@ The helper function `NewDefaultNetwork` returns a network using a pre-defined co
func NewDefaultNetwork(
log logging.Logger,
binaryPath string,
reassignPortsIfUsed,
) (network.Network, error)
```
Expand Down
31 changes: 20 additions & 11 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func (c *client) Start(ctx context.Context, execPath string, opts ...OpOption) (
if ret.customNodeConfigs != nil {
req.CustomNodeConfigs = ret.customNodeConfigs
}
req.ReassignPortsIfUsed = &ret.reassignPortsIfUsed

c.log.Info("start")
return c.controlc.Start(ctx, req)
Expand Down Expand Up @@ -301,6 +302,7 @@ func (c *client) LoadSnapshot(ctx context.Context, snapshotName string, opts ...
if ret.globalNodeConfig != "" {
req.GlobalNodeConfig = &ret.globalNodeConfig
}
req.ReassignPortsIfUsed = &ret.reassignPortsIfUsed
return c.controlc.LoadSnapshot(ctx, &req)
}

Expand All @@ -326,17 +328,18 @@ func (c *client) Close() error {
}

type Op struct {
numNodes uint32
execPath string
whitelistedSubnets string
globalNodeConfig string
rootDataDir string
pluginDir string
blockchainSpecs []*rpcpb.BlockchainSpec
customNodeConfigs map[string]string
numSubnets uint32
chainConfigs map[string]string
upgradeConfigs map[string]string
numNodes uint32
execPath string
whitelistedSubnets string
globalNodeConfig string
rootDataDir string
pluginDir string
blockchainSpecs []*rpcpb.BlockchainSpec
customNodeConfigs map[string]string
numSubnets uint32
chainConfigs map[string]string
upgradeConfigs map[string]string
reassignPortsIfUsed bool
}

type OpOption func(*Op)
Expand Down Expand Up @@ -417,6 +420,12 @@ func WithNumSubnets(numSubnets uint32) OpOption {
}
}

func WithReassignPortsIfUsed(reassignPortsIfUsed bool) OpOption {
return func(op *Op) {
op.reassignPortsIfUsed = reassignPortsIfUsed
}
}

func isClientCanceled(ctxErr error, err error) bool {
if ctxErr != nil {
return true
Expand Down
37 changes: 26 additions & 11 deletions cmd/control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,18 @@ func NewCommand() *cobra.Command {
}

var (
avalancheGoBinPath string
numNodes uint32
pluginDir string
globalNodeConfig string
addNodeConfig string
blockchainSpecsStr string
customNodeConfigs string
rootDataDir string
numSubnets uint32
chainConfigs string
upgradeConfigs string
avalancheGoBinPath string
numNodes uint32
pluginDir string
globalNodeConfig string
addNodeConfig string
blockchainSpecsStr string
customNodeConfigs string
rootDataDir string
numSubnets uint32
chainConfigs string
upgradeConfigs string
reassignPortsIfUsed bool
)

func newStartCommand() *cobra.Command {
Expand Down Expand Up @@ -170,6 +171,12 @@ func newStartCommand() *cobra.Command {
"",
"[optional] JSON string of map from chain id to its upgrade file contents",
)
cmd.PersistentFlags().BoolVar(
&reassignPortsIfUsed,
"reassign-ports-if-used",
false,
"true to reassign given ports if already taken",
)
if err := cmd.MarkPersistentFlagRequired("avalanchego-path"); err != nil {
panic(err)
}
Expand All @@ -188,6 +195,7 @@ func startFunc(cmd *cobra.Command, args []string) error {
client.WithPluginDir(pluginDir),
client.WithWhitelistedSubnets(whitelistedSubnets),
client.WithRootDataDir(rootDataDir),
client.WithReassignPortsIfUsed(reassignPortsIfUsed),
}

if globalNodeConfig != "" {
Expand Down Expand Up @@ -854,6 +862,12 @@ func newLoadSnapshotCommand() *cobra.Command {
"",
"[optional] global node config as JSON string, applied to all nodes",
)
cmd.PersistentFlags().BoolVar(
&reassignPortsIfUsed,
"reassign-ports-if-used",
false,
"true to reassign snapshot ports if already taken",
)
return cmd
}

Expand All @@ -868,6 +882,7 @@ func loadSnapshotFunc(cmd *cobra.Command, args []string) error {
client.WithExecPath(avalancheGoBinPath),
client.WithPluginDir(pluginDir),
client.WithRootDataDir(rootDataDir),
client.WithReassignPortsIfUsed(reassignPortsIfUsed),
}

if chainConfigs != "" {
Expand Down
2 changes: 1 addition & 1 deletion examples/local/fivenodenetwork/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func main() {

func run(log logging.Logger, binaryPath string) error {
// Create the network
nw, err := local.NewDefaultNetwork(log, binaryPath)
nw, err := local.NewDefaultNetwork(log, binaryPath, true)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion examples/local/indepth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func main() {

func run(log logging.Logger, binaryPath string) error {
// Create the network
nw, err := local.NewDefaultNetwork(log, binaryPath)
nw, err := local.NewDefaultNetwork(log, binaryPath, true)
if err != nil {
return err
}
Expand Down
14 changes: 13 additions & 1 deletion local/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ func getConfigEntry(
}

// getPort looks up the port config in the config file, if there is none, it tries to get a random free port from the OS
// if [reassingIfUsed] is true, and the port from config is not free, also tries to get a random free port
func getPort(
flags map[string]interface{},
configFile map[string]interface{},
portKey string,
reassignIfUsed bool,
) (port uint16, err error) {
if portIntf, ok := flags[portKey]; ok {
if portFromFlags, ok := portIntf.(int); ok {
Expand All @@ -123,9 +125,19 @@ func getPort(
// Note: it is possible but unlikely for getFreePort to return the same port multiple times.
port, err = getFreePort()
if err != nil {
return 0, fmt.Errorf("couldn't get free API port: %w", err)
return 0, fmt.Errorf("couldn't get free port: %w", err)
}
}
if reassignIfUsed && !isFreePort(port) {
port, err = getFreePort()
if err != nil {
return 0, fmt.Errorf("couldn't get free port: %w", err)
}
}
// last check, avoid starting network with used ports
if !isFreePort(port) {
return 0, fmt.Errorf("port %d is not free", port)
}
return port, nil
}

Expand Down
40 changes: 28 additions & 12 deletions local/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type localNetwork struct {
chainConfigFiles map[string]string
// upgrade config files to use per default
upgradeConfigFiles map[string]string
// if true, for ports given in conf that are already taken, assign new random ones
reassignPortsIfUsed bool
}

var (
Expand Down Expand Up @@ -228,6 +230,7 @@ func NewNetwork(
networkConfig network.Config,
rootDir string,
snapshotsDir string,
reassignPortsIfUsed bool,
) (network.Network, error) {
net, err := newNetwork(
log,
Expand All @@ -240,6 +243,7 @@ func NewNetwork(
},
rootDir,
snapshotsDir,
reassignPortsIfUsed,
)
if err != nil {
return net, err
Expand All @@ -256,6 +260,7 @@ func newNetwork(
nodeProcessCreator NodeProcessCreator,
rootDir string,
snapshotsDir string,
reassignPortsIfUsed bool,
) (*localNetwork, error) {
var err error
if rootDir == "" {
Expand All @@ -275,15 +280,16 @@ func newNetwork(
}
// Create the network
net := &localNetwork{
nextNodeSuffix: 1,
nodes: map[string]*localNode{},
onStopCh: make(chan struct{}),
log: log,
bootstraps: beacon.NewSet(),
newAPIClientF: newAPIClientF,
nodeProcessCreator: nodeProcessCreator,
rootDir: rootDir,
snapshotsDir: snapshotsDir,
nextNodeSuffix: 1,
nodes: map[string]*localNode{},
onStopCh: make(chan struct{}),
log: log,
bootstraps: beacon.NewSet(),
newAPIClientF: newAPIClientF,
nodeProcessCreator: nodeProcessCreator,
rootDir: rootDir,
snapshotsDir: snapshotsDir,
reassignPortsIfUsed: reassignPortsIfUsed,
}
return net, nil
}
Expand All @@ -310,9 +316,10 @@ func newNetwork(
func NewDefaultNetwork(
log logging.Logger,
binaryPath string,
reassignPortsIfUsed bool,
) (network.Network, error) {
config := NewDefaultConfig(binaryPath)
return NewNetwork(log, config, "", "")
return NewNetwork(log, config, "", "", reassignPortsIfUsed)
}

func copyMapStringInterface(flags map[string]interface{}) map[string]interface{} {
Expand Down Expand Up @@ -858,14 +865,14 @@ func (ln *localNetwork) buildFlags(
}

// Use random free API port unless given in config file
apiPort, err := getPort(nodeConfig.Flags, configFile, config.HTTPPortKey)
apiPort, err := getPort(nodeConfig.Flags, configFile, config.HTTPPortKey, ln.reassignPortsIfUsed)
if err != nil {
return buildFlagsReturn{}, err
}

// Use a random free P2P (staking) port unless given in config file
// Use random free API port unless given in config file
p2pPort, err := getPort(nodeConfig.Flags, configFile, config.StakingPortKey)
p2pPort, err := getPort(nodeConfig.Flags, configFile, config.StakingPortKey, ln.reassignPortsIfUsed)
if err != nil {
return buildFlagsReturn{}, err
}
Expand All @@ -888,12 +895,21 @@ func (ln *localNetwork) buildFlags(
}
flags = append(flags, fileFlags...)

// avoid given these again, as apiPort/p2pPort can be dynamic even if given in nodeConfig
portFlags := map[string]struct{}{
config.HTTPPortKey: struct{}{},
config.StakingPortKey: struct{}{},
}

// Add flags given in node config.
// Note these will overwrite existing flags if the same flag is given twice.
for flagName, flagVal := range nodeConfig.Flags {
if _, ok := warnFlags[flagName]; ok {
ln.log.Warn("A provided flag can create conflicts with the runner. The suggestion is to remove this flag", zap.String("flag-name", flagName))
}
if _, ok := portFlags[flagName]; ok {
continue
}
flags = append(flags, fmt.Sprintf("--%s=%v", flagName, flagVal))
}

Expand Down
Loading

0 comments on commit 173abf7

Please sign in to comment.