diff --git a/azure/backend.go b/azure/backend.go index 0e7bb6626..5373716f4 100644 --- a/azure/backend.go +++ b/azure/backend.go @@ -21,11 +21,6 @@ import ( "github.com/docker/api/context/store" ) -type aciApiService struct { - containerGroupsClient containerinstance.ContainerGroupsClient - ctx store.AciContext -} - func init() { backend.Register("aci", "aci", func(ctx context.Context) (interface{}, error) { return New(ctx) @@ -36,13 +31,8 @@ func getter() interface{} { return &store.AciContext{} } -type AciService interface { - containers.ContainerService - compose.Service -} - -// New creates a backend that can manage containers on ACI -func New(ctx context.Context) (AciService, error) { +// New creates a backend that can manage containers +func New(ctx context.Context) (backend.Service, error) { currentContext := apicontext.CurrentContext(ctx) contextStore, err := store.New() if err != nil { @@ -58,13 +48,47 @@ func New(ctx context.Context) (AciService, error) { containerGroupsClient := containerinstance.NewContainerGroupsClient(aciContext.SubscriptionID) containerGroupsClient.Authorizer = auth - return &aciApiService{ - containerGroupsClient: containerGroupsClient, - ctx: aciContext, - }, nil + return getAciApiService(containerGroupsClient, aciContext), nil } -func (cs *aciApiService) List(ctx context.Context) ([]containers.Container, error) { +func getAciApiService(cgc containerinstance.ContainerGroupsClient, aciCtx store.AciContext) *aciApiService { + return &aciApiService{ + container: aciContainerService{ + containerGroupsClient: cgc, + ctx: aciCtx, + }, + compose: aciComposeService{ + containerGroupsClient: cgc, + ctx: aciCtx, + }, + } +} + +type aciApiService struct { + container aciContainerService + compose aciComposeService +} + +func (a *aciApiService) ContainerService() containers.Service { + return &aciContainerService{ + containerGroupsClient: a.container.containerGroupsClient, + ctx: a.container.ctx, + } +} + +func (a *aciApiService) ComposeService() compose.Service { + return &aciComposeService{ + containerGroupsClient: a.compose.containerGroupsClient, + ctx: a.compose.ctx, + } +} + +type aciContainerService struct { + containerGroupsClient containerinstance.ContainerGroupsClient + ctx store.AciContext +} + +func (cs *aciContainerService) List(ctx context.Context) ([]containers.Container, error) { var containerGroups []containerinstance.ContainerGroup result, err := cs.containerGroupsClient.ListByResourceGroup(ctx, cs.ctx.ResourceGroup) if err != nil { @@ -101,7 +125,7 @@ func (cs *aciApiService) List(ctx context.Context) ([]containers.Container, erro return res, nil } -func (cs *aciApiService) Run(ctx context.Context, r containers.ContainerConfig) error { +func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerConfig) error { var ports []types.ServicePortConfig for _, p := range r.Ports { ports = append(ports, types.ServicePortConfig{ @@ -132,7 +156,7 @@ func (cs *aciApiService) Run(ctx context.Context, r containers.ContainerConfig) return err } -func (cs *aciApiService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error { +func (cs *aciContainerService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error { containerExecResponse, err := execACIContainer(ctx, cs.ctx, command, name, name) if err != nil { return err @@ -147,7 +171,7 @@ func (cs *aciApiService) Exec(ctx context.Context, name string, command string, ) } -func (cs *aciApiService) Logs(ctx context.Context, containerName string, req containers.LogsRequest) error { +func (cs *aciContainerService) Logs(ctx context.Context, containerName string, req containers.LogsRequest) error { logs, err := getACIContainerLogs(ctx, cs.ctx, containerName, containerName) if err != nil { return err @@ -169,7 +193,12 @@ func (cs *aciApiService) Logs(ctx context.Context, containerName string, req con return err } -func (cs *aciApiService) Up(ctx context.Context, opts compose.ProjectOptions) error { +type aciComposeService struct { + containerGroupsClient containerinstance.ContainerGroupsClient + ctx store.AciContext +} + +func (cs *aciComposeService) Up(ctx context.Context, opts compose.ProjectOptions) error { project, err := compose.ProjectFromOptions(&opts) if err != nil { return err @@ -183,7 +212,7 @@ func (cs *aciApiService) Up(ctx context.Context, opts compose.ProjectOptions) er return err } -func (cs *aciApiService) Down(ctx context.Context, opts compose.ProjectOptions) error { +func (cs *aciComposeService) Down(ctx context.Context, opts compose.ProjectOptions) error { project, err := compose.ProjectFromOptions(&opts) if err != nil { return err diff --git a/backend/backend.go b/backend/backend.go index d0620f34d..ab539a6e7 100644 --- a/backend/backend.go +++ b/backend/backend.go @@ -4,6 +4,11 @@ import ( "context" "errors" "fmt" + + "github.com/sirupsen/logrus" + + "github.com/docker/api/compose" + "github.com/docker/api/containers" ) var ( @@ -24,17 +29,23 @@ var backends = struct { r []*registeredBackend }{} +// Aggregation of service interfaces +type Service interface { + ContainerService() containers.Service + ComposeService() compose.Service +} + // Register adds a typed backend to the registry func Register(name string, backendType string, init initFunc) { if name == "" { - panic(errNoName) + logrus.Fatal(errNoName) } if backendType == "" { - panic(errNoType) + logrus.Fatal(errNoType) } for _, b := range backends.r { if b.backendType == backendType { - panic(errTypeRegistered) + logrus.Fatal(errTypeRegistered) } } diff --git a/cli/cmd/compose/compose.go b/cli/cmd/compose/compose.go index 885e4af58..78b210cfb 100644 --- a/cli/cmd/compose/compose.go +++ b/cli/cmd/compose/compose.go @@ -28,11 +28,11 @@ func upCommand() *cobra.Command { if err != nil { return err } - return c.AciService().Up(cmd.Context(), *opts) + return c.ComposeService().Up(cmd.Context(), *opts) }, } - upCmd.Flags().StringVar(&opts.Name, "name", "", "Project name") - upCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir") + upCmd.Flags().StringVar(&opts.Name, "name", "", "Project name") + upCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir") upCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files") upCmd.Flags().StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables") @@ -48,11 +48,11 @@ func downCommand() *cobra.Command { if err != nil { return err } - return c.AciService().Down(cmd.Context(), *opts) + return c.ComposeService().Down(cmd.Context(), *opts) }, } - downCmd.Flags().StringVar(&opts.Name, "name", "", "Project name") - downCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir") + downCmd.Flags().StringVar(&opts.Name, "name", "", "Project name") + downCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir") return downCmd -} \ No newline at end of file +} diff --git a/cli/cmd/exec.go b/cli/cmd/exec.go index ad024f4d2..a0199e209 100644 --- a/cli/cmd/exec.go +++ b/cli/cmd/exec.go @@ -62,5 +62,5 @@ func runExec(ctx context.Context, opts execOpts, name string, command string) er stdout = con } - return c.AciService().Exec(ctx, name, command, os.Stdin, stdout) + return c.ContainerService().Exec(ctx, name, command, os.Stdin, stdout) } diff --git a/cli/cmd/logs.go b/cli/cmd/logs.go index 65c72bf6c..d9706d149 100644 --- a/cli/cmd/logs.go +++ b/cli/cmd/logs.go @@ -46,5 +46,5 @@ func runLogs(ctx context.Context, containerName string, opts logsOpts) error { Writer: os.Stdout, } - return c.AciService().Logs(ctx, containerName, req) + return c.ContainerService().Logs(ctx, containerName, req) } diff --git a/cli/cmd/ps.go b/cli/cmd/ps.go index e54326cf8..168dfa702 100644 --- a/cli/cmd/ps.go +++ b/cli/cmd/ps.go @@ -23,7 +23,7 @@ var PsCommand = cobra.Command{ return errors.Wrap(err, "cannot connect to backend") } - containers, err := c.AciService().List(ctx) + containers, err := c.ContainerService().List(ctx) if err != nil { return errors.Wrap(err, "fetch containers") } diff --git a/cli/cmd/run/run.go b/cli/cmd/run/run.go index b6fcb29d9..b2c25c1f7 100644 --- a/cli/cmd/run/run.go +++ b/cli/cmd/run/run.go @@ -65,5 +65,5 @@ func runRun(ctx context.Context, image string, opts runOpts) error { return err } - return c.AciService().Run(ctx, project) + return c.ContainerService().Run(ctx, project) } diff --git a/client/client.go b/client/client.go index 9771d06f6..80f5e3d3e 100644 --- a/client/client.go +++ b/client/client.go @@ -31,11 +31,12 @@ import ( "context" "errors" - "github.com/docker/api/azure" "github.com/docker/api/backend" backendv1 "github.com/docker/api/backend/v1" cliv1 "github.com/docker/api/cli/v1" + "github.com/docker/api/compose" composev1 "github.com/docker/api/compose/v1" + "github.com/docker/api/containers" containersv1 "github.com/docker/api/containers/v1" apicontext "github.com/docker/api/context" "github.com/docker/api/context/store" @@ -57,13 +58,13 @@ func New(ctx context.Context) (*Client, error) { return nil, err } - aciService, ok := b.(azure.AciService) + service, ok := b.(backend.Service) if !ok { return nil, errors.New("backend not found") } return &Client{ backendType: contextType, - cc: aciService, + bs: service, }, nil } @@ -76,10 +77,15 @@ type Client struct { composev1.ComposeClient backendType string - cc azure.AciService + bs backend.Service } -// AciService returns the backend service for the current context -func (c *Client) AciService() azure.AciService { - return c.cc +// ContainerService returns the backend service for the current context +func (c *Client) ContainerService() containers.Service { + return c.bs.ContainerService() +} + +// ComposeService returns the backend service for the current context +func (c *Client) ComposeService() compose.Service { + return c.bs.ComposeService() } diff --git a/containers/api.go b/containers/api.go index b114ac20c..f3ba59454 100644 --- a/containers/api.go +++ b/containers/api.go @@ -44,8 +44,8 @@ type LogsRequest struct { Writer io.Writer } -// ContainerService interacts with the underlying container backend -type ContainerService interface { +// Service interacts with the underlying container backend +type Service interface { // List returns all the containers List(ctx context.Context) ([]Container, error) // Run creates and starts a container diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index 43f48be89..a30c38801 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -31,7 +31,7 @@ type proxyContainerAPI struct{} func (p *proxyContainerAPI) List(ctx context.Context, _ *v1.ListRequest) (*v1.ListResponse, error) { client := Client(ctx) - c, err := client.AciService().List(ctx) + c, err := client.ContainerService().List(ctx) if err != nil { return &v1.ListResponse{}, nil } @@ -52,7 +52,7 @@ func (p *proxyContainerAPI) List(ctx context.Context, _ *v1.ListRequest) (*v1.Li func (p *proxyContainerAPI) Create(ctx context.Context, request *v1.CreateRequest) (*v1.CreateResponse, error) { client := Client(ctx) - err := client.AciService().Run(ctx, containers.ContainerConfig{ + err := client.ContainerService().Run(ctx, containers.ContainerConfig{ ID: request.Id, Image: request.Image, })