mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	daemon: daemon.ContainerKill() accept stop-signal as string
This allows the postContainersKill() handler to pass values as-is. As part of the rewrite, I also moved the daemon.GetContainer(name) call later in the function, so that we can fail early if an invalid signal is passed, before doing the (heavier) fetching of the container. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
		
							parent
							
								
									521807837b
								
							
						
					
					
						commit
						d733481399
					
				
					 9 changed files with 26 additions and 30 deletions
				
			
		| 
						 | 
				
			
			@ -33,7 +33,7 @@ type copyBackend interface {
 | 
			
		|||
// stateBackend includes functions to implement to provide container state lifecycle functionality.
 | 
			
		||||
type stateBackend interface {
 | 
			
		||||
	ContainerCreate(config types.ContainerCreateConfig) (container.CreateResponse, error)
 | 
			
		||||
	ContainerKill(name string, sig uint64) error
 | 
			
		||||
	ContainerKill(name string, signal string) error
 | 
			
		||||
	ContainerPause(name string) error
 | 
			
		||||
	ContainerRename(oldName, newName string) error
 | 
			
		||||
	ContainerResize(name string, height, width int) error
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,6 @@ import (
 | 
			
		|||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/containerd/containerd/platforms"
 | 
			
		||||
	"github.com/docker/docker/api/server/httpstatus"
 | 
			
		||||
| 
						 | 
				
			
			@ -254,18 +253,8 @@ func (s *containerRouter) postContainersKill(ctx context.Context, w http.Respons
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var sig syscall.Signal
 | 
			
		||||
	name := vars["name"]
 | 
			
		||||
 | 
			
		||||
	// If we have a signal, look at it. Otherwise, do nothing
 | 
			
		||||
	if sigStr := r.Form.Get("signal"); sigStr != "" {
 | 
			
		||||
		var err error
 | 
			
		||||
		if sig, err = signal.ParseSignal(sigStr); err != nil {
 | 
			
		||||
			return errdefs.InvalidParameter(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := s.backend.ContainerKill(name, uint64(sig)); err != nil {
 | 
			
		||||
	if err := s.backend.ContainerKill(name, r.Form.Get("signal")); err != nil {
 | 
			
		||||
		var isStopped bool
 | 
			
		||||
		if errdefs.IsConflict(err) {
 | 
			
		||||
			isStopped = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ type ExecBackend interface {
 | 
			
		|||
	// ContainerRm removes a container specified by `id`.
 | 
			
		||||
	ContainerRm(name string, config *types.ContainerRmConfig) error
 | 
			
		||||
	// ContainerKill stops the container execution abruptly.
 | 
			
		||||
	ContainerKill(containerID string, sig uint64) error
 | 
			
		||||
	ContainerKill(containerID string, sig string) error
 | 
			
		||||
	// ContainerStart starts a new container
 | 
			
		||||
	ContainerStart(containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
 | 
			
		||||
	// ContainerWait stops processing until the given container is stopped.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ func (c *containerManager) Run(ctx context.Context, cID string, stdout, stderr i
 | 
			
		|||
		select {
 | 
			
		||||
		case <-ctx.Done():
 | 
			
		||||
			logrus.Debugln("Build cancelled, killing and removing container:", cID)
 | 
			
		||||
			c.backend.ContainerKill(cID, 0)
 | 
			
		||||
			c.backend.ContainerKill(cID, "")
 | 
			
		||||
			c.removeContainer(cID, stdout)
 | 
			
		||||
			cancelErrCh <- errCancelled
 | 
			
		||||
		case <-finished:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ func (m *MockBackend) CommitBuildStep(c backend.CommitConfig) (image.ID, error)
 | 
			
		|||
	return "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MockBackend) ContainerKill(containerID string, sig uint64) error {
 | 
			
		||||
func (m *MockBackend) ContainerKill(containerID string, sig string) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,7 @@ func (l *mockLayer) NewRWLayer() (builder.RWLayer, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (l *mockLayer) DiffID() layer.DiffID {
 | 
			
		||||
	return layer.DiffID("abcdef")
 | 
			
		||||
	return "abcdef"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mockRWLayer struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ type Backend interface {
 | 
			
		|||
	ContainerInspectCurrent(name string, size bool) (*types.ContainerJSON, error)
 | 
			
		||||
	ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error)
 | 
			
		||||
	ContainerRm(name string, config *types.ContainerRmConfig) error
 | 
			
		||||
	ContainerKill(name string, sig uint64) error
 | 
			
		||||
	ContainerKill(name string, sig string) error
 | 
			
		||||
	SetContainerDependencyStore(name string, store exec.DependencyGetter) error
 | 
			
		||||
	SetContainerSecretReferences(name string, refs []*swarmtypes.SecretReference) error
 | 
			
		||||
	SetContainerConfigReferences(name string, refs []*swarmtypes.ConfigReference) error
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -417,7 +417,7 @@ func (c *containerAdapter) shutdown(ctx context.Context) error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (c *containerAdapter) terminate(ctx context.Context) error {
 | 
			
		||||
	return c.backend.ContainerKill(c.container.name(), uint64(syscall.SIGKILL))
 | 
			
		||||
	return c.backend.ContainerKill(c.container.name(), syscall.SIGKILL.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *containerAdapter) remove(ctx context.Context) error {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,22 +34,29 @@ func isErrNoSuchProcess(err error) bool {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// ContainerKill sends signal to the container
 | 
			
		||||
// If no signal is given (sig 0), then Kill with SIGKILL and wait
 | 
			
		||||
// If no signal is given, then Kill with SIGKILL and wait
 | 
			
		||||
// for the container to exit.
 | 
			
		||||
// If a signal is given, then just send it to the container and return.
 | 
			
		||||
func (daemon *Daemon) ContainerKill(name string, stopSignal uint64) error {
 | 
			
		||||
	sig := syscall.Signal(stopSignal)
 | 
			
		||||
func (daemon *Daemon) ContainerKill(name, stopSignal string) error {
 | 
			
		||||
	var (
 | 
			
		||||
		err error
 | 
			
		||||
		sig = syscall.SIGKILL
 | 
			
		||||
	)
 | 
			
		||||
	if stopSignal != "" {
 | 
			
		||||
		sig, err = signal.ParseSignal(stopSignal)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return errdefs.InvalidParameter(err)
 | 
			
		||||
		}
 | 
			
		||||
		if !signal.ValidSignalForPlatform(sig) {
 | 
			
		||||
			return errdefs.InvalidParameter(errors.Errorf("the %s daemon does not support signal %d", runtime.GOOS, sig))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	container, err := daemon.GetContainer(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if sig != 0 && !signal.ValidSignalForPlatform(sig) {
 | 
			
		||||
		return fmt.Errorf("The %s daemon does not support signal %d", runtime.GOOS, sig)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
 | 
			
		||||
	if sig == 0 || sig == syscall.SIGKILL {
 | 
			
		||||
	if sig == syscall.SIGKILL {
 | 
			
		||||
		// perform regular Kill (SIGKILL + wait())
 | 
			
		||||
		return daemon.Kill(container)
 | 
			
		||||
	}
 | 
			
		||||
	return daemon.killWithSignal(container, sig)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -688,7 +688,7 @@ func (c *client) Exec(ctx context.Context, containerID, processID string, spec *
 | 
			
		|||
// SignalProcess handles `docker stop` on Windows. While Linux has support for
 | 
			
		||||
// the full range of signals, signals aren't really implemented on Windows.
 | 
			
		||||
// We fake supporting regular stop and -9 to force kill.
 | 
			
		||||
func (c *client) SignalProcess(_ context.Context, containerID, processID string, signal int) error {
 | 
			
		||||
func (c *client) SignalProcess(_ context.Context, containerID, processID string, signal syscall.Signal) error {
 | 
			
		||||
	ctr, p, err := c.getProcess(containerID, processID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue