|
@@ -16,6 +16,41 @@ var (
|
|
|
validCheckpointNamePattern = api.RestrictedNamePattern
|
|
|
)
|
|
|
|
|
|
+// getCheckpointDir verifies checkpoint directory for create,remove, list options and checks if checkpoint already exists
|
|
|
+func getCheckpointDir(checkDir, checkpointID string, ctrName string, ctrID string, ctrCheckpointDir string, create bool) (string, error) {
|
|
|
+ var checkpointDir string
|
|
|
+ var err2 error
|
|
|
+ if checkDir != "" {
|
|
|
+ checkpointDir = filepath.Join(checkDir, ctrID, "checkpoints")
|
|
|
+ } else {
|
|
|
+ checkpointDir = ctrCheckpointDir
|
|
|
+ }
|
|
|
+ checkpointAbsDir := filepath.Join(checkpointDir, checkpointID)
|
|
|
+ stat, err := os.Stat(checkpointAbsDir)
|
|
|
+ if create {
|
|
|
+ switch {
|
|
|
+ case err == nil && stat.IsDir():
|
|
|
+ err2 = fmt.Errorf("checkpoint with name %s already exists for container %s", checkpointID, ctrName)
|
|
|
+ case err != nil && os.IsNotExist(err):
|
|
|
+ err2 = nil
|
|
|
+ case err != nil:
|
|
|
+ err2 = err
|
|
|
+ case err == nil:
|
|
|
+ err2 = fmt.Errorf("%s exists and is not a directory", checkpointAbsDir)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ switch {
|
|
|
+ case err != nil:
|
|
|
+ err2 = fmt.Errorf("checkpoint %s does not exists for container %s", checkpointID, ctrName)
|
|
|
+ case err == nil && stat.IsDir():
|
|
|
+ err2 = nil
|
|
|
+ case err == nil:
|
|
|
+ err2 = fmt.Errorf("%s exists and is not a directory", checkpointAbsDir)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return checkpointDir, err2
|
|
|
+}
|
|
|
+
|
|
|
// CheckpointCreate checkpoints the process running in a container with CRIU
|
|
|
func (daemon *Daemon) CheckpointCreate(name string, config types.CheckpointCreateOptions) error {
|
|
|
container, err := daemon.GetContainer(name)
|
|
@@ -27,17 +62,16 @@ func (daemon *Daemon) CheckpointCreate(name string, config types.CheckpointCreat
|
|
|
return fmt.Errorf("Container %s not running", name)
|
|
|
}
|
|
|
|
|
|
- var checkpointDir string
|
|
|
- if config.CheckpointDir != "" {
|
|
|
- checkpointDir = config.CheckpointDir
|
|
|
- } else {
|
|
|
- checkpointDir = container.CheckpointDir()
|
|
|
- }
|
|
|
-
|
|
|
if !validCheckpointNamePattern.MatchString(config.CheckpointID) {
|
|
|
return fmt.Errorf("Invalid checkpoint ID (%s), only %s are allowed", config.CheckpointID, validCheckpointNameChars)
|
|
|
}
|
|
|
|
|
|
+ checkpointDir, err := getCheckpointDir(config.CheckpointDir, config.CheckpointID, name, container.ID, container.CheckpointDir(), true)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("cannot checkpoint container %s: %s", name, err)
|
|
|
+ }
|
|
|
+
|
|
|
err = daemon.containerd.CreateCheckpoint(container.ID, config.CheckpointID, checkpointDir, config.Exit)
|
|
|
if err != nil {
|
|
|
return fmt.Errorf("Cannot checkpoint container %s: %s", name, err)
|
|
@@ -54,15 +88,11 @@ func (daemon *Daemon) CheckpointDelete(name string, config types.CheckpointDelet
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
-
|
|
|
- var checkpointDir string
|
|
|
- if config.CheckpointDir != "" {
|
|
|
- checkpointDir = config.CheckpointDir
|
|
|
- } else {
|
|
|
- checkpointDir = container.CheckpointDir()
|
|
|
+ checkpointDir, err := getCheckpointDir(config.CheckpointDir, config.CheckpointID, name, container.ID, container.CheckpointDir(), false)
|
|
|
+ if err == nil {
|
|
|
+ return os.RemoveAll(filepath.Join(checkpointDir, config.CheckpointID))
|
|
|
}
|
|
|
-
|
|
|
- return os.RemoveAll(filepath.Join(checkpointDir, config.CheckpointID))
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
// CheckpointList lists all checkpoints of the specified container
|
|
@@ -74,12 +104,7 @@ func (daemon *Daemon) CheckpointList(name string, config types.CheckpointListOpt
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- var checkpointDir string
|
|
|
- if config.CheckpointDir != "" {
|
|
|
- checkpointDir = config.CheckpointDir
|
|
|
- } else {
|
|
|
- checkpointDir = container.CheckpointDir()
|
|
|
- }
|
|
|
+ checkpointDir, err := getCheckpointDir(config.CheckpointDir, "", name, container.ID, container.CheckpointDir(), true)
|
|
|
|
|
|
if err := os.MkdirAll(checkpointDir, 0755); err != nil {
|
|
|
return nil, err
|