mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
|
// +build experimental
|
||
|
|
||
|
package libcontainerd
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/Sirupsen/logrus"
|
||
|
containerd "github.com/docker/containerd/api/grpc/types"
|
||
|
)
|
||
|
|
||
|
func (clnt *client) restore(cont *containerd.Container, options ...CreateOption) (err error) {
|
||
|
clnt.lock(cont.Id)
|
||
|
defer clnt.unlock(cont.Id)
|
||
|
|
||
|
logrus.Debugf("restore container %s state %s", cont.Id, cont.Status)
|
||
|
|
||
|
containerID := cont.Id
|
||
|
if _, err := clnt.getContainer(containerID); err == nil {
|
||
|
return fmt.Errorf("container %s is aleady active", containerID)
|
||
|
}
|
||
|
|
||
|
defer func() {
|
||
|
if err != nil {
|
||
|
clnt.deleteContainer(cont.Id)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
container := clnt.newContainer(cont.BundlePath, options...)
|
||
|
container.systemPid = systemPid(cont)
|
||
|
|
||
|
var terminal bool
|
||
|
for _, p := range cont.Processes {
|
||
|
if p.Pid == InitFriendlyName {
|
||
|
terminal = p.Terminal
|
||
|
}
|
||
|
}
|
||
|
|
||
|
iopipe, err := container.openFifos(terminal)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err := clnt.backend.AttachStreams(containerID, *iopipe); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
clnt.appendContainer(container)
|
||
|
|
||
|
err = clnt.backend.StateChanged(containerID, StateInfo{
|
||
|
State: StateRestore,
|
||
|
Pid: container.systemPid,
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if event, ok := clnt.remote.pastEvents[containerID]; ok {
|
||
|
// This should only be a pause or resume event
|
||
|
if event.Type == StatePause || event.Type == StateResume {
|
||
|
return clnt.backend.StateChanged(containerID, StateInfo{
|
||
|
State: event.Type,
|
||
|
Pid: container.systemPid,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
logrus.Warnf("unexpected backlog event: %#v", event)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (clnt *client) Restore(containerID string, options ...CreateOption) error {
|
||
|
cont, err := clnt.getContainerdContainer(containerID)
|
||
|
if err == nil && cont.Status != "stopped" {
|
||
|
if err := clnt.restore(cont, options...); err != nil {
|
||
|
logrus.Errorf("error restoring %s: %v", containerID, err)
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
return clnt.setExited(containerID)
|
||
|
}
|