diff --git a/api/compose/delegator.go b/api/compose/delegator.go deleted file mode 100644 index 08905bd5d..000000000 --- a/api/compose/delegator.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright 2020 Docker Compose CLI authors - - 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" - - "github.com/compose-spec/compose-go/types" -) - -// ServiceDelegator implements Service by delegating to another implementation. This allows lazy init -type ServiceDelegator struct { - Delegate Service -} - -//Build implements Service interface -func (s *ServiceDelegator) Build(ctx context.Context, project *types.Project, options BuildOptions) error { - return s.Delegate.Build(ctx, project, options) -} - -//Push implements Service interface -func (s *ServiceDelegator) Push(ctx context.Context, project *types.Project, options PushOptions) error { - return s.Delegate.Push(ctx, project, options) -} - -//Pull implements Service interface -func (s *ServiceDelegator) Pull(ctx context.Context, project *types.Project, options PullOptions) error { - return s.Delegate.Pull(ctx, project, options) -} - -//Create implements Service interface -func (s *ServiceDelegator) Create(ctx context.Context, project *types.Project, options CreateOptions) error { - return s.Delegate.Create(ctx, project, options) -} - -//Start implements Service interface -func (s *ServiceDelegator) Start(ctx context.Context, project *types.Project, options StartOptions) error { - return s.Delegate.Start(ctx, project, options) -} - -//Restart implements Service interface -func (s *ServiceDelegator) Restart(ctx context.Context, project *types.Project, options RestartOptions) error { - return s.Delegate.Restart(ctx, project, options) -} - -//Stop implements Service interface -func (s *ServiceDelegator) Stop(ctx context.Context, project *types.Project, options StopOptions) error { - return s.Delegate.Stop(ctx, project, options) -} - -//Up implements Service interface -func (s *ServiceDelegator) Up(ctx context.Context, project *types.Project, options UpOptions) error { - return s.Delegate.Up(ctx, project, options) -} - -//Down implements Service interface -func (s *ServiceDelegator) Down(ctx context.Context, project string, options DownOptions) error { - return s.Delegate.Down(ctx, project, options) -} - -//Logs implements Service interface -func (s *ServiceDelegator) Logs(ctx context.Context, project string, consumer LogConsumer, options LogOptions) error { - return s.Delegate.Logs(ctx, project, consumer, options) -} - -//Ps implements Service interface -func (s *ServiceDelegator) Ps(ctx context.Context, project string, options PsOptions) ([]ContainerSummary, error) { - return s.Delegate.Ps(ctx, project, options) -} - -//List implements Service interface -func (s *ServiceDelegator) List(ctx context.Context, options ListOptions) ([]Stack, error) { - return s.Delegate.List(ctx, options) -} - -//Convert implements Service interface -func (s *ServiceDelegator) Convert(ctx context.Context, project *types.Project, options ConvertOptions) ([]byte, error) { - return s.Delegate.Convert(ctx, project, options) -} - -//Kill implements Service interface -func (s *ServiceDelegator) Kill(ctx context.Context, project *types.Project, options KillOptions) error { - return s.Delegate.Kill(ctx, project, options) -} - -//RunOneOffContainer implements Service interface -func (s *ServiceDelegator) RunOneOffContainer(ctx context.Context, project *types.Project, options RunOptions) (int, error) { - return s.Delegate.RunOneOffContainer(ctx, project, options) -} - -//Remove implements Service interface -func (s *ServiceDelegator) Remove(ctx context.Context, project *types.Project, options RemoveOptions) ([]string, error) { - return s.Delegate.Remove(ctx, project, options) -} - -//Exec implements Service interface -func (s *ServiceDelegator) Exec(ctx context.Context, project *types.Project, options RunOptions) (int, error) { - return s.Delegate.Exec(ctx, project, options) -} - -//Copy implements Service interface -func (s *ServiceDelegator) Copy(ctx context.Context, project *types.Project, options CopyOptions) error { - return s.Delegate.Copy(ctx, project, options) -} - -//Pause implements Service interface -func (s *ServiceDelegator) Pause(ctx context.Context, project string, options PauseOptions) error { - return s.Delegate.Pause(ctx, project, options) -} - -//UnPause implements Service interface -func (s *ServiceDelegator) UnPause(ctx context.Context, project string, options PauseOptions) error { - return s.Delegate.UnPause(ctx, project, options) -} - -//Top implements Service interface -func (s *ServiceDelegator) Top(ctx context.Context, project string, services []string) ([]ContainerProcSummary, error) { - return s.Delegate.Top(ctx, project, services) -} - -//Events implements Service interface -func (s *ServiceDelegator) Events(ctx context.Context, project string, options EventsOptions) error { - return s.Delegate.Events(ctx, project, options) -} - -//Port implements Service interface -func (s *ServiceDelegator) Port(ctx context.Context, project string, service string, port int, options PortOptions) (string, int, error) { - return s.Delegate.Port(ctx, project, service, port, options) -} - -//Images implements Service interface -func (s *ServiceDelegator) Images(ctx context.Context, project string, options ImagesOptions) ([]ImageSummary, error) { - return s.Delegate.Images(ctx, project, options) -} diff --git a/api/compose/noimpl.go b/api/compose/noimpl.go deleted file mode 100644 index 356b9a996..000000000 --- a/api/compose/noimpl.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright 2020 Docker Compose CLI authors - - 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" - - "github.com/compose-spec/compose-go/types" - - "github.com/docker/compose-cli/api/errdefs" -) - -// NoImpl implements Service to return ErrNotImplemented -type NoImpl struct{} - -//Build implements Service interface -func (s NoImpl) Build(ctx context.Context, project *types.Project, options BuildOptions) error { - return errdefs.ErrNotImplemented -} - -//Push implements Service interface -func (s NoImpl) Push(ctx context.Context, project *types.Project, options PushOptions) error { - return errdefs.ErrNotImplemented -} - -//Pull implements Service interface -func (s NoImpl) Pull(ctx context.Context, project *types.Project, options PullOptions) error { - return errdefs.ErrNotImplemented -} - -//Create implements Service interface -func (s NoImpl) Create(ctx context.Context, project *types.Project, options CreateOptions) error { - return errdefs.ErrNotImplemented -} - -//Start implements Service interface -func (s NoImpl) Start(ctx context.Context, project *types.Project, options StartOptions) error { - return errdefs.ErrNotImplemented -} - -//Restart implements Service interface -func (s NoImpl) Restart(ctx context.Context, project *types.Project, options RestartOptions) error { - return errdefs.ErrNotImplemented -} - -//Stop implements Service interface -func (s NoImpl) Stop(ctx context.Context, project *types.Project, options StopOptions) error { - return errdefs.ErrNotImplemented -} - -//Up implements Service interface -func (s NoImpl) Up(ctx context.Context, project *types.Project, options UpOptions) error { - return errdefs.ErrNotImplemented -} - -//Down implements Service interface -func (s NoImpl) Down(ctx context.Context, project string, options DownOptions) error { - return errdefs.ErrNotImplemented -} - -//Logs implements Service interface -func (s NoImpl) Logs(ctx context.Context, project string, consumer LogConsumer, options LogOptions) error { - return errdefs.ErrNotImplemented -} - -//Ps implements Service interface -func (s NoImpl) Ps(ctx context.Context, project string, options PsOptions) ([]ContainerSummary, error) { - return nil, errdefs.ErrNotImplemented -} - -//List implements Service interface -func (s NoImpl) List(ctx context.Context, options ListOptions) ([]Stack, error) { - return nil, errdefs.ErrNotImplemented -} - -//Convert implements Service interface -func (s NoImpl) Convert(ctx context.Context, project *types.Project, options ConvertOptions) ([]byte, error) { - return nil, errdefs.ErrNotImplemented -} - -//Kill implements Service interface -func (s NoImpl) Kill(ctx context.Context, project *types.Project, options KillOptions) error { - return errdefs.ErrNotImplemented -} - -//RunOneOffContainer implements Service interface -func (s NoImpl) RunOneOffContainer(ctx context.Context, project *types.Project, options RunOptions) (int, error) { - return 0, errdefs.ErrNotImplemented -} - -//Remove implements Service interface -func (s NoImpl) Remove(ctx context.Context, project *types.Project, options RemoveOptions) ([]string, error) { - return nil, errdefs.ErrNotImplemented -} - -//Exec implements Service interface -func (s NoImpl) Exec(ctx context.Context, project *types.Project, opts RunOptions) (int, error) { - return 0, errdefs.ErrNotImplemented -} - -//Copy implements Service interface -func (s NoImpl) Copy(ctx context.Context, project *types.Project, opts CopyOptions) error { - return errdefs.ErrNotImplemented -} - -//Pause implements Service interface -func (s NoImpl) Pause(ctx context.Context, project string, options PauseOptions) error { - return errdefs.ErrNotImplemented -} - -//UnPause implements Service interface -func (s NoImpl) UnPause(ctx context.Context, project string, options PauseOptions) error { - return errdefs.ErrNotImplemented -} - -//Top implements Service interface -func (s NoImpl) Top(ctx context.Context, project string, services []string) ([]ContainerProcSummary, error) { - return nil, errdefs.ErrNotImplemented -} - -//Events implements Service interface -func (s NoImpl) Events(ctx context.Context, project string, options EventsOptions) error { - return errdefs.ErrNotImplemented -} - -//Port implements Service interface -func (s NoImpl) Port(ctx context.Context, project string, service string, port int, options PortOptions) (string, int, error) { - return "", 0, errdefs.ErrNotImplemented -} - -//Images implements Service interface -func (s NoImpl) Images(ctx context.Context, project string, options ImagesOptions) ([]ImageSummary, error) { - return nil, errdefs.ErrNotImplemented -} diff --git a/api/compose/proxy.go b/api/compose/proxy.go new file mode 100644 index 000000000..e01e1a847 --- /dev/null +++ b/api/compose/proxy.go @@ -0,0 +1,333 @@ +/* + Copyright 2020 Docker Compose CLI authors + + 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" + + "github.com/docker/compose-cli/api/errdefs" + + "github.com/compose-spec/compose-go/types" +) + +// ServiceProxy implements Service by delegating to implementation functions. This allows lazy init and per-method overrides +type ServiceProxy struct { + BuildFn func(ctx context.Context, project *types.Project, options BuildOptions) error + PushFn func(ctx context.Context, project *types.Project, options PushOptions) error + PullFn func(ctx context.Context, project *types.Project, opts PullOptions) error + CreateFn func(ctx context.Context, project *types.Project, opts CreateOptions) error + StartFn func(ctx context.Context, project *types.Project, options StartOptions) error + RestartFn func(ctx context.Context, project *types.Project, options RestartOptions) error + StopFn func(ctx context.Context, project *types.Project, options StopOptions) error + UpFn func(ctx context.Context, project *types.Project, options UpOptions) error + DownFn func(ctx context.Context, projectName string, options DownOptions) error + LogsFn func(ctx context.Context, projectName string, consumer LogConsumer, options LogOptions) error + PsFn func(ctx context.Context, projectName string, options PsOptions) ([]ContainerSummary, error) + ListFn func(ctx context.Context, options ListOptions) ([]Stack, error) + ConvertFn func(ctx context.Context, project *types.Project, options ConvertOptions) ([]byte, error) + KillFn func(ctx context.Context, project *types.Project, options KillOptions) error + RunOneOffContainerFn func(ctx context.Context, project *types.Project, opts RunOptions) (int, error) + RemoveFn func(ctx context.Context, project *types.Project, options RemoveOptions) ([]string, error) + ExecFn func(ctx context.Context, project *types.Project, opts RunOptions) (int, error) + CopyFn func(ctx context.Context, project *types.Project, opts CopyOptions) error + PauseFn func(ctx context.Context, project string, options PauseOptions) error + UnPauseFn func(ctx context.Context, project string, options PauseOptions) error + TopFn func(ctx context.Context, projectName string, services []string) ([]ContainerProcSummary, error) + EventsFn func(ctx context.Context, project string, options EventsOptions) error + PortFn func(ctx context.Context, project string, service string, port int, options PortOptions) (string, int, error) + ImagesFn func(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error) + interceptors []Interceptor +} + +// NewServiceProxy produces a ServiceProxy +func NewServiceProxy() *ServiceProxy { + return &ServiceProxy{} +} + +// Interceptor allow to customize the compose types.Project before the actual Service method is executed +type Interceptor func(ctx context.Context, project *types.Project) + +var _ Service = &ServiceProxy{} + +// WithService configure proxy to use specified Service as delegate +func (s *ServiceProxy) WithService(service Service) *ServiceProxy { + s.BuildFn = service.Build + s.PushFn = service.Push + s.PullFn = service.Pull + s.CreateFn = service.Create + s.StartFn = service.Start + s.RestartFn = service.Restart + s.StopFn = service.Stop + s.UpFn = service.Up + s.DownFn = service.Down + s.LogsFn = service.Logs + s.PsFn = service.Ps + s.ListFn = service.List + s.ConvertFn = service.Convert + s.KillFn = service.Kill + s.RunOneOffContainerFn = service.RunOneOffContainer + s.RemoveFn = service.Remove + s.ExecFn = service.Exec + s.CopyFn = service.Copy + s.PauseFn = service.Pause + s.UnPauseFn = service.UnPause + s.TopFn = service.Top + s.EventsFn = service.Events + s.PortFn = service.Port + s.ImagesFn = service.Images + return s +} + +// WithInterceptor configures Interceptor to be applied to Service method execution +func (s *ServiceProxy) WithInterceptor(interceptors ...Interceptor) *ServiceProxy { + s.interceptors = append(s.interceptors, interceptors...) + return s +} + +//Build implements Service interface +func (s *ServiceProxy) Build(ctx context.Context, project *types.Project, options BuildOptions) error { + if s.BuildFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.BuildFn(ctx, project, options) +} + +//Push implements Service interface +func (s *ServiceProxy) Push(ctx context.Context, project *types.Project, options PushOptions) error { + if s.PushFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.PushFn(ctx, project, options) +} + +//Pull implements Service interface +func (s *ServiceProxy) Pull(ctx context.Context, project *types.Project, options PullOptions) error { + if s.PullFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.PullFn(ctx, project, options) +} + +//Create implements Service interface +func (s *ServiceProxy) Create(ctx context.Context, project *types.Project, options CreateOptions) error { + if s.CreateFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.CreateFn(ctx, project, options) +} + +//Start implements Service interface +func (s *ServiceProxy) Start(ctx context.Context, project *types.Project, options StartOptions) error { + if s.StartFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.StartFn(ctx, project, options) +} + +//Restart implements Service interface +func (s *ServiceProxy) Restart(ctx context.Context, project *types.Project, options RestartOptions) error { + if s.RestartFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.RestartFn(ctx, project, options) +} + +//Stop implements Service interface +func (s *ServiceProxy) Stop(ctx context.Context, project *types.Project, options StopOptions) error { + if s.StopFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.StopFn(ctx, project, options) +} + +//Up implements Service interface +func (s *ServiceProxy) Up(ctx context.Context, project *types.Project, options UpOptions) error { + if s.UpFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.UpFn(ctx, project, options) +} + +//Down implements Service interface +func (s *ServiceProxy) Down(ctx context.Context, project string, options DownOptions) error { + if s.DownFn == nil { + return errdefs.ErrNotImplemented + } + return s.DownFn(ctx, project, options) +} + +//Logs implements Service interface +func (s *ServiceProxy) Logs(ctx context.Context, project string, consumer LogConsumer, options LogOptions) error { + if s.LogsFn == nil { + return errdefs.ErrNotImplemented + } + return s.LogsFn(ctx, project, consumer, options) +} + +//Ps implements Service interface +func (s *ServiceProxy) Ps(ctx context.Context, project string, options PsOptions) ([]ContainerSummary, error) { + if s.PsFn == nil { + return nil, errdefs.ErrNotImplemented + } + return s.PsFn(ctx, project, options) +} + +//List implements Service interface +func (s *ServiceProxy) List(ctx context.Context, options ListOptions) ([]Stack, error) { + if s.ListFn == nil { + return nil, errdefs.ErrNotImplemented + } + return s.ListFn(ctx, options) +} + +//Convert implements Service interface +func (s *ServiceProxy) Convert(ctx context.Context, project *types.Project, options ConvertOptions) ([]byte, error) { + if s.ConvertFn == nil { + return nil, errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.ConvertFn(ctx, project, options) +} + +//Kill implements Service interface +func (s *ServiceProxy) Kill(ctx context.Context, project *types.Project, options KillOptions) error { + if s.KillFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.KillFn(ctx, project, options) +} + +//RunOneOffContainer implements Service interface +func (s *ServiceProxy) RunOneOffContainer(ctx context.Context, project *types.Project, options RunOptions) (int, error) { + if s.RunOneOffContainerFn == nil { + return 0, errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.RunOneOffContainerFn(ctx, project, options) +} + +//Remove implements Service interface +func (s *ServiceProxy) Remove(ctx context.Context, project *types.Project, options RemoveOptions) ([]string, error) { + if s.RemoveFn == nil { + return nil, errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.RemoveFn(ctx, project, options) +} + +//Exec implements Service interface +func (s *ServiceProxy) Exec(ctx context.Context, project *types.Project, options RunOptions) (int, error) { + if s.ExecFn == nil { + return 0, errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.ExecFn(ctx, project, options) +} + +//Copy implements Service interface +func (s *ServiceProxy) Copy(ctx context.Context, project *types.Project, options CopyOptions) error { + if s.CopyFn == nil { + return errdefs.ErrNotImplemented + } + for _, i := range s.interceptors { + i(ctx, project) + } + return s.CopyFn(ctx, project, options) +} + +//Pause implements Service interface +func (s *ServiceProxy) Pause(ctx context.Context, project string, options PauseOptions) error { + if s.PauseFn == nil { + return errdefs.ErrNotImplemented + } + return s.PauseFn(ctx, project, options) +} + +//UnPause implements Service interface +func (s *ServiceProxy) UnPause(ctx context.Context, project string, options PauseOptions) error { + if s.UnPauseFn == nil { + return errdefs.ErrNotImplemented + } + return s.UnPauseFn(ctx, project, options) +} + +//Top implements Service interface +func (s *ServiceProxy) Top(ctx context.Context, project string, services []string) ([]ContainerProcSummary, error) { + if s.TopFn == nil { + return nil, errdefs.ErrNotImplemented + } + return s.TopFn(ctx, project, services) +} + +//Events implements Service interface +func (s *ServiceProxy) Events(ctx context.Context, project string, options EventsOptions) error { + if s.EventsFn == nil { + return errdefs.ErrNotImplemented + } + return s.EventsFn(ctx, project, options) +} + +//Port implements Service interface +func (s *ServiceProxy) Port(ctx context.Context, project string, service string, port int, options PortOptions) (string, int, error) { + if s.PortFn == nil { + return "", 0, errdefs.ErrNotImplemented + } + return s.PortFn(ctx, project, service, port, options) +} + +//Images implements Service interface +func (s *ServiceProxy) Images(ctx context.Context, project string, options ImagesOptions) ([]ImageSummary, error) { + if s.ImagesFn == nil { + return nil, errdefs.ErrNotImplemented + } + return s.ImagesFn(ctx, project, options) +} diff --git a/cli/cmd/compose/up.go b/cli/cmd/compose/up.go index b7a4b125b..88fe33f03 100644 --- a/cli/cmd/compose/up.go +++ b/cli/cmd/compose/up.go @@ -45,8 +45,6 @@ type composeOptions struct { *projectOptions Build bool noBuild bool - // ACI only - DomainName string } type upOptions struct { @@ -186,8 +184,6 @@ func upCommand(p *projectOptions, contextType string, backend compose.Service) * flags.BoolVar(&opts.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.") switch contextType { - case store.AciContextType: - flags.StringVar(&opts.DomainName, "domainname", "", "Container NIS domain name") case store.LocalContextType, store.DefaultContextType, store.EcsLocalSimulationContextType: flags.BoolVar(&opts.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.") flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.") @@ -360,10 +356,6 @@ func setup(opts composeOptions, services []string) (*types.Project, error) { return nil, err } - if opts.DomainName != "" { - // arbitrarily set the domain name on the first service ; ACI backend will expose the entire project - project.Services[0].DomainName = opts.DomainName - } if opts.Build { for i, service := range project.Services { service.PullPolicy = types.PullPolicyBuild diff --git a/cli/main.go b/cli/main.go index 3057c9066..548957816 100644 --- a/cli/main.go +++ b/cli/main.go @@ -28,12 +28,14 @@ import ( "syscall" "time" + "github.com/compose-spec/compose-go/types" "github.com/docker/cli/cli" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/docker/compose-cli/api/backend" + api "github.com/docker/compose-cli/api/compose" "github.com/docker/compose-cli/api/config" apicontext "github.com/docker/compose-cli/api/context" "github.com/docker/compose-cli/api/context/store" @@ -223,7 +225,14 @@ func main() { if ctype != store.DefaultContextType { // On default context, "compose" is implemented by CLI Plugin - root.AddCommand(compose.RootCommand(ctype, service.ComposeService())) + proxy := api.NewServiceProxy().WithService(service.ComposeService()) + command := compose.RootCommand(ctype, proxy) + + if ctype == store.AciContextType { + customizeCliForACI(command, proxy) + } + + root.AddCommand(command) } if err = root.ExecuteContext(ctx); err != nil { @@ -232,6 +241,22 @@ func main() { metrics.Track(ctype, os.Args[1:], metrics.SuccessStatus) } +func customizeCliForACI(command *cobra.Command, proxy *api.ServiceProxy) { + var domainName string + for _, c := range command.Commands() { + if c.Name() == "up" { + c.Flags().StringVar(&domainName, "domainname", "", "Container NIS domain name") + proxy.WithInterceptor(func(ctx context.Context, project *types.Project) { + if domainName != "" { + // arbitrarily set the domain name on the first service ; ACI backend will expose the entire project + project.Services[0].DomainName = domainName + } + + }) + } + } +} + func getBackend(ctype string, configDir string, opts cliopts.GlobalOpts) (backend.Service, error) { switch ctype { case store.DefaultContextType, store.LocalContextType: diff --git a/main.go b/main.go index cb7e0956b..1041fda33 100644 --- a/main.go +++ b/main.go @@ -35,16 +35,14 @@ import ( func main() { plugin.Run(func(dockerCli command.Cli) *cobra.Command { - lazyInit := api.ServiceDelegator{ - Delegate: api.NoImpl{}, - } - cmd := compose.RootCommand(store.DefaultContextType, &lazyInit) + lazyInit := api.NewServiceProxy() + cmd := compose.RootCommand(store.DefaultContextType, lazyInit) originalPreRun := cmd.PersistentPreRunE cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { if err := plugin.PersistentPreRunE(cmd, args); err != nil { return err } - lazyInit.Delegate = impl.NewComposeService(dockerCli.Client(), dockerCli.ConfigFile()) + lazyInit.WithService(impl.NewComposeService(dockerCli.Client(), dockerCli.ConfigFile())) if originalPreRun != nil { return originalPreRun(cmd, args) }