mirror of
https://github.com/luxfi/cli.git
synced 2026-10-30 17:01:20 +00:00
127 lines
3.8 KiB
Go
127 lines
3.8 KiB
Go
// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
package nodecmd
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/luxfi/cli/v2/pkg/node"
|
|
|
|
"github.com/luxfi/cli/v2/cmd/blockchaincmd"
|
|
"github.com/luxfi/cli/v2/pkg/ansible"
|
|
"github.com/luxfi/cli/v2/pkg/cobrautils"
|
|
"github.com/luxfi/cli/v2/pkg/models"
|
|
"github.com/luxfi/cli/v2/pkg/ssh"
|
|
"github.com/luxfi/cli/v2/pkg/utils"
|
|
"github.com/luxfi/cli/v2/pkg/ux"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func newUpdateSubnetCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "subnet [clusterName] [subnetName]",
|
|
Short: "(ALPHA Warning) Update nodes in a cluster with latest subnet configuration and VM for custom VM",
|
|
Long: `(ALPHA Warning) This command is currently in experimental mode.
|
|
|
|
The node update subnet command updates all nodes in a cluster with latest Subnet configuration and VM for custom VM.
|
|
You can check the updated subnet bootstrap status by calling lux node status <clusterName> --subnet <subnetName>`,
|
|
Args: cobrautils.ExactArgs(2),
|
|
RunE: updateSubnet,
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
func updateSubnet(_ *cobra.Command, args []string) error {
|
|
clusterName := args[0]
|
|
subnetName := args[1]
|
|
if err := node.CheckCluster(app, clusterName); err != nil {
|
|
return err
|
|
}
|
|
clusterConfig, err := app.GetClusterConfig(clusterName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if clusterConfig.Local {
|
|
return notImplementedForLocal("update")
|
|
}
|
|
if _, err := blockchaincmd.ValidateSubnetNameAndGetChains([]string{subnetName}); err != nil {
|
|
return err
|
|
}
|
|
hosts, err := ansible.GetInventoryFromAnsibleInventoryFile(app.GetAnsibleInventoryDirPath(clusterName))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer node.DisconnectHosts(hosts)
|
|
if err := node.CheckHostsAreBootstrapped(hosts); err != nil {
|
|
return err
|
|
}
|
|
if err := node.CheckHostsAreHealthy(hosts); err != nil {
|
|
return err
|
|
}
|
|
if err := node.CheckHostsAreRPCCompatible(app, hosts, subnetName); err != nil {
|
|
return err
|
|
}
|
|
nonUpdatedNodes, err := doUpdateSubnet(hosts, clusterName, clusterConfig.Network, subnetName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(nonUpdatedNodes) > 0 {
|
|
return fmt.Errorf("node(s) %s failed to be updated for subnet %s", nonUpdatedNodes, subnetName)
|
|
}
|
|
ux.Logger.PrintToUser("Node(s) successfully updated for Subnet!")
|
|
ux.Logger.PrintToUser(fmt.Sprintf("Check node subnet status with lux node status %s --subnet %s", clusterName, subnetName))
|
|
return nil
|
|
}
|
|
|
|
// doUpdateSubnet exports deployed subnet in user's local machine to cloud server and calls node to
|
|
// restart tracking the specified subnet (similar to lux blockchain join <subnetName> command)
|
|
func doUpdateSubnet(
|
|
hosts []*models.Host,
|
|
clusterName string,
|
|
network models.Network,
|
|
subnetName string,
|
|
) ([]string, error) {
|
|
// load cluster config
|
|
clusterConf, err := app.GetClusterConfig(clusterName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// and get list of subnets
|
|
allSubnets := utils.Unique(append(clusterConf.Subnets, subnetName))
|
|
|
|
wg := sync.WaitGroup{}
|
|
wgResults := models.NodeResults{}
|
|
for _, host := range hosts {
|
|
wg.Add(1)
|
|
go func(nodeResults *models.NodeResults, host *models.Host) {
|
|
defer wg.Done()
|
|
if err := ssh.RunSSHStopNode(host); err != nil {
|
|
nodeResults.AddResult(host.NodeID, nil, err)
|
|
}
|
|
if err := ssh.RunSSHRenderLuxNodeConfig(
|
|
app,
|
|
host,
|
|
network,
|
|
allSubnets,
|
|
clusterConf.IsAPIHost(host.GetCloudID()),
|
|
); err != nil {
|
|
nodeResults.AddResult(host.NodeID, nil, err)
|
|
}
|
|
if err := ssh.RunSSHSyncSubnetData(app, host, network, subnetName); err != nil {
|
|
nodeResults.AddResult(host.NodeID, nil, err)
|
|
}
|
|
if err := ssh.RunSSHStartNode(host); err != nil {
|
|
nodeResults.AddResult(host.NodeID, nil, err)
|
|
return
|
|
}
|
|
}(&wgResults, host)
|
|
}
|
|
wg.Wait()
|
|
if wgResults.HasErrors() {
|
|
return nil, fmt.Errorf("failed to update subnet for node(s) %s", wgResults.GetErrorHostMap())
|
|
}
|
|
return wgResults.GetErrorHosts(), nil
|
|
}
|