Skip to content

Commit 2c76e3f

Browse files
Refactor node setup out of node create (#2522)
* refactor node setup * fix lint * address comments * fix lint * address comments * address comments * address comment * fix merge --------- Signed-off-by: sukantoraymond <[email protected]>
1 parent d32dda3 commit 2c76e3f

File tree

14 files changed

+373
-120
lines changed

14 files changed

+373
-120
lines changed

cmd/nodecmd/create.go

+72-76
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/ava-labs/avalanche-cli/pkg/utils"
3232
"github.com/ava-labs/avalanche-cli/pkg/ux"
3333
"github.com/ava-labs/avalanche-cli/pkg/vm"
34+
sdkUtils "github.com/ava-labs/avalanche-cli/sdk/utils"
3435
"github.com/ava-labs/avalanchego/ids"
3536
"github.com/ava-labs/avalanchego/staking"
3637
"github.com/ava-labs/avalanchego/utils/logging"
@@ -661,7 +662,6 @@ func createNodes(cmd *cobra.Command, args []string) error {
661662
}
662663
return fmt.Errorf("failed to provision node(s) %s", failedHosts.GetNodeList())
663664
}
664-
ux.Logger.PrintToUser("Starting bootstrap process on the newly created Avalanche node(s)...")
665665
wg := sync.WaitGroup{}
666666
wgResults := models.NodeResults{}
667667
spinSession := ux.NewUserSpinner()
@@ -672,6 +672,7 @@ func createNodes(cmd *cobra.Command, args []string) error {
672672
}
673673
startTime := time.Now()
674674
if addMonitoring {
675+
spinSession := ux.NewUserSpinner()
675676
if len(monitoringHosts) != 1 {
676677
return fmt.Errorf("expected only one monitoring host, found %d", len(monitoringHosts))
677678
}
@@ -682,116 +683,91 @@ func createNodes(cmd *cobra.Command, args []string) error {
682683
go func(nodeResults *models.NodeResults, monitoringHost *models.Host) {
683684
defer wg.Done()
684685
if err := monitoringHost.Connect(0); err != nil {
685-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
686+
nodeResults.AddResult(monitoringHost.IP, nil, err)
686687
return
687688
}
688-
spinner := spinSession.SpinToUser(utils.ScriptLog(monitoringHost.NodeID, "Setup Monitoring"))
689+
spinner := spinSession.SpinToUser(utils.ScriptLog(monitoringHost.IP, "Setup Monitoring"))
689690
if err = app.SetupMonitoringEnv(); err != nil {
690-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
691+
nodeResults.AddResult(monitoringHost.IP, nil, err)
691692
ux.SpinFailWithError(spinner, "", err)
692693
return
693694
}
694695
if err = ssh.RunSSHSetupDockerService(monitoringHost); err != nil {
695-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
696+
nodeResults.AddResult(monitoringHost.IP, nil, err)
696697
ux.SpinFailWithError(spinner, "", err)
697698
return
698699
}
699700
ux.Logger.Info("SetupMonitoringEnv RunSSHSetupDockerService completed")
700701
if err = ssh.RunSSHSetupMonitoringFolders(monitoringHost); err != nil {
701-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
702+
nodeResults.AddResult(monitoringHost.IP, nil, err)
702703
ux.SpinFailWithError(spinner, "", err)
703704
return
704705
}
705706
ux.Logger.Info("RunSSHSetupMonitoringFolders completed")
706707
if err := ssh.RunSSHCopyMonitoringDashboards(monitoringHost, app.GetMonitoringDashboardDir()+"/"); err != nil {
707-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
708+
nodeResults.AddResult(monitoringHost.IP, nil, err)
708709
ux.SpinFailWithError(spinner, "", err)
709710
return
710711
}
711712
ux.Logger.Info("RunSSHCopyMonitoringDashboards completed")
712713
if err := ssh.RunSSHSetupPrometheusConfig(monitoringHost, avalancheGoPorts, machinePorts, ltPorts); err != nil {
713-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
714+
nodeResults.AddResult(monitoringHost.IP, nil, err)
714715
ux.SpinFailWithError(spinner, "", err)
715716
return
716717
}
717718
ux.Logger.Info("RunSSHSetupPrometheusConfig completed")
718719
if err := ssh.RunSSHSetupLokiConfig(monitoringHost, constants.AvalancheGoLokiPort); err != nil {
719-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
720+
nodeResults.AddResult(monitoringHost.IP, nil, err)
720721
ux.SpinFailWithError(spinner, "", err)
721722
return
722723
}
723724
ux.Logger.Info("RunSSHSetupLokiConfig completed")
724725
if err := docker.ComposeSSHSetupMonitoring(monitoringHost); err != nil {
725-
nodeResults.AddResult(monitoringHost.NodeID, nil, err)
726+
nodeResults.AddResult(monitoringHost.IP, nil, err)
726727
ux.SpinFailWithError(spinner, "", err)
727728
return
728729
}
729730
ux.Logger.Info("ComposeSSHSetupMonitoring completed")
730731
ux.SpinComplete(spinner)
731732
}(&wgResults, monitoringHost)
732733
}
734+
wg.Wait()
735+
spinSession.Stop()
733736
}
734737
for _, host := range hosts {
735-
wg.Add(1)
736-
go func(nodeResults *models.NodeResults, host *models.Host) {
737-
defer wg.Done()
738-
if err := host.Connect(0); err != nil {
739-
nodeResults.AddResult(host.NodeID, nil, err)
740-
return
741-
}
742-
if err := provideStakingCertAndKey(host); err != nil {
743-
nodeResults.AddResult(host.NodeID, nil, err)
744-
return
745-
}
746-
spinner := spinSession.SpinToUser(utils.ScriptLog(host.NodeID, "Setup Node"))
747-
if err := ssh.RunSSHSetupNode(host, app.Conf.GetConfigPath()); err != nil {
748-
nodeResults.AddResult(host.NodeID, nil, err)
749-
ux.SpinFailWithError(spinner, "", err)
750-
return
751-
}
752-
if err := ssh.RunSSHSetupDockerService(host); err != nil {
753-
nodeResults.AddResult(host.NodeID, nil, err)
754-
ux.SpinFailWithError(spinner, "", err)
755-
return
756-
}
757-
ux.SpinComplete(spinner)
758-
if addMonitoring {
759-
cloudID := host.GetCloudID()
760-
nodeID, err := getNodeID(app.GetNodeInstanceDirPath(cloudID))
761-
if err != nil {
762-
nodeResults.AddResult(host.NodeID, nil, err)
763-
ux.SpinFailWithError(spinner, "", err)
764-
return
765-
}
766-
if err = ssh.RunSSHSetupPromtailConfig(host, monitoringNodeConfig.PublicIPs[0], constants.AvalancheGoLokiPort, cloudID, nodeID.String(), ""); err != nil {
767-
nodeResults.AddResult(host.NodeID, nil, err)
768-
ux.SpinFailWithError(spinner, "", err)
769-
return
738+
publicAccessToHTTPPort := slices.Contains(cloudConfigMap.GetAllAPIInstanceIDs(), host.GetCloudID()) || publicHTTPPortAccess
739+
host.APINode = publicAccessToHTTPPort
740+
}
741+
if err = setup(hosts, avalancheGoVersion, network); err != nil {
742+
return err
743+
}
744+
if addMonitoring {
745+
spinSession := ux.NewUserSpinner()
746+
for _, host := range hosts {
747+
wg.Add(1)
748+
go func(nodeResults *models.NodeResults, host *models.Host) {
749+
defer wg.Done()
750+
spinner := spinSession.SpinToUser(utils.ScriptLog(host.IP, "Add Monitoring"))
751+
if addMonitoring {
752+
cloudID := host.GetCloudID()
753+
nodeID, err := getNodeID(app.GetNodeInstanceDirPath(cloudID))
754+
if err != nil {
755+
nodeResults.AddResult(host.IP, nil, err)
756+
ux.SpinFailWithError(spinner, "", err)
757+
return
758+
}
759+
if err = ssh.RunSSHSetupPromtailConfig(host, monitoringNodeConfig.PublicIPs[0], constants.AvalancheGoLokiPort, cloudID, nodeID.String(), ""); err != nil {
760+
nodeResults.AddResult(host.IP, nil, err)
761+
ux.SpinFailWithError(spinner, "", err)
762+
return
763+
}
764+
ux.SpinComplete(spinner)
770765
}
771-
ux.SpinComplete(spinner)
772-
}
773-
spinner = spinSession.SpinToUser(utils.ScriptLog(host.NodeID, "Setup AvalancheGo"))
774-
// check if host is a API host
775-
publicAccessToHTTPPort := slices.Contains(cloudConfigMap.GetAllAPIInstanceIDs(), host.GetCloudID()) || publicHTTPPortAccess
776-
if err := docker.ComposeSSHSetupNode(host,
777-
network,
778-
avalancheGoVersion,
779-
bootstrapIDs,
780-
bootstrapIPs,
781-
partialSync,
782-
genesisPath,
783-
upgradePath,
784-
addMonitoring,
785-
publicAccessToHTTPPort,
786-
); err != nil {
787-
nodeResults.AddResult(host.NodeID, nil, err)
788-
ux.SpinFailWithError(spinner, "", err)
789-
return
790-
}
791-
ux.SpinComplete(spinner)
792-
}(&wgResults, host)
766+
}(&wgResults, host)
767+
}
768+
wg.Wait()
769+
spinSession.Stop()
793770
}
794-
wg.Wait()
795771
ux.Logger.Info("Create and setup nodes time took: %s", time.Since(startTime))
796772
spinSession.Stop()
797773
if network.Kind == models.Devnet {
@@ -800,8 +776,8 @@ func createNodes(cmd *cobra.Command, args []string) error {
800776
}
801777
}
802778
for _, node := range hosts {
803-
if wgResults.HasNodeIDWithError(node.NodeID) {
804-
ux.Logger.RedXToUser("Node %s is ERROR with error: %s", node.NodeID, wgResults.GetErrorHostMap()[node.NodeID])
779+
if wgResults.HasIDWithError(node.IP) {
780+
ux.Logger.RedXToUser("Node %s is ERROR with error: %s", node.IP, wgResults.GetErrorHostMap()[node.IP])
805781
}
806782
}
807783

@@ -1033,18 +1009,38 @@ func generateNodeCertAndKeys(stakerCertFilePath, stakerKeyFilePath, blsKeyFilePa
10331009
}
10341010

10351011
func provideStakingCertAndKey(host *models.Host) error {
1036-
instanceID := host.GetCloudID()
1037-
keyPath := filepath.Join(app.GetNodesDir(), instanceID)
1012+
keyPath := app.GetNodeStakingDir(host.IP)
1013+
if sdkUtils.DirExists(keyPath) && !overrideExisting {
1014+
yes, err := app.Prompt.CaptureNoYes(fmt.Sprintf("Directory %s alreday exists. Do you want to override it?", keyPath))
1015+
if err != nil {
1016+
return err
1017+
}
1018+
if !yes {
1019+
return nil
1020+
}
1021+
}
10381022
nodeID, err := generateNodeCertAndKeys(
10391023
filepath.Join(keyPath, constants.StakerCertFileName),
10401024
filepath.Join(keyPath, constants.StakerKeyFileName),
10411025
filepath.Join(keyPath, constants.BLSKeyFileName),
10421026
)
10431027
if err != nil {
1044-
ux.Logger.PrintToUser("Failed to generate staking keys for host %s", instanceID)
1028+
ux.Logger.PrintToUser("Failed to generate staking keys for host %s", host.IP)
10451029
return err
10461030
} else {
1047-
ux.Logger.GreenCheckmarkToUser("Generated staking keys for host %s[%s] ", instanceID, nodeID.String())
1031+
ux.Logger.GreenCheckmarkToUser("Generated staking keys for host %s[%s] ", host.IP, nodeID.String())
1032+
}
1033+
instanceID := host.GetCloudID()
1034+
if instanceID != "" {
1035+
if err := utils.FileCopy(filepath.Join(keyPath, constants.StakerCertFileName), filepath.Join(app.GetNodesDir(), instanceID, constants.StakerCertFileName)); err != nil {
1036+
return err
1037+
}
1038+
if err := utils.FileCopy(filepath.Join(keyPath, constants.StakerKeyFileName), filepath.Join(app.GetNodesDir(), instanceID, constants.StakerKeyFileName)); err != nil {
1039+
return err
1040+
}
1041+
if err := utils.FileCopy(filepath.Join(keyPath, constants.BLSKeyFileName), filepath.Join(app.GetNodesDir(), instanceID, constants.BLSKeyFileName)); err != nil {
1042+
return err
1043+
}
10481044
}
10491045
return ssh.RunSSHUploadStakingFiles(host, keyPath)
10501046
}
@@ -1214,9 +1210,9 @@ func waitForHosts(hosts []*models.Host) *models.NodeResults {
12141210
createdWaitGroup.Add(1)
12151211
go func(nodeResults *models.NodeResults, host *models.Host) {
12161212
defer createdWaitGroup.Done()
1217-
spinner := spinSession.SpinToUser(utils.ScriptLog(host.NodeID, "Waiting for instance response"))
1213+
spinner := spinSession.SpinToUser(utils.ScriptLog(host.IP, "Waiting for instance response"))
12181214
if err := host.WaitForSSHShell(constants.SSHServerStartTimeout); err != nil {
1219-
nodeResults.AddResult(host.NodeID, nil, err)
1215+
nodeResults.AddResult(host.IP, nil, err)
12201216
ux.SpinFailWithError(spinner, "", err)
12211217
return
12221218
}

cmd/nodecmd/create_devnet.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func setupDevnet(clusterName string, hosts []*models.Host, apiNodeIPMap map[stri
273273
wg.Wait()
274274
ux.Logger.PrintLineSeparator()
275275
for _, node := range hosts {
276-
if wgResults.HasNodeIDWithError(node.NodeID) {
276+
if wgResults.HasIDWithError(node.NodeID) {
277277
ux.Logger.RedXToUser("Node %s is ERROR with error: %s", node.NodeID, wgResults.GetErrorHostMap()[node.NodeID])
278278
} else {
279279
nodeID, err := getNodeID(app.GetNodeInstanceDirPath(node.GetCloudID()))

cmd/nodecmd/local.go

+36-34
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,30 @@ import (
4141
var (
4242
avalanchegoBinaryPath string
4343

44-
bootstrapIDs []string
45-
bootstrapIPs []string
46-
genesisPath string
47-
upgradePath string
48-
stakingTLSKeyPath string
49-
stakingCertKeyPath string
50-
stakingSignerKeyPath string
51-
numNodes uint32
52-
nodeConfigPath string
53-
partialSync bool
54-
stakeAmount uint64
55-
rpcURL string
56-
balanceAVAX float64
57-
remainingBalanceOwnerAddr string
58-
disableOwnerAddr string
59-
aggregatorLogLevel string
60-
aggregatorLogToStdout bool
61-
delegationFee uint16
62-
publicKey string
63-
pop string
64-
minimumStakeDuration uint64
65-
validatorManagerAddress string
44+
bootstrapIDs []string
45+
bootstrapIPs []string
46+
genesisPath string
47+
upgradePath string
48+
stakingTLSKeyPath string
49+
stakingCertKeyPath string
50+
stakingSignerKeyPath string
51+
numNodes uint32
52+
nodeConfigPath string
53+
partialSync bool
54+
stakeAmount uint64
55+
rpcURL string
56+
balanceAVAX float64
57+
remainingBalanceOwnerAddr string
58+
disableOwnerAddr string
59+
aggregatorLogLevel string
60+
aggregatorLogToStdout bool
61+
delegationFee uint16
62+
publicKey string
63+
pop string
64+
minimumStakeDuration uint64
65+
latestAvagoReleaseVersion bool
66+
latestAvagoPreReleaseVersion bool
67+
validatorManagerAddress string
6668
)
6769

6870
// const snapshotName = "local_snapshot"
@@ -104,8 +106,8 @@ You can check the bootstrapping status by running avalanche node status local.
104106
PersistentPostRun: handlePostRun,
105107
}
106108
networkoptions.AddNetworkFlagsToCmd(cmd, &globalNetworkFlags, false, networkoptions.DefaultSupportedNetworkOptions)
107-
cmd.Flags().BoolVar(&useLatestAvalanchegoReleaseVersion, "latest-avalanchego-version", false, "install latest avalanchego release version on node/s")
108-
cmd.Flags().BoolVar(&useLatestAvalanchegoPreReleaseVersion, "latest-avalanchego-pre-release-version", true, "install latest avalanchego pre-release version on node/s")
109+
cmd.Flags().BoolVar(&latestAvagoReleaseVersion, "latest-avalanchego-version", true, "install latest avalanchego release version on node/s")
110+
cmd.Flags().BoolVar(&latestAvagoPreReleaseVersion, "latest-avalanchego-pre-release-version", false, "install latest avalanchego pre-release version on node/s")
109111
cmd.Flags().StringVar(&useCustomAvalanchegoVersion, "custom-avalanchego-version", "", "install given avalanchego version on node/s")
110112
cmd.Flags().StringVar(&avalanchegoBinaryPath, "avalanchego-path", "", "use this avalanchego binary path")
111113
cmd.Flags().StringArrayVar(&bootstrapIDs, "bootstrap-id", []string{}, "nodeIDs of bootstrap nodes")
@@ -140,8 +142,8 @@ func newLocalTrackCmd() *cobra.Command {
140142
RunE: localTrack,
141143
}
142144
cmd.Flags().StringVar(&avalanchegoBinaryPath, "avalanchego-path", "", "use this avalanchego binary path")
143-
cmd.Flags().BoolVar(&useLatestAvalanchegoReleaseVersion, "latest-avalanchego-version", false, "install latest avalanchego release version on node/s")
144-
cmd.Flags().BoolVar(&useLatestAvalanchegoPreReleaseVersion, "latest-avalanchego-pre-release-version", true, "install latest avalanchego pre-release version on node/s")
145+
cmd.Flags().BoolVar(&latestAvagoReleaseVersion, "latest-avalanchego-version", true, "install latest avalanchego release version on node/s")
146+
cmd.Flags().BoolVar(&latestAvagoPreReleaseVersion, "latest-avalanchego-pre-release-version", false, "install latest avalanchego pre-release version on node/s")
145147
cmd.Flags().StringVar(&useCustomAvalanchegoVersion, "custom-avalanchego-version", "", "install given avalanchego version on node/s")
146148
return cmd
147149
}
@@ -183,13 +185,13 @@ func localStartNode(_ *cobra.Command, args []string) error {
183185
StakingTLSKeyPath: stakingTLSKeyPath,
184186
}
185187
if useCustomAvalanchegoVersion != "" {
186-
useLatestAvalanchegoReleaseVersion = false
187-
useLatestAvalanchegoPreReleaseVersion = false
188+
latestAvagoPreReleaseVersion = false
189+
latestAvagoReleaseVersion = false
188190
}
189191
avaGoVersionSetting := node.AvalancheGoVersionSettings{
190192
UseCustomAvalanchegoVersion: useCustomAvalanchegoVersion,
191-
UseLatestAvalanchegoPreReleaseVersion: useLatestAvalanchegoPreReleaseVersion,
192-
UseLatestAvalanchegoReleaseVersion: useLatestAvalanchegoReleaseVersion,
193+
UseLatestAvalanchegoPreReleaseVersion: latestAvagoPreReleaseVersion,
194+
UseLatestAvalanchegoReleaseVersion: latestAvagoReleaseVersion,
193195
}
194196
nodeConfig := make(map[string]interface{})
195197
if nodeConfigPath != "" {
@@ -228,13 +230,13 @@ func localDestroyNode(_ *cobra.Command, args []string) error {
228230
func localTrack(_ *cobra.Command, args []string) error {
229231
if avalanchegoBinaryPath == "" {
230232
if useCustomAvalanchegoVersion != "" {
231-
useLatestAvalanchegoReleaseVersion = false
232-
useLatestAvalanchegoPreReleaseVersion = false
233+
latestAvagoReleaseVersion = false
234+
latestAvagoPreReleaseVersion = false
233235
}
234236
avaGoVersionSetting := node.AvalancheGoVersionSettings{
235237
UseCustomAvalanchegoVersion: useCustomAvalanchegoVersion,
236-
UseLatestAvalanchegoPreReleaseVersion: useLatestAvalanchegoPreReleaseVersion,
237-
UseLatestAvalanchegoReleaseVersion: useLatestAvalanchegoReleaseVersion,
238+
UseLatestAvalanchegoPreReleaseVersion: latestAvagoPreReleaseVersion,
239+
UseLatestAvalanchegoReleaseVersion: latestAvagoReleaseVersion,
238240
}
239241
avalancheGoVersion, err := node.GetAvalancheGoVersion(app, avaGoVersionSetting)
240242
if err != nil {

cmd/nodecmd/node.go

+2
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,7 @@ rest of the commands to maintain your node and make your node a Subnet Validator
6060
cmd.AddCommand(newImportCmd())
6161
// node local
6262
cmd.AddCommand(newLocalCmd())
63+
// node setup
64+
cmd.AddCommand(newSetupCmd())
6365
return cmd
6466
}

0 commit comments

Comments
 (0)