-
Notifications
You must be signed in to change notification settings - Fork 55
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
Change subnet/blockchain creation order #1375
base: main
Are you sure you want to change the base?
Changes from all commits
a716235
36a21b6
e8e956c
81a1a62
63efc24
0d74d36
9db6e8b
7e1a61b
314f2e5
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 |
---|---|---|
|
@@ -7,15 +7,13 @@ import ( | |
"path/filepath" | ||
"sync" | ||
|
||
"github.com/ava-labs/avalanche-cli/pkg/ssh" | ||
|
||
"github.com/ava-labs/avalanche-cli/pkg/constants" | ||
|
||
"github.com/ava-labs/avalanche-cli/pkg/ansible" | ||
|
||
"github.com/ava-labs/avalanche-cli/cmd/subnetcmd" | ||
"github.com/ava-labs/avalanche-cli/pkg/ansible" | ||
"github.com/ava-labs/avalanche-cli/pkg/constants" | ||
"github.com/ava-labs/avalanche-cli/pkg/models" | ||
"github.com/ava-labs/avalanche-cli/pkg/ssh" | ||
"github.com/ava-labs/avalanche-cli/pkg/ux" | ||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
|
@@ -71,15 +69,15 @@ func syncSubnet(_ *cobra.Command, args []string) error { | |
if len(notHealthyNodes) > 0 { | ||
return fmt.Errorf("node(s) %s are not healthy, please fix the issue and again", notHealthyNodes) | ||
} | ||
sc, err := app.LoadSidecar(subnetName) | ||
if err != nil { | ||
return err | ||
} | ||
incompatibleNodes, err := checkAvalancheGoVersionCompatible(hosts, subnetName) | ||
if err != nil { | ||
return err | ||
} | ||
if len(incompatibleNodes) > 0 { | ||
sc, err := app.LoadSidecar(subnetName) | ||
if err != nil { | ||
return err | ||
} | ||
ux.Logger.PrintToUser("Either modify your Avalanche Go version or modify your VM version") | ||
ux.Logger.PrintToUser("To modify your Avalanche Go version: https://docs.avax.network/nodes/maintain/upgrade-your-avalanchego-node") | ||
switch sc.VM { | ||
|
@@ -103,7 +101,10 @@ func syncSubnet(_ *cobra.Command, args []string) error { | |
return fmt.Errorf("node(s) %s failed to sync with subnet %s", untrackedNodes, subnetName) | ||
} | ||
ux.Logger.PrintToUser("Node(s) successfully started syncing with Subnet!") | ||
ux.Logger.PrintToUser(fmt.Sprintf("Check node subnet syncing status with avalanche node status %s --subnet %s", clusterName, subnetName)) | ||
blockchainID := sc.Networks[network.Kind.String()].BlockchainID | ||
if blockchainID != ids.Empty { | ||
ux.Logger.PrintToUser(fmt.Sprintf("Check node subnet syncing status with avalanche node status %s --subnet %s", clusterName, subnetName)) | ||
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. fmt.Sprintf is not need as |
||
} | ||
return nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,8 @@ import ( | |
"github.com/ava-labs/avalanche-cli/pkg/constants" | ||
"github.com/ava-labs/avalanche-cli/pkg/models" | ||
"github.com/ava-labs/avalanche-cli/pkg/ssh" | ||
"github.com/ava-labs/avalanche-cli/pkg/subnet" | ||
"github.com/ava-labs/avalanche-cli/pkg/utils" | ||
"github.com/ava-labs/avalanche-cli/pkg/ux" | ||
|
||
"github.com/ava-labs/avalanchego/ids" | ||
|
@@ -153,7 +155,6 @@ func wiz(cmd *cobra.Command, args []string) error { | |
} else { | ||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Adding subnet into existing devnet %s..."), clusterName) | ||
ux.Logger.PrintToUser("") | ||
} | ||
|
||
// check all validators are found | ||
|
@@ -184,6 +185,23 @@ func wiz(cmd *cobra.Command, args []string) error { | |
return err | ||
} | ||
|
||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Adding nodes as subnet validators")) | ||
ux.Logger.PrintToUser("") | ||
if err := validateSubnet(cmd, []string{clusterName, subnetName}); err != nil { | ||
return err | ||
} | ||
if err := waitForSubnetValidators(clusterName, subnetName, validateCheckTimeout, validateCheckPoolTime); err != nil { | ||
return err | ||
} | ||
|
||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Deploying the blockchain")) | ||
ux.Logger.PrintToUser("") | ||
if err := deploySubnet(cmd, []string{clusterName, subnetName}); err != nil { | ||
return err | ||
} | ||
|
||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Setting the nodes as subnet trackers")) | ||
ux.Logger.PrintToUser("") | ||
|
@@ -193,6 +211,7 @@ func wiz(cmd *cobra.Command, args []string) error { | |
if err := waitForHealthyCluster(clusterName, healthCheckTimeout, healthCheckPoolTime); err != nil { | ||
return err | ||
} | ||
|
||
sc, err := app.LoadSidecar(subnetName) | ||
if err != nil { | ||
return err | ||
|
@@ -201,24 +220,17 @@ func wiz(cmd *cobra.Command, args []string) error { | |
if blockchainID == ids.Empty { | ||
return ErrNoBlockchainID | ||
} | ||
if err := waitForClusterSubnetStatus(clusterName, subnetName, blockchainID, status.Syncing, syncCheckTimeout, syncCheckPoolTime); err != nil { | ||
return err | ||
} | ||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Adding nodes as subnet validators")) | ||
ux.Logger.PrintToUser("") | ||
if err := validateSubnet(cmd, []string{clusterName, subnetName}); err != nil { | ||
return err | ||
} | ||
if err := waitForClusterSubnetStatus(clusterName, subnetName, blockchainID, status.Validating, validateCheckTimeout, validateCheckPoolTime); err != nil { | ||
return err | ||
} | ||
|
||
ux.Logger.PrintToUser("") | ||
if clusterAlreadyExists { | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Devnet %s is now validating subnet %s"), clusterName, subnetName) | ||
} else { | ||
ux.Logger.PrintToUser(logging.Green.Wrap("Devnet %s is successfully created and is now validating subnet %s!"), clusterName, subnetName) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -326,21 +338,29 @@ func waitForClusterSubnetStatus( | |
} | ||
|
||
func checkClusterIsADevnet(clusterName string) error { | ||
exists, err := clusterExists(clusterName) | ||
network, err := getClusterNetwork(clusterName) | ||
if err != nil { | ||
return err | ||
} | ||
if network.Kind != models.Devnet { | ||
return fmt.Errorf("cluster %q is not a Devnet", clusterName) | ||
} | ||
return nil | ||
} | ||
|
||
func getClusterNetwork(clusterName string) (models.Network, error) { | ||
exists, err := clusterExists(clusterName) | ||
if err != nil { | ||
return models.UndefinedNetwork, err | ||
} | ||
if !exists { | ||
return fmt.Errorf("cluster %q does not exists", clusterName) | ||
return models.UndefinedNetwork, fmt.Errorf("cluster %q does not exists", clusterName) | ||
} | ||
clustersConfig, err := app.LoadClustersConfig() | ||
if err != nil { | ||
return err | ||
} | ||
if clustersConfig.Clusters[clusterName].Network.Kind != models.Devnet { | ||
return fmt.Errorf("cluster %q is not a Devnet", clusterName) | ||
return models.UndefinedNetwork, err | ||
} | ||
return nil | ||
return clustersConfig.Clusters[clusterName].Network, nil | ||
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. check if clustersConfig.Clusters[clusterName] is not nil before accessing Network |
||
} | ||
|
||
func filterHosts(hosts []*models.Host, nodes []string) ([]*models.Host, error) { | ||
|
@@ -371,3 +391,88 @@ func filterHosts(hosts []*models.Host, nodes []string) ([]*models.Host, error) { | |
} | ||
return filteredHosts, nil | ||
} | ||
|
||
func checkForSubnetValidators( | ||
clusterName string, | ||
subnetName string, | ||
) ([]string, error) { | ||
ux.Logger.PrintToUser("Checking if node(s) are subnet validator(s)") | ||
hosts, err := ansible.GetInventoryFromAnsibleInventoryFile(app.GetAnsibleInventoryDirPath(clusterName)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if len(validators) != 0 { | ||
hosts, err = filterHosts(hosts, validators) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
hostIDs, err := utils.MapWithError(hosts, func(h *models.Host) (string, error) { | ||
_, o, err := models.HostAnsibleIDToCloudID(h.NodeID) | ||
return o, err | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
nodeIDs, err := utils.MapWithError(hostIDs, func(s string) (ids.NodeID, error) { | ||
n, err := getNodeID(app.GetNodeInstanceDirPath(s)) | ||
return n, err | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
network, err := getClusterNetwork(clusterName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
sc, err := app.LoadSidecar(subnetName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
subnetID := sc.Networks[network.Kind.String()].SubnetID | ||
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. check if sc.Networks[network.Kind.String()] is not nil |
||
if subnetID == ids.Empty { | ||
return nil, fmt.Errorf("expected a subnet ID different from primary network") | ||
} | ||
nonValidators := []string{} | ||
for i, nodeID := range nodeIDs { | ||
isValidator, err := subnet.IsSubnetValidator(subnetID, nodeID, network) | ||
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. suggestion: can be done in parallel to increase performance |
||
if err != nil { | ||
return nil, err | ||
} | ||
if !isValidator { | ||
nonValidators = append(nonValidators, hostIDs[i]) | ||
} | ||
} | ||
return nonValidators, nil | ||
} | ||
|
||
func waitForSubnetValidators( | ||
clusterName string, | ||
subnetName string, | ||
timeout time.Duration, | ||
poolTime time.Duration, | ||
) error { | ||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser("Waiting for node(s) in cluster %s to become subnet validator(s) of %s...", clusterName, subnetName) | ||
startTime := time.Now() | ||
for { | ||
nonValidators, err := checkForSubnetValidators(clusterName, subnetName) | ||
if err != nil { | ||
return err | ||
} | ||
if len(nonValidators) == 0 { | ||
ux.Logger.PrintToUser("All nodes are subnet validators after %d seconds", uint32(time.Since(startTime).Seconds())) | ||
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. can it be |
||
return nil | ||
} | ||
if time.Since(startTime) > timeout { | ||
ux.Logger.PrintToUser("") | ||
ux.Logger.PrintToUser("Non validator Nodes") | ||
for _, nonValidator := range nonValidators { | ||
ux.Logger.PrintToUser(" " + nonValidator) | ||
} | ||
ux.Logger.PrintToUser("") | ||
return fmt.Errorf("failed to verify all nodes are subnet validators after %d seconds", uint32(timeout.Seconds())) | ||
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. can it be replaced with |
||
} | ||
time.Sleep(poolTime) | ||
} | ||
} |
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.
we need to check if
sc.Networks[network.Kind.String()]
is not nil before trying to accessBlockchainID
as it can crash