-
Notifications
You must be signed in to change notification settings - Fork 747
[tmpnet] Avoid serializing the node data directory #3881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -239,13 +239,6 @@ func (n *Network) EnsureDefaultConfig(log logging.Logger) error { | |
n.PrimaryChainConfigs[alias].SetDefaults(chainConfig) | ||
} | ||
|
||
// Ensure nodes are configured | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discovered during testing that this configuration is duplicative - it's already being done on network bootstrap, node start, and node read |
||
for i := range n.Nodes { | ||
if err := n.EnsureNodeConfig(n.Nodes[i]); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -503,23 +496,22 @@ func (n *Network) RestartNode(ctx context.Context, log logging.Logger, node *Nod | |
|
||
// Stops all nodes in the network. | ||
func (n *Network) Stop(ctx context.Context) error { | ||
// Target all nodes, including the ephemeral ones | ||
nodes, err := ReadNodes(n, true /* includeEphemeral */) | ||
if err != nil { | ||
// Ensure the node state is up-to-date | ||
if err := n.readNodes(); err != nil { | ||
return err | ||
} | ||
|
||
var errs []error | ||
|
||
// Initiate stop on all nodes | ||
for _, node := range nodes { | ||
for _, node := range n.Nodes { | ||
if err := node.InitiateStop(ctx); err != nil { | ||
errs = append(errs, fmt.Errorf("failed to stop node %s: %w", node.NodeID, err)) | ||
} | ||
} | ||
|
||
// Wait for stop to complete on all nodes | ||
for _, node := range nodes { | ||
for _, node := range n.Nodes { | ||
if err := node.WaitForStopped(ctx); err != nil { | ||
errs = append(errs, fmt.Errorf("failed to wait for node %s to stop: %w", node.NodeID, err)) | ||
} | ||
|
@@ -543,8 +535,7 @@ func (n *Network) Restart(ctx context.Context, log logging.Logger) error { | |
} | ||
|
||
// Ensures the provided node has the configuration it needs to start. If the data dir is not | ||
// set, it will be defaulted to [nodeParentDir]/[node ID]. For a not-yet-created network, | ||
// no action will be taken. | ||
// set, it will be defaulted to [nodeParentDir]/[node ID]. | ||
func (n *Network) EnsureNodeConfig(node *Node) error { | ||
// Ensure the node has access to network configuration | ||
node.network = n | ||
|
@@ -553,14 +544,9 @@ func (n *Network) EnsureNodeConfig(node *Node) error { | |
return err | ||
} | ||
|
||
if len(n.Dir) > 0 { | ||
// Ensure the node's data dir is configured | ||
dataDir := node.GetDataDir() | ||
if len(dataDir) == 0 { | ||
// NodeID will have been set by EnsureKeys | ||
dataDir = filepath.Join(n.Dir, node.NodeID.String()) | ||
node.Flags[config.DataDirKey] = dataDir | ||
} | ||
// Ensure a data directory if not already set | ||
if len(node.DataDir) == 0 { | ||
node.DataDir = filepath.Join(n.Dir, node.NodeID.String()) | ||
} | ||
|
||
return nil | ||
|
@@ -767,16 +753,13 @@ func (n *Network) GetNodeURIs() []NodeURI { | |
// collecting the bootstrap details for restarting a node). | ||
// For consumption outside of avalanchego. Needs to be kept exported. | ||
func (n *Network) GetBootstrapIPsAndIDs(skippedNode *Node) ([]string, []string, error) { | ||
// Collect staking addresses of non-ephemeral nodes for use in bootstrapping a node | ||
nodes, err := ReadNodes(n, false /* includeEphemeral */) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there's much value in forcing a read here. The network can always be reloaded to achieve a similar result. |
||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to read network's nodes: %w", err) | ||
} | ||
var ( | ||
bootstrapIPs = make([]string, 0, len(nodes)) | ||
bootstrapIDs = make([]string, 0, len(nodes)) | ||
) | ||
for _, node := range nodes { | ||
bootstrapIPs := []string{} | ||
bootstrapIDs := []string{} | ||
for _, node := range n.Nodes { | ||
if node.IsEphemeral { | ||
// Ephemeral nodes are not guaranteed to stay running | ||
continue | ||
} | ||
if skippedNode != nil && node.NodeID == skippedNode.NodeID { | ||
continue | ||
} | ||
|
@@ -934,12 +917,16 @@ func (n *Network) writeNodeFlags(log logging.Logger, node *Node) error { | |
// Only configure the plugin dir with a non-empty value to ensure the use of | ||
// the default value (`[datadir]/plugins`) when no plugin dir is configured. | ||
processConfig := node.getRuntimeConfig().Process | ||
if processConfig != nil && len(processConfig.PluginDir) > 0 { | ||
// Ensure the plugin directory exists or the node will fail to start | ||
if err := os.MkdirAll(processConfig.PluginDir, perms.ReadWriteExecute); err != nil { | ||
return fmt.Errorf("failed to create plugin dir: %w", err) | ||
if processConfig != nil { | ||
if len(processConfig.PluginDir) > 0 { | ||
// Ensure the plugin directory exists or the node will fail to start | ||
if err := os.MkdirAll(processConfig.PluginDir, perms.ReadWriteExecute); err != nil { | ||
return fmt.Errorf("failed to create plugin dir: %w", err) | ||
} | ||
flags.SetDefault(config.PluginDirKey, processConfig.PluginDir) | ||
} | ||
flags.SetDefault(config.PluginDirKey, processConfig.PluginDir) | ||
|
||
flags.SetDefault(config.DataDirKey, node.DataDir) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The kube runtime will set its own data dir since it uses a different filesystem |
||
} | ||
|
||
// Set the network and tmpnet defaults last to ensure they can be overridden | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,13 +56,35 @@ func (n *Network) readNetwork() error { | |
return n.readConfig() | ||
} | ||
|
||
// Read the non-ephemeral nodes associated with the network from disk. | ||
// Read the nodes associated with the network from disk. | ||
func (n *Network) readNodes() error { | ||
nodes, err := ReadNodes(n, false /* includeEphemeral */) | ||
nodes := []*Node{} | ||
|
||
// Node configuration is stored in child directories | ||
entries, err := os.ReadDir(n.Dir) | ||
if err != nil { | ||
return err | ||
return fmt.Errorf("failed to read dir: %w", err) | ||
} | ||
for _, entry := range entries { | ||
if !entry.IsDir() { | ||
continue | ||
} | ||
|
||
node := NewNode() | ||
dataDir := filepath.Join(n.Dir, entry.Name()) | ||
err := node.Read(n, dataDir) | ||
if errors.Is(err, os.ErrNotExist) { | ||
// If no config file exists, assume this is not the path of a node | ||
continue | ||
} else if err != nil { | ||
return err | ||
} | ||
|
||
nodes = append(nodes, node) | ||
} | ||
|
||
n.Nodes = nodes | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -128,13 +150,13 @@ func (n *Network) readConfig() error { | |
|
||
// The subset of network fields to store in the network config file. | ||
type serializedNetworkConfig struct { | ||
UUID string `json:",omitempty"` | ||
Owner string `json:",omitempty"` | ||
PrimarySubnetConfig FlagsMap `json:",omitempty"` | ||
PrimaryChainConfigs map[string]FlagsMap `json:",omitempty"` | ||
DefaultFlags FlagsMap `json:",omitempty"` | ||
DefaultRuntimeConfig NodeRuntimeConfig `json:",omitempty"` | ||
PreFundedKeys []*secp256k1.PrivateKey `json:",omitempty"` | ||
UUID string `json:"uuid,omitempty"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reviewing the serialized json, realized that fields should all be in lowerCamelCase |
||
Owner string `json:"owner,omitempty"` | ||
PrimarySubnetConfig FlagsMap `json:"primarySubnetConfig,omitempty"` | ||
PrimaryChainConfigs map[string]FlagsMap `json:"primaryChainConfigs,omitempty"` | ||
DefaultFlags FlagsMap `json:"defaultFlags,omitempty"` | ||
DefaultRuntimeConfig NodeRuntimeConfig `json:"defaultRuntimeConfig,omitempty"` | ||
PreFundedKeys []*secp256k1.PrivateKey `json:"preFundedKeys,omitempty"` | ||
} | ||
|
||
func (n *Network) writeNetworkConfig() error { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The need to be able to set the DataDir suggested accepting a node instead of a FlagsMap here.