Merge pull request #29099 from dattatrayakumbhar/28755_Err_Duplicate_checkpoint
#28755: [experimental] Proper error handling for checkpoint conflict
This commit is contained in:
commit
6b06cc54d0
1 changed files with 46 additions and 21 deletions
|
@ -16,6 +16,41 @@ var (
|
||||||
validCheckpointNamePattern = api.RestrictedNamePattern
|
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
|
// CheckpointCreate checkpoints the process running in a container with CRIU
|
||||||
func (daemon *Daemon) CheckpointCreate(name string, config types.CheckpointCreateOptions) error {
|
func (daemon *Daemon) CheckpointCreate(name string, config types.CheckpointCreateOptions) error {
|
||||||
container, err := daemon.GetContainer(name)
|
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)
|
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) {
|
if !validCheckpointNamePattern.MatchString(config.CheckpointID) {
|
||||||
return fmt.Errorf("Invalid checkpoint ID (%s), only %s are allowed", config.CheckpointID, validCheckpointNameChars)
|
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)
|
err = daemon.containerd.CreateCheckpoint(container.ID, config.CheckpointID, checkpointDir, config.Exit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Cannot checkpoint container %s: %s", name, err)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
checkpointDir, err := getCheckpointDir(config.CheckpointDir, config.CheckpointID, name, container.ID, container.CheckpointDir(), false)
|
||||||
var checkpointDir string
|
if err == nil {
|
||||||
if config.CheckpointDir != "" {
|
|
||||||
checkpointDir = config.CheckpointDir
|
|
||||||
} else {
|
|
||||||
checkpointDir = container.CheckpointDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// CheckpointList lists all checkpoints of the specified container
|
||||||
|
@ -74,12 +104,7 @@ func (daemon *Daemon) CheckpointList(name string, config types.CheckpointListOpt
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkpointDir string
|
checkpointDir, err := getCheckpointDir(config.CheckpointDir, "", name, container.ID, container.CheckpointDir(), true)
|
||||||
if config.CheckpointDir != "" {
|
|
||||||
checkpointDir = config.CheckpointDir
|
|
||||||
} else {
|
|
||||||
checkpointDir = container.CheckpointDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(checkpointDir, 0755); err != nil {
|
if err := os.MkdirAll(checkpointDir, 0755); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in a new issue