mirror of https://github.com/docker/compose.git
Add restart command
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
This commit is contained in:
parent
7bb0f02d2e
commit
2fdc3bad48
|
@ -64,6 +64,10 @@ func (cs *aciComposeService) Start(ctx context.Context, project *types.Project,
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *aciComposeService) Restart(ctx context.Context, project *types.Project, options compose.RestartOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (cs *aciComposeService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
func (cs *aciComposeService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,10 @@ func (c *composeService) Start(ctx context.Context, project *types.Project, opti
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *composeService) Restart(ctx context.Context, project *types.Project, options compose.RestartOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (c *composeService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
func (c *composeService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ type Service interface {
|
||||||
Create(ctx context.Context, project *types.Project, opts CreateOptions) error
|
Create(ctx context.Context, project *types.Project, opts CreateOptions) error
|
||||||
// Start executes the equivalent to a `compose start`
|
// Start executes the equivalent to a `compose start`
|
||||||
Start(ctx context.Context, project *types.Project, options StartOptions) error
|
Start(ctx context.Context, project *types.Project, options StartOptions) error
|
||||||
|
// Restart restarts containers
|
||||||
|
Restart(ctx context.Context, project *types.Project, options RestartOptions) error
|
||||||
// Stop executes the equivalent to a `compose stop`
|
// Stop executes the equivalent to a `compose stop`
|
||||||
Stop(ctx context.Context, project *types.Project, options StopOptions) error
|
Stop(ctx context.Context, project *types.Project, options StopOptions) error
|
||||||
// Up executes the equivalent to a `compose up`
|
// Up executes the equivalent to a `compose up`
|
||||||
|
@ -106,6 +108,12 @@ type StartOptions struct {
|
||||||
Services []string
|
Services []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RestartOptions group options of the Restart API
|
||||||
|
type RestartOptions struct {
|
||||||
|
// Timeout override container restart timeout
|
||||||
|
Timeout *time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
// StopOptions group options of the Stop API
|
// StopOptions group options of the Stop API
|
||||||
type StopOptions struct {
|
type StopOptions struct {
|
||||||
// Timeout override container stop timeout
|
// Timeout override container stop timeout
|
||||||
|
|
|
@ -68,6 +68,16 @@ func StartedEvent(ID string) Event {
|
||||||
return NewEvent(ID, Done, "Started")
|
return NewEvent(ID, Done, "Started")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RestartingEvent creates a new Restarting in progress Event
|
||||||
|
func RestartingEvent(ID string) Event {
|
||||||
|
return NewEvent(ID, Working, "Restarting")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestartedEvent creates a new Restarted in progress Event
|
||||||
|
func RestartedEvent(ID string) Event {
|
||||||
|
return NewEvent(ID, Done, "Restarted")
|
||||||
|
}
|
||||||
|
|
||||||
// RunningEvent creates a new Running in progress Event
|
// RunningEvent creates a new Running in progress Event
|
||||||
func RunningEvent(ID string) Event {
|
func RunningEvent(ID string) Event {
|
||||||
return NewEvent(ID, Done, "Running")
|
return NewEvent(ID, Done, "Running")
|
||||||
|
|
|
@ -127,6 +127,7 @@ func Command(contextType string) *cobra.Command {
|
||||||
upCommand(&opts, contextType),
|
upCommand(&opts, contextType),
|
||||||
downCommand(&opts, contextType),
|
downCommand(&opts, contextType),
|
||||||
startCommand(&opts),
|
startCommand(&opts),
|
||||||
|
restartCommand(&opts),
|
||||||
stopCommand(&opts),
|
stopCommand(&opts),
|
||||||
psCommand(&opts),
|
psCommand(&opts),
|
||||||
listCommand(contextType),
|
listCommand(contextType),
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/docker/compose-cli/api/client"
|
||||||
|
"github.com/docker/compose-cli/api/compose"
|
||||||
|
"github.com/docker/compose-cli/api/progress"
|
||||||
|
)
|
||||||
|
|
||||||
|
type restartOptions struct {
|
||||||
|
*projectOptions
|
||||||
|
timeout int
|
||||||
|
}
|
||||||
|
|
||||||
|
func restartCommand(p *projectOptions) *cobra.Command {
|
||||||
|
opts := restartOptions{
|
||||||
|
projectOptions: p,
|
||||||
|
}
|
||||||
|
restartCmd := &cobra.Command{
|
||||||
|
Use: "restart",
|
||||||
|
Short: "Restart containers",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return runRestart(cmd.Context(), opts, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
flags := restartCmd.Flags()
|
||||||
|
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
|
||||||
|
|
||||||
|
return restartCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runRestart(ctx context.Context, opts restartOptions, services []string) error {
|
||||||
|
c, err := client.New(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := opts.toProject(services)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout := time.Duration(opts.timeout) * time.Second
|
||||||
|
_, err = progress.Run(ctx, func(ctx context.Context) (string, error) {
|
||||||
|
return "", c.ComposeService().Restart(ctx, project, compose.RestartOptions{
|
||||||
|
Timeout: &timeout,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ cname:
|
||||||
- docker compose ps
|
- docker compose ps
|
||||||
- docker compose pull
|
- docker compose pull
|
||||||
- docker compose push
|
- docker compose push
|
||||||
|
- docker compose restart
|
||||||
- docker compose rm
|
- docker compose rm
|
||||||
- docker compose run
|
- docker compose run
|
||||||
- docker compose start
|
- docker compose start
|
||||||
|
@ -38,6 +39,7 @@ clink:
|
||||||
- docker_compose_ps.yaml
|
- docker_compose_ps.yaml
|
||||||
- docker_compose_pull.yaml
|
- docker_compose_pull.yaml
|
||||||
- docker_compose_push.yaml
|
- docker_compose_push.yaml
|
||||||
|
- docker_compose_restart.yaml
|
||||||
- docker_compose_rm.yaml
|
- docker_compose_rm.yaml
|
||||||
- docker_compose_run.yaml
|
- docker_compose_run.yaml
|
||||||
- docker_compose_start.yaml
|
- docker_compose_start.yaml
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
command: docker compose restart
|
||||||
|
short: Restart containers
|
||||||
|
long: Restart containers
|
||||||
|
usage: docker compose restart
|
||||||
|
pname: docker compose
|
||||||
|
plink: docker_compose.yaml
|
||||||
|
options:
|
||||||
|
- option: timeout
|
||||||
|
shorthand: t
|
||||||
|
value_type: int
|
||||||
|
default_value: "10"
|
||||||
|
description: Specify a shutdown timeout in seconds
|
||||||
|
deprecated: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
deprecated: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
|
|
@ -57,6 +57,10 @@ func (e ecsLocalSimulation) Start(ctx context.Context, project *types.Project, o
|
||||||
return e.compose.Start(ctx, project, options)
|
return e.compose.Start(ctx, project, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e ecsLocalSimulation) Restart(ctx context.Context, project *types.Project, options compose.RestartOptions) error {
|
||||||
|
return e.compose.Restart(ctx, project, options)
|
||||||
|
}
|
||||||
|
|
||||||
func (e ecsLocalSimulation) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
func (e ecsLocalSimulation) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
||||||
return e.compose.Stop(ctx, project, options)
|
return e.compose.Stop(ctx, project, options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,10 @@ func (b *ecsAPIService) Start(ctx context.Context, project *types.Project, optio
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *ecsAPIService) Restart(ctx context.Context, project *types.Project, options compose.RestartOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (b *ecsAPIService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
func (b *ecsAPIService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,6 +188,11 @@ func (s *composeService) Start(ctx context.Context, project *types.Project, opti
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart executes the equivalent to a `compose restart`
|
||||||
|
func (s *composeService) Restart(ctx context.Context, project *types.Project, options compose.RestartOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// Stop executes the equivalent to a `compose stop`
|
// Stop executes the equivalent to a `compose stop`
|
||||||
func (s *composeService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
func (s *composeService) Stop(ctx context.Context, project *types.Project, options compose.StopOptions) error {
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
|
|
|
@ -390,3 +390,26 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
|
||||||
}
|
}
|
||||||
return eg.Wait()
|
return eg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *composeService) restartService(ctx context.Context, serviceName string, timeout *time.Duration) error {
|
||||||
|
containerState, err := GetContextContainerState(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
containers := containerState.GetContainers().filter(isService(serviceName))
|
||||||
|
w := progress.ContextWriter(ctx)
|
||||||
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
for _, c := range containers {
|
||||||
|
container := c
|
||||||
|
eg.Go(func() error {
|
||||||
|
eventName := getContainerProgressName(container)
|
||||||
|
w.Event(progress.RestartingEvent(eventName))
|
||||||
|
err := s.apiClient.ContainerRestart(ctx, container.ID, timeout)
|
||||||
|
if err == nil {
|
||||||
|
w.Event(progress.StartedEvent(eventName))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return eg.Wait()
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
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/compose"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *composeService) Restart(ctx context.Context, project *types.Project, options compose.RestartOptions) error {
|
||||||
|
ctx, err := s.getUpdatedContainersStateContext(ctx, project.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = InDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error {
|
||||||
|
return s.restartService(ctx, service.Name, options.Timeout)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -100,3 +101,17 @@ func GetContextContainerState(ctx context.Context) (ContainersState, error) {
|
||||||
}
|
}
|
||||||
return cState, nil
|
return cState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s composeService) getUpdatedContainersStateContext(ctx context.Context, projectName string) (context.Context, error) {
|
||||||
|
observedState, err := s.apiClient.ContainerList(ctx, types.ContainerListOptions{
|
||||||
|
Filters: filters.NewArgs(
|
||||||
|
projectFilter(projectName),
|
||||||
|
),
|
||||||
|
All: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
containerState := NewContainersState(observedState)
|
||||||
|
return context.WithValue(ctx, ContainersKey{}, containerState), nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue