mirror of
https://github.com/luxfi/cli.git
synced 2026-10-30 17:01:20 +00:00
The CLI set --partial-sync-primary-network on every validator it brought up, and defaulted the flag to true. luxd no longer has the mode: the primary network's chains are one validator set, and a node that syncs only the P-Chain casts no vote on the rest. The flag, the template line that emitted it, and the remote-config round trip that read it back are gone. Co-authored-by: Hanzo Dev <[email protected]>
180 lines
6.6 KiB
Go
180 lines
6.6 KiB
Go
// Copyright (C) 2022-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package docker
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/luxfi/cli/pkg/remoteconfig"
|
|
"github.com/luxfi/cli/pkg/utils"
|
|
"github.com/luxfi/cli/pkg/ux"
|
|
"github.com/luxfi/constants"
|
|
"github.com/luxfi/sdk/models"
|
|
)
|
|
|
|
// ValidateComposeFile validates a docker-compose file on a remote host.
|
|
func ValidateComposeFile(host *models.Host, composeFile string, timeout time.Duration) error {
|
|
if output, err := host.Command(fmt.Sprintf("docker compose -f %s config", composeFile), nil, timeout); err != nil {
|
|
return fmt.Errorf("%w: %s", err, string(output))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ComposeSSHSetupNode sets up an Luxd node and dependencies on a remote host over SSH.
|
|
func ComposeSSHSetupNode(
|
|
host *models.Host,
|
|
network models.Network,
|
|
luxdVersion string,
|
|
luxdBootstrapIDs []string,
|
|
luxdBootstrapIPs []string,
|
|
luxdGenesisFilePath string,
|
|
luxdUpgradeFilePath string,
|
|
withMonitoring bool,
|
|
publicAccessToHTTPPort bool,
|
|
) error {
|
|
startTime := time.Now()
|
|
folderStructure := remoteconfig.RemoteFoldersToCreateLuxgo()
|
|
for _, dir := range folderStructure {
|
|
if err := host.MkdirAll(dir, constants.SSHFileOpsTimeout); err != nil {
|
|
return fmt.Errorf("failed to create directory %s: %w", dir, err)
|
|
}
|
|
}
|
|
ux.Logger.Info("luxCLI folder structure created on remote host %s after %s ", folderStructure, time.Since(startTime))
|
|
|
|
luxdDockerImage := fmt.Sprintf("%s:%s", constants.LuxdDockerImage, luxdVersion)
|
|
ux.Logger.Info("Preparing Luxd Docker image %s on %s[%s]", luxdDockerImage, host.NodeID, host.IP)
|
|
if err := PrepareDockerImageWithRepo(host, luxdDockerImage, constants.LuxdGitRepo, luxdVersion); err != nil {
|
|
return err
|
|
}
|
|
ux.Logger.Info("Luxd Docker image %s ready on %s[%s] after %s", luxdDockerImage, host.NodeID, host.IP, time.Since(startTime))
|
|
nodeConfFile, cChainConfFile, err := prepareLuxgoConfig(
|
|
host,
|
|
network,
|
|
LuxdConfigOptions{
|
|
BootstrapIDs: luxdBootstrapIDs,
|
|
BootstrapIPs: luxdBootstrapIPs,
|
|
GenesisPath: luxdGenesisFilePath,
|
|
UpgradePath: luxdUpgradeFilePath,
|
|
AllowPublicAccess: publicAccessToHTTPPort,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err := os.Remove(nodeConfFile); err != nil {
|
|
ux.Logger.Error("Error removing temporary file %s: %s", nodeConfFile, err)
|
|
}
|
|
if err := os.Remove(cChainConfFile); err != nil {
|
|
ux.Logger.Error("Error removing temporary file %s: %s", cChainConfFile, err)
|
|
}
|
|
}()
|
|
|
|
if err := host.Upload(nodeConfFile, remoteconfig.GetRemoteLuxNodeConfig(), constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
if err := host.Upload(cChainConfFile, remoteconfig.GetRemoteLuxCChainConfig(), constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
if luxdGenesisFilePath != "" {
|
|
if err := host.Upload(luxdGenesisFilePath, remoteconfig.GetRemoteLuxGenesis(), constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if luxdUpgradeFilePath != "" {
|
|
if err := host.Upload(luxdUpgradeFilePath, remoteconfig.GetRemoteLuxUpgrade(), constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
ux.Logger.Info("Luxd configs uploaded to %s[%s] after %s", host.NodeID, host.IP, time.Since(startTime))
|
|
return ComposeOverSSH("Compose Node",
|
|
host,
|
|
constants.SSHScriptTimeout,
|
|
"templates/luxd.docker-compose.yml",
|
|
ComposeInputs{
|
|
LuxgoVersion: luxdVersion,
|
|
WithMonitoring: withMonitoring,
|
|
WithLuxgo: true,
|
|
E2E: utils.IsE2E(),
|
|
E2EIP: utils.E2EConvertIP(host.IP),
|
|
E2ESuffix: utils.E2ESuffix(host.IP),
|
|
})
|
|
}
|
|
|
|
// ComposeSSHSetupLoadTest sets up load test environment using docker-compose.
|
|
func ComposeSSHSetupLoadTest(host *models.Host) error {
|
|
return ComposeOverSSH("Compose Node",
|
|
host,
|
|
constants.SSHScriptTimeout,
|
|
"templates/luxd.docker-compose.yml",
|
|
ComposeInputs{
|
|
WithMonitoring: true,
|
|
WithLuxgo: false,
|
|
})
|
|
}
|
|
|
|
// WasNodeSetupWithMonitoring checks if an Luxd node was setup with monitoring on a remote host.
|
|
func WasNodeSetupWithMonitoring(host *models.Host) (bool, error) {
|
|
return HasRemoteComposeService(host, utils.GetRemoteComposeFile(), "promtail", constants.SSHScriptTimeout)
|
|
}
|
|
|
|
// ComposeSSHSetupMonitoring sets up monitoring using docker-compose.
|
|
func ComposeSSHSetupMonitoring(host *models.Host) error {
|
|
grafanaConfigFile, grafanaDashboardsFile, grafanaLokiDatasourceFile, grafanaPromDatasourceFile, err := prepareGrafanaConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err := os.Remove(grafanaLokiDatasourceFile); err != nil {
|
|
ux.Logger.Error("Error removing temporary file %s: %s", grafanaLokiDatasourceFile, err)
|
|
}
|
|
if err := os.Remove(grafanaPromDatasourceFile); err != nil {
|
|
ux.Logger.Error("Error removing temporary file %s: %s", grafanaPromDatasourceFile, err)
|
|
}
|
|
if err := os.Remove(grafanaDashboardsFile); err != nil {
|
|
ux.Logger.Error("Error removing temporary file %s: %s", grafanaDashboardsFile, err)
|
|
}
|
|
if err := os.Remove(grafanaConfigFile); err != nil {
|
|
ux.Logger.Error("Error removing temporary file %s: %s", grafanaConfigFile, err)
|
|
}
|
|
}()
|
|
|
|
grafanaLokiDatasourceRemoteFileName := filepath.Join(utils.GetRemoteComposeServicePath("grafana", "provisioning", "datasources"), "loki.yml")
|
|
if err := host.Upload(grafanaLokiDatasourceFile, grafanaLokiDatasourceRemoteFileName, constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
grafanaPromDatasourceFileName := filepath.Join(utils.GetRemoteComposeServicePath("grafana", "provisioning", "datasources"), "prometheus.yml")
|
|
if err := host.Upload(grafanaPromDatasourceFile, grafanaPromDatasourceFileName, constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
grafanaDashboardsRemoteFileName := filepath.Join(utils.GetRemoteComposeServicePath("grafana", "provisioning", "dashboards"), "dashboards.yml")
|
|
if err := host.Upload(grafanaDashboardsFile, grafanaDashboardsRemoteFileName, constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
grafanaConfigRemoteFileName := filepath.Join(utils.GetRemoteComposeServicePath("grafana"), "grafana.ini")
|
|
if err := host.Upload(grafanaConfigFile, grafanaConfigRemoteFileName, constants.SSHFileOpsTimeout); err != nil {
|
|
return err
|
|
}
|
|
|
|
return ComposeOverSSH("Setup Monitoring",
|
|
host,
|
|
constants.SSHScriptTimeout,
|
|
"templates/monitoring.docker-compose.yml",
|
|
ComposeInputs{})
|
|
}
|
|
|
|
// ComposeSSHSetupWarpRelayer sets up the AWM warp relayer using docker-compose.
|
|
func ComposeSSHSetupWarpRelayer(host *models.Host, relayerVersion string) error {
|
|
return ComposeOverSSH("Setup AWM Relayer",
|
|
host,
|
|
constants.SSHScriptTimeout,
|
|
"templates/awmrelayer.docker-compose.yml",
|
|
ComposeInputs{
|
|
WarpRelayerVersion: relayerVersion,
|
|
})
|
|
}
|