From 5e7969750589783e6607bce2ce395714736a17c6 Mon Sep 17 00:00:00 2001 From: Pavel Sviderski Date: Wed, 13 Nov 2024 19:52:46 +1000 Subject: [PATCH] move RunService from CLI to the client, print output in the command --- cmd/uncloud/machine/list.go | 4 +-- cmd/uncloud/service/run.go | 24 ++++++++++++-- internal/cli/{ => client}/service.go | 47 +++++++++++++++------------- 3 files changed, 48 insertions(+), 27 deletions(-) rename internal/cli/{ => client}/service.go (52%) diff --git a/cmd/uncloud/machine/list.go b/cmd/uncloud/machine/list.go index 3cb7ea91..44722673 100644 --- a/cmd/uncloud/machine/list.go +++ b/cmd/uncloud/machine/list.go @@ -37,9 +37,7 @@ func runList(ctx context.Context, uncli *cli.CLI, clusterName string) error { if err != nil { return fmt.Errorf("connect to cluster: %w", err) } - defer func() { - _ = c.Close() - }() + defer c.Close() listResp, err := c.ListMachines(ctx, &emptypb.Empty{}) if err != nil { diff --git a/cmd/uncloud/service/run.go b/cmd/uncloud/service/run.go index 17176494..0f16fe10 100644 --- a/cmd/uncloud/service/run.go +++ b/cmd/uncloud/service/run.go @@ -1,14 +1,17 @@ package service import ( + "context" + "fmt" "github.com/spf13/cobra" "uncloud/internal/cli" + "uncloud/internal/cli/client" ) func NewRunCommand() *cobra.Command { var ( cluster string - opts cli.ServiceOptions + opts client.ServiceOptions ) cmd := &cobra.Command{ @@ -17,9 +20,8 @@ func NewRunCommand() *cobra.Command { Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { uncli := cmd.Context().Value("cli").(*cli.CLI) - opts.Image = args[0] - return uncli.RunService(cmd.Context(), cluster, &opts) + return runRun(cmd.Context(), uncli, cluster, &opts) }, } @@ -39,3 +41,19 @@ func NewRunCommand() *cobra.Command { return cmd } + +func runRun(ctx context.Context, uncli *cli.CLI, clusterName string, opts *client.ServiceOptions) error { + c, err := uncli.ConnectCluster(ctx, clusterName) + if err != nil { + return fmt.Errorf("connect to cluster: %w", err) + } + defer c.Close() + + resp, err := c.RunService(ctx, opts) + if err != nil { + return fmt.Errorf("run service: %w", err) + } + + fmt.Printf("Service %q started on machine %q.\n", resp.Name, resp.MachineName) + return nil +} diff --git a/internal/cli/service.go b/internal/cli/client/service.go similarity index 52% rename from internal/cli/service.go rename to internal/cli/client/service.go index 4dfb6b00..d3304b51 100644 --- a/internal/cli/service.go +++ b/internal/cli/client/service.go @@ -1,4 +1,4 @@ -package cli +package client import ( "context" @@ -16,26 +16,28 @@ type ServiceOptions struct { Publish []string } -func (cli *CLI) RunService(ctx context.Context, clusterName string, opts *ServiceOptions) error { - c, err := cli.ConnectCluster(ctx, clusterName) - if err != nil { - return fmt.Errorf("connect to cluster: %w", err) - } - defer func() { - _ = c.Close() - }() +type RunServiceResponse struct { + ID string + Name string + MachineName string +} + +func (c *Client) RunService(ctx context.Context, opts *ServiceOptions) (RunServiceResponse, error) { + var resp RunServiceResponse listResp, err := c.ListMachines(ctx, &emptypb.Empty{}) if err != nil { - return fmt.Errorf("list machines: %w", err) + return resp, fmt.Errorf("list machines: %w", err) } - // TODO: update ListMachine endpoint to return machine status based on the Corrosion member list. + // TODO: find the first available machine (state UP). machineIP, _ := listResp.Machines[0].Machine.Network.ManagementIp.ToAddr() + resp.MachineName = listResp.Machines[0].Machine.Name if opts.Machine != "" { for _, m := range listResp.Machines { if m.Machine.Name == opts.Machine || m.Machine.Id == opts.Machine { machineIP, _ = m.Machine.Network.ManagementIp.ToAddr() + resp.MachineName = m.Machine.Name break } } @@ -44,20 +46,23 @@ func (cli *CLI) RunService(ctx context.Context, clusterName string, opts *Servic md := metadata.Pairs("machines", machineIP.String()) ctx = metadata.NewOutgoingContext(ctx, md) + // TODO: generate a random service ID. + resp.ID = "todo-service-id" + // TODO: generate a random service name if not specified. + resp.Name = opts.Name + // TODO: generate a container name from the service name. + // TODO: set service labels on the container. + config := &container.Config{ Image: opts.Image, } - // TODO: generate a container name from the service name. - // TODO: set service labels on the container. - resp, err := c.CreateContainer(ctx, config, nil, nil, nil, opts.Name) + createResp, err := c.CreateContainer(ctx, config, nil, nil, nil, opts.Name) if err != nil { - return fmt.Errorf("create container: %w", err) + return resp, fmt.Errorf("create container: %w", err) + } + if err = c.StartContainer(ctx, createResp.ID, container.StartOptions{}); err != nil { + return resp, fmt.Errorf("start container: %w", err) } - if err = c.StartContainer(ctx, resp.ID, container.StartOptions{}); err != nil { - return fmt.Errorf("start container: %w", err) - } - - fmt.Printf("Service %q started with container ID %q\n", opts.Name, resp.ID) - return nil + return resp, nil }