Allow to checkpoint and restore a container with console
runc already supports this case, so we just need to run it with proper options. Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
0846d6f8e9
commit
60daa414db
@ -69,7 +69,13 @@ func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Consol
|
|||||||
// NewTask creates a new task
|
// NewTask creates a new task
|
||||||
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, tty, nullIO bool, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
|
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, tty, nullIO bool, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
|
||||||
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
|
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
|
||||||
if checkpoint == "" {
|
if checkpoint != "" {
|
||||||
|
im, err := client.GetImage(ctx, checkpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
opts = append(opts, containerd.WithTaskCheckpoint(im))
|
||||||
|
}
|
||||||
ioCreator := stdio
|
ioCreator := stdio
|
||||||
if tty {
|
if tty {
|
||||||
ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStdio, cio.WithTerminal}, ioOpts...)...)
|
ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStdio, cio.WithTerminal}, ioOpts...)...)
|
||||||
@ -82,13 +88,6 @@ func NewTask(ctx gocontext.Context, client *containerd.Client, container contain
|
|||||||
}
|
}
|
||||||
return container.NewTask(ctx, ioCreator, opts...)
|
return container.NewTask(ctx, ioCreator, opts...)
|
||||||
}
|
}
|
||||||
im, err := client.GetImage(ctx, checkpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
opts = append(opts, containerd.WithTaskCheckpoint(im))
|
|
||||||
return container.NewTask(ctx, stdio, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNewTaskOpts(context *cli.Context) []containerd.NewTaskOpts {
|
func getNewTaskOpts(context *cli.Context) []containerd.NewTaskOpts {
|
||||||
if context.Bool("no-pivot") {
|
if context.Bool("no-pivot") {
|
||||||
|
@ -194,10 +194,23 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
|||||||
s.p.mu.Lock()
|
s.p.mu.Lock()
|
||||||
defer s.p.mu.Unlock()
|
defer s.p.mu.Unlock()
|
||||||
p := s.p
|
p := s.p
|
||||||
|
sio := p.stdio
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
socket *runc.Socket
|
||||||
|
)
|
||||||
|
if sio.Terminal {
|
||||||
|
if socket, err = runc.NewTempConsoleSocket(); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to create OCI runtime console socket")
|
||||||
|
}
|
||||||
|
defer socket.Close()
|
||||||
|
s.opts.ConsoleSocket = socket
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := s.p.runtime.Restore(ctx, p.id, p.bundle, s.opts); err != nil {
|
if _, err := s.p.runtime.Restore(ctx, p.id, p.bundle, s.opts); err != nil {
|
||||||
return p.runtimeError(err, "OCI runtime restore failed")
|
return p.runtimeError(err, "OCI runtime restore failed")
|
||||||
}
|
}
|
||||||
sio := p.stdio
|
|
||||||
if sio.Stdin != "" {
|
if sio.Stdin != "" {
|
||||||
sc, err := fifo.OpenFifo(ctx, sio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
sc, err := fifo.OpenFifo(ctx, sio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -207,7 +220,17 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
|||||||
p.closers = append(p.closers, sc)
|
p.closers = append(p.closers, sc)
|
||||||
}
|
}
|
||||||
var copyWaitGroup sync.WaitGroup
|
var copyWaitGroup sync.WaitGroup
|
||||||
if !sio.IsNull() {
|
if socket != nil {
|
||||||
|
console, err := socket.ReceiveMaster()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to retrieve console master")
|
||||||
|
}
|
||||||
|
console, err = p.platform.CopyConsole(ctx, console, sio.Stdin, sio.Stdout, sio.Stderr, &p.wg, ©WaitGroup)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to start console copy")
|
||||||
|
}
|
||||||
|
p.console = console
|
||||||
|
} else if !sio.IsNull() {
|
||||||
if err := copyPipes(ctx, p.io, sio.Stdin, sio.Stdout, sio.Stderr, &p.wg, ©WaitGroup); err != nil {
|
if err := copyPipes(ctx, p.io, sio.Stdin, sio.Stdout, sio.Stderr, &p.wg, ©WaitGroup); err != nil {
|
||||||
return errors.Wrap(err, "failed to start io pipe copy")
|
return errors.Wrap(err, "failed to start io pipe copy")
|
||||||
}
|
}
|
||||||
@ -219,7 +242,6 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
|||||||
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
||||||
}
|
}
|
||||||
p.pid = pid
|
p.pid = pid
|
||||||
|
|
||||||
return s.transition("running")
|
return s.transition("running")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user