mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
Add --ignore-rootfs option for checkpoint/restore
The newly added functionality to include the container's root file-system changes into the checkpoint archive can now be explicitly disabled. Either during checkpoint or during restore. If a container changes a lot of files during its runtime it might be more effective to migrated the root file-system changes in some other way and to not needlessly increase the size of the checkpoint archive. If a checkpoint archive does not contain the root file-system changes information it will automatically be skipped. If the root file-system changes are part of the checkpoint archive it is also possible to tell Podman to ignore these changes. Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
@ -46,6 +46,7 @@ func init() {
|
||||
flags.BoolVarP(&checkpointCommand.All, "all", "a", false, "Checkpoint all running containers")
|
||||
flags.BoolVarP(&checkpointCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
|
||||
flags.StringVarP(&checkpointCommand.Export, "export", "e", "", "Export the checkpoint image to a tar.gz")
|
||||
flags.BoolVar(&checkpointCommand.IgnoreRootfs, "ignore-rootfs", false, "Do not include root file-system changes when exporting")
|
||||
markFlagHiddenForRemoteClient("latest", flags)
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ type CheckpointValues struct {
|
||||
All bool
|
||||
Latest bool
|
||||
Export string
|
||||
IgnoreRootfs bool
|
||||
}
|
||||
|
||||
type CommitValues struct {
|
||||
@ -433,6 +434,7 @@ type RestoreValues struct {
|
||||
TcpEstablished bool
|
||||
Import string
|
||||
Name string
|
||||
IgnoreRootfs bool
|
||||
}
|
||||
|
||||
type RmValues struct {
|
||||
|
@ -45,6 +45,7 @@ func init() {
|
||||
flags.BoolVar(&restoreCommand.TcpEstablished, "tcp-established", false, "Restore a container with established TCP connections")
|
||||
flags.StringVarP(&restoreCommand.Import, "import", "i", "", "Restore from exported checkpoint archive (tar.gz)")
|
||||
flags.StringVarP(&restoreCommand.Name, "name", "n", "", "Specify new name for container restored from exported checkpoint (only works with --import)")
|
||||
flags.BoolVar(&restoreCommand.IgnoreRootfs, "ignore-rootfs", false, "Do not apply root file-system changes when importing from exported checkpoint")
|
||||
|
||||
markFlagHiddenForRemoteClient("latest", flags)
|
||||
}
|
||||
@ -60,6 +61,10 @@ func restoreCmd(c *cliconfig.RestoreValues, cmd *cobra.Command) error {
|
||||
}
|
||||
defer runtime.DeferredShutdown(false)
|
||||
|
||||
if c.Import == "" && c.IgnoreRootfs {
|
||||
return errors.Errorf("--ignore-rootfs can only be used with --import")
|
||||
}
|
||||
|
||||
if c.Import == "" && c.Name != "" {
|
||||
return errors.Errorf("--name can only be used with --import")
|
||||
}
|
||||
|
@ -758,6 +758,7 @@ _podman_container_checkpoint() {
|
||||
-R
|
||||
--leave-running
|
||||
--tcp-established
|
||||
--ignore-rootfs
|
||||
"
|
||||
case "$prev" in
|
||||
-e|--export)
|
||||
@ -870,6 +871,7 @@ _podman_container_restore() {
|
||||
-l
|
||||
--latest
|
||||
--tcp-established
|
||||
--ignore-rootfs
|
||||
"
|
||||
case "$prev" in
|
||||
-i|--import)
|
||||
|
@ -42,7 +42,15 @@ connections.
|
||||
|
||||
Export the checkpoint to a tar.gz file. The exported checkpoint can be used
|
||||
to import the container on another system and thus enabling container live
|
||||
migration.
|
||||
migration. This checkpoint archive also includes all changes to the container's
|
||||
root file-system, if not explicitly disabled using **--ignore-rootfs**
|
||||
|
||||
**--ignore-rootfs**
|
||||
|
||||
This only works in combination with **--export, -e**. If a checkpoint is
|
||||
exported to a tar.gz file it is possible with the help of **--ignore-rootfs**
|
||||
to explicitly disable including changes to the root file-system into
|
||||
the checkpoint archive file.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
|
@ -60,6 +60,13 @@ address to the container it was using before checkpointing as each IP address ca
|
||||
be used once and the restored container will have another IP address. This also means
|
||||
that **--name, -n** cannot be used in combination with **--tcp-established**.
|
||||
|
||||
**--ignore-rootfs**
|
||||
|
||||
This is only available in combination with **--import, -i**. If a container is restored
|
||||
from a checkpoint tar.gz file it is possible that it also contains all root file-system
|
||||
changes. With **--ignore-rootfs** it is possible to explicitly disable applying these
|
||||
root file-system changes to the restored container.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
podman container restore mywebserver
|
||||
|
@ -799,6 +799,9 @@ type ContainerCheckpointOptions struct {
|
||||
// checkpoint archive a new name should be used for the
|
||||
// restored container
|
||||
Name string
|
||||
// IgnoreRootfs tells the API to not export changes to
|
||||
// the container's root file-system (or to not import)
|
||||
IgnoreRootfs bool
|
||||
}
|
||||
|
||||
// Checkpoint checkpoints a container
|
||||
|
@ -510,14 +510,23 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) exportCheckpoint(dest string) (err error) {
|
||||
func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) (err error) {
|
||||
if (len(c.config.NamedVolumes) > 0) || (len(c.Dependencies()) > 0) {
|
||||
return errors.Errorf("Cannot export checkpoints of containers with named volumes or dependencies")
|
||||
}
|
||||
logrus.Debugf("Exporting checkpoint image of container %q to %q", c.ID(), dest)
|
||||
|
||||
includeFiles := []string{
|
||||
"checkpoint",
|
||||
"artifacts",
|
||||
"ctr.log",
|
||||
"config.dump",
|
||||
"spec.dump",
|
||||
"network.status"}
|
||||
|
||||
// Get root file-system changes included in the checkpoint archive
|
||||
rootfsDiffPath := filepath.Join(c.bundlePath(), "rootfs-diff.tar")
|
||||
if !ignoreRootfs {
|
||||
rootfsDiffFile, err := os.Create(rootfsDiffPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating root file-system diff file %q", rootfsDiffPath)
|
||||
@ -532,19 +541,13 @@ func (c *Container) exportCheckpoint(dest string) (err error) {
|
||||
}
|
||||
tarStream.Close()
|
||||
rootfsDiffFile.Close()
|
||||
|
||||
includeFiles = append(includeFiles, "rootfs-diff.tar")
|
||||
}
|
||||
|
||||
input, err := archive.TarWithOptions(c.bundlePath(), &archive.TarOptions{
|
||||
Compression: archive.Gzip,
|
||||
IncludeSourceDir: true,
|
||||
IncludeFiles: []string{
|
||||
"checkpoint",
|
||||
"artifacts",
|
||||
"ctr.log",
|
||||
"config.dump",
|
||||
"spec.dump",
|
||||
"rootfs-diff.tar",
|
||||
"network.status"},
|
||||
IncludeFiles: includeFiles,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@ -627,7 +630,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
|
||||
}
|
||||
|
||||
if options.TargetFile != "" {
|
||||
if err = c.exportCheckpoint(options.TargetFile); err != nil {
|
||||
if err = c.exportCheckpoint(options.TargetFile, options.IgnoreRootfs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -816,6 +819,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
|
||||
}
|
||||
|
||||
// Before actually restarting the container, apply the root file-system changes
|
||||
if !options.IgnoreRootfs {
|
||||
rootfsDiffPath := filepath.Join(c.bundlePath(), "rootfs-diff.tar")
|
||||
if _, err := os.Stat(rootfsDiffPath); err == nil {
|
||||
// Only do this if a rootfs-diff.tar actually exists
|
||||
@ -828,6 +832,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
|
||||
}
|
||||
rootfsDiffFile.Close()
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.ociRuntime.createContainer(c, c.config.CgroupParent, &options); err != nil {
|
||||
return err
|
||||
|
@ -524,6 +524,10 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error {
|
||||
KeepRunning: c.LeaveRunning,
|
||||
TCPEstablished: c.TcpEstablished,
|
||||
TargetFile: c.Export,
|
||||
IgnoreRootfs: c.IgnoreRootfs,
|
||||
}
|
||||
if c.Export == "" && c.IgnoreRootfs {
|
||||
return errors.Errorf("--ignore-rootfs can only be used with --export")
|
||||
}
|
||||
if c.All {
|
||||
containers, err = r.Runtime.GetRunningContainers()
|
||||
@ -560,6 +564,7 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues)
|
||||
TCPEstablished: c.TcpEstablished,
|
||||
TargetFile: c.Import,
|
||||
Name: c.Name,
|
||||
IgnoreRootfs: c.IgnoreRootfs,
|
||||
}
|
||||
|
||||
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
|
||||
|
@ -668,6 +668,9 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error {
|
||||
if c.Export != "" {
|
||||
return errors.New("the remote client does not support exporting checkpoints")
|
||||
}
|
||||
if c.IgnoreRootfs {
|
||||
return errors.New("the remote client does not support --ignore-rootfs")
|
||||
}
|
||||
|
||||
var lastError error
|
||||
ids, err := iopodman.GetContainersByContext().Call(r.Conn, c.All, c.Latest, c.InputArgs)
|
||||
@ -708,6 +711,9 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues)
|
||||
if c.Import != "" {
|
||||
return errors.New("the remote client does not support importing checkpoints")
|
||||
}
|
||||
if c.IgnoreRootfs {
|
||||
return errors.New("the remote client does not support --ignore-rootfs")
|
||||
}
|
||||
|
||||
var lastError error
|
||||
ids, err := iopodman.GetContainersByContext().Call(r.Conn, c.All, c.Latest, c.InputArgs)
|
||||
|
Reference in New Issue
Block a user