diff --git a/tools/kysor/cmd/start.go b/tools/kysor/cmd/start.go index 86be5baa..62d47089 100644 --- a/tools/kysor/cmd/start.go +++ b/tools/kysor/cmd/start.go @@ -41,10 +41,11 @@ import ( ) const ( - // globalCleanupLabel labels all containers and images created by kysor. It can be used to remove all kysor containers and images - globalCleanupLabel = "kysor-all" - protocolPath = "protocol/core" - runtimePath = "runtime" + // globalContainerLabel labels all containers and images created by kysor. + // It can be used to address all containers and images created by kysor. + globalContainerLabel = "kysor-all" + protocolPath = "protocol/core" + runtimePath = "runtime" ) type Runtime struct { @@ -325,7 +326,7 @@ func buildImages( protocolImage = docker.Image{ Path: options.ProtocolBuildDir, Tags: []string{fmt.Sprintf("%s/%s:%s", strings.ToLower(kr.name), protocol.name, "local")}, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, BuildArgs: map[string]*string{"VERSION": &vers}, } } else { @@ -335,7 +336,7 @@ func buildImages( protocolImage = docker.Image{ Path: protocol.path, Tags: []string{fmt.Sprintf("%s/%s:%s", strings.ToLower(kr.name), protocol.name, protocol.ver.String())}, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, BuildArgs: map[string]*string{"VERSION": &vers}, } } @@ -346,7 +347,7 @@ func buildImages( runtimeImage = docker.Image{ Path: options.RuntimeBuildDir, Tags: []string{fmt.Sprintf("%s/%s:%s", strings.ToLower(kr.name), runtime.name, "local")}, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, BuildArgs: map[string]*string{"VERSION": &vers}, } } else { @@ -356,7 +357,7 @@ func buildImages( runtimeImage = docker.Image{ Path: runtime.path, Tags: []string{fmt.Sprintf("%s/%s:%s", strings.ToLower(kr.name), runtime.name, runtime.ver.String())}, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, BuildArgs: map[string]*string{"VERSION": &vers}, } } @@ -403,7 +404,7 @@ func startContainers(cli *client.Client, valConfig config.ValaccountConfig, pool err = docker.CreateNetwork(ctx, cli, docker.NetworkConfig{ Name: label, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, }) if err != nil { return nil, nil, err @@ -423,7 +424,7 @@ func startContainers(cli *client.Client, valConfig config.ValaccountConfig, pool Name: protocolName, Network: label, Env: env, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, ExposedPorts: exposedPorts, } @@ -432,7 +433,7 @@ func startContainers(cli *client.Client, valConfig config.ValaccountConfig, pool Name: runtimeName, Network: label, Env: runtimeEnv, - Labels: map[string]string{globalCleanupLabel: "", label: ""}, + Labels: map[string]string{globalContainerLabel: "", label: ""}, ExtraHosts: []string{"host.docker.internal:host-gateway"}, } diff --git a/tools/kysor/cmd/status.go b/tools/kysor/cmd/status.go new file mode 100644 index 00000000..8d11d5fb --- /dev/null +++ b/tools/kysor/cmd/status.go @@ -0,0 +1,111 @@ +package cmd + +import ( + "context" + "fmt" + querytypes "github.com/KYVENetwork/chain/x/query/types" + commoncmd "github.com/KYVENetwork/kyve-rdk/common/goutils/cmd" + "github.com/KYVENetwork/kyve-rdk/common/goutils/docker" + "github.com/KYVENetwork/kyve-rdk/tools/kysor/cmd/chain" + "github.com/KYVENetwork/kyve-rdk/tools/kysor/cmd/config" + "github.com/KYVENetwork/kyve-rdk/tools/kysor/cmd/utils" + "github.com/docker/docker/client" + "github.com/spf13/cobra" + "strings" +) + +type runStatus struct { + containers []string + valConfig config.ValaccountConfig + pool querytypes.PoolResponse +} + +func getRunStatus(cli *client.Client, kyveClient *chain.KyveClient) (runStatusList []runStatus, err error) { + containers, err := docker.ListContainers(context.Background(), cli, globalContainerLabel) + if err != nil { + return nil, fmt.Errorf("failed to list containers: %v", err) + } + + for _, valConfig := range config.ValaccountConfigOptions { + rs := runStatus{valConfig: valConfig.Value()} + for _, cont := range containers { + label := valConfig.Value().GetContainerLabel() + if _, ok := cont.Labels[label]; ok { + rs.containers = append(rs.containers, strings.TrimPrefix(cont.Names[0], "/")) + } + } + + // Add only if there are running containers + if len(rs.containers) != 0 { + pool, err := kyveClient.QueryPool(rs.valConfig.Pool) + if err != nil { + return nil, err + } + rs.pool = pool.GetPool() + + runStatusList = append(runStatusList, rs) + } + } + + return runStatusList, nil +} + +func getBaseUrl() string { + chainId := config.GetConfigX().ChainID + chainPrefix := chainId[:strings.LastIndex(chainId, "-")] + return fmt.Sprintf("https://app.%s.kyve.network", chainPrefix) +} + +func statusCmd() *cobra.Command { + return &cobra.Command{ + Use: "status", + Short: "Show KYSOR status", + PreRunE: commoncmd.CombineFuncs(utils.CheckDockerInstalled, config.LoadConfigs, commoncmd.SetupInteractiveMode), + RunE: func(cmd *cobra.Command, args []string) error { + kyveClient, err := chain.NewKyveClient(config.GetConfigX(), config.ValaccountConfigs) + if err != nil { + return err + } + + cli, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation()) + if err != nil { + return fmt.Errorf("failed to create docker client: %v", err) + } + //goland:noinspection GoUnhandledErrorResult + defer cli.Close() + + runStatusList, err := getRunStatus(cli, kyveClient) + if err != nil { + return fmt.Errorf("failed to get run status: %v", err) + } + + if len(runStatusList) == 0 { + fmt.Println("No containers are running") + return nil + } + + for _, rs := range runStatusList { + baseUrl := getBaseUrl() + poolUlr := fmt.Sprintf("%s/#/pools/%d", baseUrl, rs.pool.GetData().Id) + fmt.Printf("Valaccount: %s\n", rs.valConfig.Name()) + fmt.Printf(" Pool: %s (ID: %d) -> %s\n", rs.pool.GetData().Name, rs.pool.GetData().Id, poolUlr) + fmt.Print(" Running docker containers:\n") + for _, cont := range rs.containers { + fmt.Printf(" - %s\n", cont) + } + fmt.Printf(" Log commands:\n") + for _, cont := range rs.containers { + fmt.Print(" ") + utils.PrintlnItalic(fmt.Sprintf("docker logs -f %s", cont)) + } + fmt.Println() + } + + return nil + }, + } +} + +func init() { + rootCmd.AddCommand(statusCmd()) +} diff --git a/tools/kysor/cmd/stop.go b/tools/kysor/cmd/stop.go index d30cacfc..de62dceb 100644 --- a/tools/kysor/cmd/stop.go +++ b/tools/kysor/cmd/stop.go @@ -65,7 +65,7 @@ func (o StopOption) StringValue() string { func setStopOptions(cli *client.Client) error { options := make(map[string]commoncmd.Option[StopOption]) - containers, err := docker.ListContainers(context.Background(), cli, globalCleanupLabel) + containers, err := docker.ListContainers(context.Background(), cli, globalContainerLabel) if err != nil { return fmt.Errorf("failed to list containers: %v", err) } @@ -81,7 +81,7 @@ func setStopOptions(cli *client.Client) error { optionsList := maps.Values(options) if len(optionsList) >= 1 { // Add all option to beginning of the list - optionsList = append([]commoncmd.Option[StopOption]{newStopOption("all", globalCleanupLabel)}, optionsList...) + optionsList = append([]commoncmd.Option[StopOption]{newStopOption("all", globalContainerLabel)}, optionsList...) } flagStopValaccount.Options = optionsList return nil