switchstatus{// 对于一个已经处于Created状态的容器,执行Exec
caselibcontainer.Created:returncontainer.Exec()caselibcontainer.Stopped:returnerrors.New("cannot start a container that has stopped")caselibcontainer.Running:returnerrors.New("cannot start an already running container")default:returnfmt.Errorf("cannot start a container in the %s state\n",status)}
funcstartContainer(ctxcontext.Context,containercontainerd.Container,flagAbool,client*containerd.Client)error{......ifoldTask,err:=container.Task(ctx,nil);err==nil{if_,err:=oldTask.Delete(ctx);err!=nil{logrus.WithError(err).Debug("failed to delete old task")}}task,err:=container.NewTask(ctx,taskCIO)iferr!=nil{returnerr}......iferr:=task.Start(ctx);err!=nil{returnerr}......}
func(p*Init)delete(ctxcontext.Context)error{waitTimeout(ctx,&p.wg,2*time.Second)// 1 runc delete
err:=p.runtime.Delete(ctx,p.id,nil)// ignore errors if a runtime has already deleted the process
// but we still hold metadata and pipes
//
// this is common during a checkpoint, runc will delete the container state
// after a checkpoint and the container will no longer exist within runc
iferr!=nil{ifstrings.Contains(err.Error(),"does not exist"){err=nil}else{err=p.runtimeError(err,"failed to delete task")}}ifp.io!=nil{for_,c:=rangep.closers{c.Close()}p.io.Close()}// 取消rootfs挂载
iferr2:=mount.UnmountAll(p.Rootfs,0);err2!=nil{log.G(ctx).WithError(err2).Warn("failed to cleanup rootfs mount")iferr==nil{err=fmt.Errorf("failed rootfs umount: %w",err2)}}returnerr}
通过runc删除容器
1
err:=p.runtime.Delete(ctx,p.id,nil)
取消rootfs挂载
1
2
3
4
5
6
iferr2:=mount.UnmountAll(p.Rootfs,0);err2!=nil{log.G(ctx).WithError(err2).Warn("failed to cleanup rootfs mount")iferr==nil{err=fmt.Errorf("failed rootfs umount: %w",err2)}}