From 46e58a28d04dfd3c117b559d07f70fa6d1dc7c1f Mon Sep 17 00:00:00 2001 From: aiordache Date: Wed, 5 Aug 2020 16:32:51 +0200 Subject: [PATCH 1/4] Add ps and logs to compose API Signed-off-by: aiordache --- aci/backend.go | 9 +++++ cli/cmd/compose/compose.go | 2 + cli/cmd/compose/logs.go | 56 +++++++++++++++++++++++++++ cli/cmd/compose/ps.go | 77 ++++++++++++++++++++++++++++++++++++++ compose/api.go | 3 ++ example/backend.go | 9 +++++ 6 files changed, 156 insertions(+) create mode 100644 cli/cmd/compose/logs.go create mode 100644 cli/cmd/compose/ps.go diff --git a/aci/backend.go b/aci/backend.go index 359d5ef64..319bbf9c9 100644 --- a/aci/backend.go +++ b/aci/backend.go @@ -39,6 +39,7 @@ import ( "github.com/docker/api/context/cloud" "github.com/docker/api/context/store" "github.com/docker/api/errdefs" + ecstypes "github.com/docker/ecs-plugin/pkg/compose" ) const ( @@ -366,6 +367,14 @@ func (cs *aciComposeService) Down(ctx context.Context, opts cli.ProjectOptions) return err } +func (cs *aciComposeService) Ps(ctx context.Context, opts cli.ProjectOptions) ([]ecstypes.ServiceStatus, error) { + return nil, errdefs.ErrNotImplemented +} + +func (cs *aciComposeService) Logs(ctx context.Context, opts cli.ProjectOptions) error { + return errdefs.ErrNotImplemented +} + type aciCloudService struct { loginService login.AzureLoginService } diff --git a/cli/cmd/compose/compose.go b/cli/cmd/compose/compose.go index 5c57e5412..f2afad296 100644 --- a/cli/cmd/compose/compose.go +++ b/cli/cmd/compose/compose.go @@ -41,6 +41,8 @@ func Command() *cobra.Command { command.AddCommand( upCommand(), downCommand(), + psCommand(), + logsCommand(), ) return command diff --git a/cli/cmd/compose/logs.go b/cli/cmd/compose/logs.go new file mode 100644 index 000000000..15e0a2600 --- /dev/null +++ b/cli/cmd/compose/logs.go @@ -0,0 +1,56 @@ +/* + Copyright 2020 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package compose + +import ( + "context" + "errors" + + "github.com/compose-spec/compose-go/cli" + "github.com/spf13/cobra" + + "github.com/docker/api/client" +) + +func logsCommand() *cobra.Command { + opts := cli.ProjectOptions{} + logsCmd := &cobra.Command{ + Use: "logs", + RunE: func(cmd *cobra.Command, args []string) error { + return runLogs(cmd.Context(), opts) + }, + } + logsCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name") + logsCmd.Flags().StringVar(&opts.WorkingDir, "workdir", ".", "Work dir") + logsCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files") + + return logsCmd +} + +func runLogs(ctx context.Context, opts cli.ProjectOptions) error { + c, err := client.New(ctx) + if err != nil { + return err + } + + composeService := c.ComposeService() + if composeService == nil { + return errors.New("compose not implemented in current context") + } + + return composeService.Logs(ctx, opts) +} diff --git a/cli/cmd/compose/ps.go b/cli/cmd/compose/ps.go new file mode 100644 index 000000000..ed726b855 --- /dev/null +++ b/cli/cmd/compose/ps.go @@ -0,0 +1,77 @@ +/* + Copyright 2020 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package compose + +import ( + "context" + "errors" + "fmt" + "io" + "os" + "strings" + "text/tabwriter" + + "github.com/compose-spec/compose-go/cli" + "github.com/spf13/cobra" + + "github.com/docker/api/client" +) + +func psCommand() *cobra.Command { + opts := cli.ProjectOptions{} + psCmd := &cobra.Command{ + Use: "ps", + RunE: func(cmd *cobra.Command, args []string) error { + return runPs(cmd.Context(), opts) + }, + } + psCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name") + psCmd.Flags().StringVar(&opts.WorkingDir, "workdir", ".", "Work dir") + psCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files") + + return psCmd +} + +func runPs(ctx context.Context, opts cli.ProjectOptions) error { + c, err := client.New(ctx) + if err != nil { + return err + } + + composeService := c.ComposeService() + if composeService == nil { + return errors.New("compose not implemented in current context") + } + + serviceList, err := composeService.Ps(ctx, opts) + if err != nil { + return err + } + printSection(os.Stdout, len(serviceList), func(w io.Writer) { + for _, service := range serviceList { + fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", service.ID, service.Name, service.Replicas, service.Desired, strings.Join(service.Ports, ", ")) + } + }, "ID", "NAME", "REPLICAS", "PORTS") + return nil +} + +func printSection(out io.Writer, len int, printer func(io.Writer), headers ...string) { + w := tabwriter.NewWriter(out, 20, 1, 3, ' ', 0) + fmt.Fprintln(w, strings.Join(headers, "\t")) + printer(w) + w.Flush() +} diff --git a/compose/api.go b/compose/api.go index b08384ec9..7d2d7244d 100644 --- a/compose/api.go +++ b/compose/api.go @@ -20,6 +20,7 @@ import ( "context" "github.com/compose-spec/compose-go/cli" + types "github.com/docker/ecs-plugin/pkg/compose" ) // Service manages a compose project @@ -28,4 +29,6 @@ type Service interface { Up(ctx context.Context, opts cli.ProjectOptions) error // Down executes the equivalent to a `compose down` Down(ctx context.Context, opts cli.ProjectOptions) error + Logs(ctx context.Context, projectName cli.ProjectOptions) error + Ps(background context.Context, options cli.ProjectOptions) ([]types.ServiceStatus, error) } diff --git a/example/backend.go b/example/backend.go index 0db8f1e3b..997894820 100644 --- a/example/backend.go +++ b/example/backend.go @@ -26,10 +26,12 @@ import ( "github.com/compose-spec/compose-go/cli" "github.com/docker/api/context/cloud" + "github.com/docker/api/errdefs" "github.com/docker/api/backend" "github.com/docker/api/compose" "github.com/docker/api/containers" + ecstypes "github.com/docker/ecs-plugin/pkg/compose" ) type apiService struct { @@ -129,3 +131,10 @@ func (cs *composeService) Down(ctx context.Context, opts cli.ProjectOptions) err fmt.Printf("Down command on project %q", prj.Name) return nil } +func (cs *composeService) Ps(ctx context.Context, opts cli.ProjectOptions) ([]ecstypes.ServiceStatus, error) { + return nil, errdefs.ErrNotImplemented +} + +func (cs *composeService) Logs(ctx context.Context, opts cli.ProjectOptions) error { + return errdefs.ErrNotImplemented +} From 64c517f3756bf91fb94295437a5524b5cf90ed83 Mon Sep 17 00:00:00 2001 From: aiordache Date: Wed, 5 Aug 2020 17:33:04 +0200 Subject: [PATCH 2/4] remove unused parameter Signed-off-by: aiordache --- cli/cmd/compose/ps.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/cmd/compose/ps.go b/cli/cmd/compose/ps.go index ed726b855..55c5a9af8 100644 --- a/cli/cmd/compose/ps.go +++ b/cli/cmd/compose/ps.go @@ -61,7 +61,7 @@ func runPs(ctx context.Context, opts cli.ProjectOptions) error { if err != nil { return err } - printSection(os.Stdout, len(serviceList), func(w io.Writer) { + printSection(os.Stdout, func(w io.Writer) { for _, service := range serviceList { fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", service.ID, service.Name, service.Replicas, service.Desired, strings.Join(service.Ports, ", ")) } @@ -69,7 +69,7 @@ func runPs(ctx context.Context, opts cli.ProjectOptions) error { return nil } -func printSection(out io.Writer, len int, printer func(io.Writer), headers ...string) { +func printSection(out io.Writer, printer func(io.Writer), headers ...string) { w := tabwriter.NewWriter(out, 20, 1, 3, ' ', 0) fmt.Fprintln(w, strings.Join(headers, "\t")) printer(w) From 00f17534a3a8b91adec67228642c2005b129a7c6 Mon Sep 17 00:00:00 2001 From: aiordache Date: Wed, 5 Aug 2020 18:02:19 +0200 Subject: [PATCH 3/4] error check Signed-off-by: aiordache --- cli/cmd/compose/ps.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/cmd/compose/ps.go b/cli/cmd/compose/ps.go index 55c5a9af8..e5930740b 100644 --- a/cli/cmd/compose/ps.go +++ b/cli/cmd/compose/ps.go @@ -61,17 +61,17 @@ func runPs(ctx context.Context, opts cli.ProjectOptions) error { if err != nil { return err } - printSection(os.Stdout, func(w io.Writer) { + err = printSection(os.Stdout, func(w io.Writer) { for _, service := range serviceList { fmt.Fprintf(w, "%s\t%s\t%d/%d\t%s\n", service.ID, service.Name, service.Replicas, service.Desired, strings.Join(service.Ports, ", ")) } }, "ID", "NAME", "REPLICAS", "PORTS") - return nil + return err } -func printSection(out io.Writer, printer func(io.Writer), headers ...string) { +func printSection(out io.Writer, printer func(io.Writer), headers ...string) error { w := tabwriter.NewWriter(out, 20, 1, 3, ' ', 0) fmt.Fprintln(w, strings.Join(headers, "\t")) printer(w) - w.Flush() + return w.Flush() } From e097d19d7c5b1d487c79c47c395d6902c01eaf0c Mon Sep 17 00:00:00 2001 From: aiordache Date: Fri, 7 Aug 2020 10:16:12 +0200 Subject: [PATCH 4/4] update param name and add comments for logs and ps methods Signed-off-by: aiordache --- compose/api.go | 6 ++++-- example/backend.go | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compose/api.go b/compose/api.go index 7d2d7244d..a9592d694 100644 --- a/compose/api.go +++ b/compose/api.go @@ -29,6 +29,8 @@ type Service interface { Up(ctx context.Context, opts cli.ProjectOptions) error // Down executes the equivalent to a `compose down` Down(ctx context.Context, opts cli.ProjectOptions) error - Logs(ctx context.Context, projectName cli.ProjectOptions) error - Ps(background context.Context, options cli.ProjectOptions) ([]types.ServiceStatus, error) + // Logs executes the equivalent to a `compose logs` + Logs(ctx context.Context, opts cli.ProjectOptions) error + // Ps executes the equivalent to a `compose ps` + Ps(ctx context.Context, opts cli.ProjectOptions) ([]types.ServiceStatus, error) } diff --git a/example/backend.go b/example/backend.go index 997894820..5c4d05e48 100644 --- a/example/backend.go +++ b/example/backend.go @@ -131,6 +131,7 @@ func (cs *composeService) Down(ctx context.Context, opts cli.ProjectOptions) err fmt.Printf("Down command on project %q", prj.Name) return nil } + func (cs *composeService) Ps(ctx context.Context, opts cli.ProjectOptions) ([]ecstypes.ServiceStatus, error) { return nil, errdefs.ErrNotImplemented }