mirror of https://github.com/docker/compose.git
Merge pull request #1688 from docker/interceptor
This commit is contained in:
commit
e91e163c84
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
|
|
27
cli/main.go
27
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:
|
||||
|
|
8
main.go
8
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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue