Skip to content

Commit

Permalink
Implemented #9147
Browse files Browse the repository at this point in the history
Signed-off-by: Mehrad Dadar <mehrad.dadar@gmail.com>
  • Loading branch information
arhemd committed Feb 5, 2022
1 parent 5262d3b commit 65ed8cf
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 58 deletions.
2 changes: 1 addition & 1 deletion cmd/compose/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func runRemove(ctx context.Context, backend api.Service, opts removeOptions, ser
}

if opts.stop {
err := backend.Stop(ctx, project, api.StopOptions{
err := backend.Stop(ctx, project.Name, api.StopOptions{
Services: services,
})
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cmd/compose/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ func restartCommand(p *projectOptions, backend api.Service) *cobra.Command {
}

func runRestart(ctx context.Context, backend api.Service, opts restartOptions, services []string) error {
project, err := opts.toProject(services)
projectName, err := opts.toProjectName()
if err != nil {
return err
}

timeout := time.Duration(opts.timeout) * time.Second
return backend.Restart(ctx, project, api.RestartOptions{
return backend.Restart(ctx, projectName, api.RestartOptions{
Timeout: &timeout,
Services: services,
})
Expand Down
2 changes: 1 addition & 1 deletion cmd/compose/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,5 +240,5 @@ func startDependencies(ctx context.Context, backend api.Service, project types.P
if err := backend.Create(ctx, &project, api.CreateOptions{}); err != nil {
return err
}
return backend.Start(ctx, &project, api.StartOptions{})
return backend.Start(ctx, project.Name, api.StartOptions{})
}
6 changes: 4 additions & 2 deletions cmd/compose/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ func startCommand(p *projectOptions, backend api.Service) *cobra.Command {
}

func runStart(ctx context.Context, backend api.Service, opts startOptions, services []string) error {
project, err := opts.toProject(services)
projectName, err := opts.toProjectName()
if err != nil {
return err
}

return backend.Start(ctx, project, api.StartOptions{})
return backend.Start(ctx, projectName, api.StartOptions{
AttachTo: services,
})
}
4 changes: 2 additions & 2 deletions cmd/compose/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func stopCommand(p *projectOptions, backend api.Service) *cobra.Command {
}

func runStop(ctx context.Context, backend api.Service, opts stopOptions, services []string) error {
project, err := opts.toProject(services)
projectName, err := opts.toProjectName()
if err != nil {
return err
}
Expand All @@ -63,7 +63,7 @@ func runStop(ctx context.Context, backend api.Service, opts stopOptions, service
timeoutValue := time.Duration(opts.timeout) * time.Second
timeout = &timeoutValue
}
return backend.Stop(ctx, project, api.StopOptions{
return backend.Stop(ctx, projectName, api.StopOptions{
Timeout: timeout,
Services: services,
})
Expand Down
6 changes: 3 additions & 3 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ type Service interface {
// Create executes the equivalent to a `compose create`
Create(ctx context.Context, project *types.Project, opts CreateOptions) error
// Start executes the equivalent to a `compose start`
Start(ctx context.Context, project *types.Project, options StartOptions) error
Start(ctx context.Context, projectName string, options StartOptions) error
// Restart restarts containers
Restart(ctx context.Context, project *types.Project, options RestartOptions) error
Restart(ctx context.Context, projectName string, options RestartOptions) error
// Stop executes the equivalent to a `compose stop`
Stop(ctx context.Context, project *types.Project, options StopOptions) error
Stop(ctx context.Context, projectName string, options StopOptions) error
// Up executes the equivalent to a `compose up`
Up(ctx context.Context, project *types.Project, options UpOptions) error
// Down executes the equivalent to a `compose down`
Expand Down
27 changes: 9 additions & 18 deletions pkg/api/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ type ServiceProxy struct {
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
StartFn func(ctx context.Context, projectName string, options StartOptions) error
RestartFn func(ctx context.Context, projectName string, options RestartOptions) error
StopFn func(ctx context.Context, projectName string, 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
Expand Down Expand Up @@ -141,36 +141,27 @@ func (s *ServiceProxy) Create(ctx context.Context, project *types.Project, optio
}

// Start implements Service interface
func (s *ServiceProxy) Start(ctx context.Context, project *types.Project, options StartOptions) error {
func (s *ServiceProxy) Start(ctx context.Context, projectName string, options StartOptions) error {
if s.StartFn == nil {
return ErrNotImplemented
}
for _, i := range s.interceptors {
i(ctx, project)
}
return s.StartFn(ctx, project, options)
return s.StartFn(ctx, projectName, options)
}

// Restart implements Service interface
func (s *ServiceProxy) Restart(ctx context.Context, project *types.Project, options RestartOptions) error {
func (s *ServiceProxy) Restart(ctx context.Context, projectName string, options RestartOptions) error {
if s.RestartFn == nil {
return ErrNotImplemented
}
for _, i := range s.interceptors {
i(ctx, project)
}
return s.RestartFn(ctx, project, options)
return s.RestartFn(ctx, projectName, options)
}

// Stop implements Service interface
func (s *ServiceProxy) Stop(ctx context.Context, project *types.Project, options StopOptions) error {
func (s *ServiceProxy) Stop(ctx context.Context, projectName string, options StopOptions) error {
if s.StopFn == nil {
return ErrNotImplemented
}
for _, i := range s.interceptors {
i(ctx, project)
}
return s.StopFn(ctx, project, options)
return s.StopFn(ctx, projectName, options)
}

// Up implements Service interface
Expand Down
31 changes: 31 additions & 0 deletions pkg/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,34 @@ func escapeDollarSign(marshal []byte) []byte {
escDollar := []byte{'$', '$'}
return bytes.ReplaceAll(marshal, dollar, escDollar)
}

// projectFromName builds a types.Project based on actual resources with compose labels set
func (s *composeService) projectFromName(containers Containers, projectName string) *types.Project {
project := &types.Project{
Name: projectName,
}
if len(containers) == 0 {
return project
}
set := map[string]moby.Container{}
for _, c := range containers {
set[c.Labels[api.ServiceLabel]] = c
}
for s, c := range set {
service := types.ServiceConfig{
Name: s,
Image: c.Image,
Labels: c.Labels,
}
dependencies := c.Labels[api.DependenciesLabel]
if len(dependencies) > 0 {
service.DependsOn = types.DependsOnConfig{}
for _, d := range strings.Split(dependencies, ",") {
service.DependsOn[d] = types.ServiceDependency{}
}
}
project.Services = append(project.Services, service)
}

return project
}
12 changes: 7 additions & 5 deletions pkg/compose/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,28 @@ package compose
import (
"context"

"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"golang.org/x/sync/errgroup"

"github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/utils"
)

func (s *composeService) Restart(ctx context.Context, project *types.Project, options api.RestartOptions) error {
func (s *composeService) Restart(ctx context.Context, projectName string, options api.RestartOptions) error {
return progress.Run(ctx, func(ctx context.Context) error {
return s.restart(ctx, project, options)
return s.restart(ctx, projectName, options)
})
}

func (s *composeService) restart(ctx context.Context, project *types.Project, options api.RestartOptions) error {
observedState, err := s.getContainers(ctx, project.Name, oneOffInclude, true)
func (s *composeService) restart(ctx context.Context, projectName string, options api.RestartOptions) error {

observedState, err := s.getContainers(ctx, projectName, oneOffInclude, true)
if err != nil {
return err
}

project := s.projectFromName(observedState, projectName)

if len(options.Services) == 0 {
options.Services = project.ServiceNames()
}
Expand Down
16 changes: 10 additions & 6 deletions pkg/compose/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,21 @@ import (
"github.com/docker/compose/v2/pkg/progress"
)

func (s *composeService) Start(ctx context.Context, project *types.Project, options api.StartOptions) error {
func (s *composeService) Start(ctx context.Context, projectName string, options api.StartOptions) error {
return progress.Run(ctx, func(ctx context.Context) error {
return s.start(ctx, project, options, nil)
return s.start(ctx, projectName, options, nil)
})
}

func (s *composeService) start(ctx context.Context, project *types.Project, options api.StartOptions, listener api.ContainerEventListener) error {
if len(options.AttachTo) == 0 {
options.AttachTo = project.ServiceNames()
func (s *composeService) start(ctx context.Context, projectName string, options api.StartOptions, listener api.ContainerEventListener) error {
var containers Containers
containers, err := s.getContainers(ctx, projectName, oneOffInclude, true, options.AttachTo...)
if err != nil {
return err
}

project := s.projectFromName(containers, projectName)

eg, ctx := errgroup.WithContext(ctx)
if listener != nil {
attached, err := s.attach(ctx, project, listener, options.AttachTo)
Expand All @@ -53,7 +57,7 @@ func (s *composeService) start(ctx context.Context, project *types.Project, opti
})
}

err := InDependencyOrder(ctx, project, func(c context.Context, name string) error {
err = InDependencyOrder(ctx, project, func(c context.Context, name string) error {
service, err := project.GetService(name)
if err != nil {
return err
Expand Down
16 changes: 9 additions & 7 deletions pkg/compose/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,31 @@ import (

"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"

"github.com/compose-spec/compose-go/types"
//"github.com/compose-spec/compose-go/types"
)

func (s *composeService) Stop(ctx context.Context, project *types.Project, options api.StopOptions) error {
func (s *composeService) Stop(ctx context.Context, projectName string, options api.StopOptions) error {
return progress.Run(ctx, func(ctx context.Context) error {
return s.stop(ctx, project, options)
return s.stop(ctx, projectName, options)
})
}

func (s *composeService) stop(ctx context.Context, project *types.Project, options api.StopOptions) error {
func (s *composeService) stop(ctx context.Context, projectName string, options api.StopOptions) error {
w := progress.ContextWriter(ctx)

services := options.Services
if len(services) == 0 {
services = project.ServiceNames()
services = []string{}
}

var containers Containers
containers, err := s.getContainers(ctx, project.Name, oneOffInclude, true, services...)
containers, err := s.getContainers(ctx, projectName, oneOffInclude, true, services...)
if err != nil {
return err
}

project := s.projectFromName(containers, projectName)

return InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
return s.stopContainers(ctx, w, containers.filter(isService(service)), options.Timeout)
})
Expand Down
9 changes: 1 addition & 8 deletions pkg/compose/stop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
compose "github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/mocks"

"github.com/compose-spec/compose-go/types"
moby "github.com/docker/docker/api/types"
"github.com/golang/mock/gomock"
"gotest.tools/v3/assert"
Expand All @@ -50,13 +49,7 @@ func TestStopTimeout(t *testing.T) {
api.EXPECT().ContainerStop(gomock.Any(), "456", &timeout).Return(nil)
api.EXPECT().ContainerStop(gomock.Any(), "789", &timeout).Return(nil)

err := tested.Stop(ctx, &types.Project{
Name: strings.ToLower(testProject),
Services: []types.ServiceConfig{
{Name: "service1"},
{Name: "service2"},
},
}, compose.StopOptions{
err := tested.Stop(ctx, strings.ToLower(testProject), compose.StopOptions{
Timeout: &timeout,
})
assert.NilError(t, err)
Expand Down
6 changes: 3 additions & 3 deletions pkg/compose/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
return err
}
if options.Start.Attach == nil {
return s.start(ctx, project, options.Start, nil)
return s.start(ctx, project.Name, options.Start, nil)
}
return nil
})
Expand All @@ -65,7 +65,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
})
}()

return s.Stop(ctx, project, api.StopOptions{
return s.Stop(ctx, project.Name, api.StopOptions{
Services: options.Create.Services,
})
})
Expand All @@ -85,7 +85,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
return err
})

err = s.start(ctx, project, options.Start, printer.HandleEvent)
err = s.start(ctx, project.Name, options.Start, printer.HandleEvent)
if err != nil {
return err
}
Expand Down

0 comments on commit 65ed8cf

Please sign in to comment.