diff --git a/api/v1/server.go b/api/v1/server.go index 0301ba3..2e83595 100644 --- a/api/v1/server.go +++ b/api/v1/server.go @@ -61,6 +61,9 @@ func (s *server) updateContainer(w http.ResponseWriter, r *http.Request) { } e := containerd.NewEvent(containerd.UpdateContainerEventType) e.ID = id + if state.Signal != 0 { + e.Signal = syscall.Signal(state.Signal) + } e.State = &runtime.State{ Status: runtime.Status(string(state.Status)), } diff --git a/api/v1/types.go b/api/v1/types.go index d841f16..0c7acb2 100644 --- a/api/v1/types.go +++ b/api/v1/types.go @@ -19,6 +19,7 @@ type Machine struct { type ContainerState struct { Status Status `json:"status,omitempty"` + Signal int `json:"signal,omitempty"` } type Container struct { diff --git a/linux/linux.go b/linux/linux.go index a605286..c8555af 100644 --- a/linux/linux.go +++ b/linux/linux.go @@ -225,7 +225,14 @@ func (c *libcontainerContainer) getCheckpointPath(name string) string { func (c *libcontainerContainer) Checkpoint(cp runtime.Checkpoint) error { opts := c.createCheckpointOpts(cp) - if err := os.MkdirAll(opts.ImagesDirectory, 0755); err != nil { + if err := os.MkdirAll(filepath.Dir(opts.ImagesDirectory), 0755); err != nil { + return err + } + // mkdir is atomic so if it already exists we can fail + if err := os.Mkdir(opts.ImagesDirectory, 0755); err != nil { + if os.IsExist(err) { + return runtime.ErrCheckpointExists + } return err } if err := c.c.Checkpoint(opts); err != nil { diff --git a/runtime/runtime.go b/runtime/runtime.go index 230239d..b92861a 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -10,6 +10,7 @@ var ( ErrNotChildProcess = errors.New("containerd: not a child process for container") ErrInvalidContainerType = errors.New("containerd: invalid container type for runtime") ErrCheckpointNotExists = errors.New("containerd: checkpoint does not exist for container") + ErrCheckpointExists = errors.New("containerd: checkpoint already exists") ) // runtime handles containers, containers handle their own actions. diff --git a/update.go b/update.go index ea121ee..f27cbc3 100644 --- a/update.go +++ b/update.go @@ -25,5 +25,16 @@ func (h *UpdateEvent) Handle(e *Event) error { return ErrUnknownContainerStatus } } + if e.Signal != nil { + // signal the pid1/main process of the container + processes, err := container.Processes() + if err != nil { + return err + } + if len(processes) == 0 { + return ErrProcessNotFound + } + return processes[0].Signal(e.Signal) + } return nil }