mirror of
https://github.com/containers/podman.git
synced 2025-06-22 01:48:54 +08:00
Merge pull request #10567 from adrianreber/2021-06-04-compress
Add support for selectable checkpoint archive compression algorithm
This commit is contained in:
@ -1211,3 +1211,10 @@ func AutocompleteVolumeFilters(cmd *cobra.Command, args []string, toComplete str
|
||||
}
|
||||
return completeKeyValues(toComplete, kv)
|
||||
}
|
||||
|
||||
// AutocompleteCheckpointCompressType - Autocomplete checkpoint compress type options.
|
||||
// -> "gzip", "none", "zstd"
|
||||
func AutocompleteCheckpointCompressType(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
types := []string{"gzip", "none", "zstd"}
|
||||
return types, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package containers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/common/pkg/completion"
|
||||
"github.com/containers/podman/v3/cmd/podman/common"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||
"github.com/containers/podman/v3/pkg/rootless"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -36,9 +38,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
checkpointOptions entities.CheckpointOptions
|
||||
)
|
||||
var checkpointOptions entities.CheckpointOptions
|
||||
|
||||
func init() {
|
||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||
@ -60,11 +60,32 @@ func init() {
|
||||
flags.BoolVarP(&checkpointOptions.PreCheckPoint, "pre-checkpoint", "P", false, "Dump container's memory information only, leave the container running")
|
||||
flags.BoolVar(&checkpointOptions.WithPrevious, "with-previous", false, "Checkpoint container with pre-checkpoint images")
|
||||
|
||||
flags.StringP("compress", "c", "zstd", "Select compression algorithm (gzip, none, zstd) for checkpoint archive.")
|
||||
_ = checkpointCommand.RegisterFlagCompletionFunc("compress", common.AutocompleteCheckpointCompressType)
|
||||
|
||||
validate.AddLatestFlag(checkpointCommand, &checkpointOptions.Latest)
|
||||
}
|
||||
|
||||
func checkpoint(cmd *cobra.Command, args []string) error {
|
||||
var errs utils.OutputErrors
|
||||
if cmd.Flags().Changed("compress") {
|
||||
if checkpointOptions.Export == "" {
|
||||
return errors.Errorf("--compress can only be used with --export")
|
||||
}
|
||||
compress, _ := cmd.Flags().GetString("compress")
|
||||
switch strings.ToLower(compress) {
|
||||
case "none":
|
||||
checkpointOptions.Compression = archive.Uncompressed
|
||||
case "gzip":
|
||||
checkpointOptions.Compression = archive.Gzip
|
||||
case "zstd":
|
||||
checkpointOptions.Compression = archive.Zstd
|
||||
default:
|
||||
return errors.Errorf("Selected compression algorithm (%q) not supported. Please select one from: gzip, none, zstd", compress)
|
||||
}
|
||||
} else {
|
||||
checkpointOptions.Compression = archive.Zstd
|
||||
}
|
||||
if rootless.IsRootless() {
|
||||
return errors.New("checkpointing a container requires root")
|
||||
}
|
||||
|
@ -10,31 +10,25 @@ podman\-container\-checkpoint - Checkpoints one or more running containers
|
||||
Checkpoints all the processes in one or more containers. You may use container IDs or names as input.
|
||||
|
||||
## OPTIONS
|
||||
#### **--keep**, **-k**
|
||||
|
||||
Keep all temporary log and statistics files created by CRIU during checkpointing. These files
|
||||
are not deleted if checkpointing fails for further debugging. If checkpointing succeeds these
|
||||
files are theoretically not needed, but if these files are needed Podman can keep the files
|
||||
for further analysis.
|
||||
|
||||
#### **--all**, **-a**
|
||||
|
||||
Checkpoint all running containers.
|
||||
|
||||
#### **--latest**, **-l**
|
||||
#### **--compress**, **-c**
|
||||
|
||||
Instead of providing the container name or ID, checkpoint the last created container. (This option is not available with the remote Podman client)
|
||||
Specify the compression algorithm used for the checkpoint archive created
|
||||
with the **--export, -e** option. Possible algorithms are *gzip*, *none*
|
||||
and *zstd*. If no compression algorithm is specified Podman will use
|
||||
*zstd*.
|
||||
|
||||
#### **--leave-running**, **-R**
|
||||
One possible reason to use *none* is to enable faster creation of checkpoint
|
||||
archives. Not compressing the checkpoint archive can result in faster checkpoint
|
||||
archive creation.
|
||||
|
||||
Leave the container running after checkpointing instead of stopping it.
|
||||
|
||||
#### **--tcp-established**
|
||||
|
||||
Checkpoint a container with established TCP connections. If the checkpoint
|
||||
image contains established TCP connections, this options is required during
|
||||
restore. Defaults to not checkpointing containers with established TCP
|
||||
connections.
|
||||
```
|
||||
# podman container checkpoint -l --compress=none --export=dump.tar
|
||||
# podman container checkpoint -l --compress=gzip --export=dump.tar.gz
|
||||
```
|
||||
|
||||
#### **--export**, **-e**
|
||||
|
||||
@ -56,11 +50,33 @@ This option must be used in combination with the **--export, -e** option.
|
||||
When this option is specified, the content of volumes associated with
|
||||
the container will not be included into the checkpoint tar.gz file.
|
||||
|
||||
#### **--keep**, **-k**
|
||||
|
||||
Keep all temporary log and statistics files created by CRIU during checkpointing. These files
|
||||
are not deleted if checkpointing fails for further debugging. If checkpointing succeeds these
|
||||
files are theoretically not needed, but if these files are needed Podman can keep the files
|
||||
for further analysis.
|
||||
|
||||
#### **--latest**, **-l**
|
||||
|
||||
Instead of providing the container name or ID, checkpoint the last created container. (This option is not available with the remote Podman client)
|
||||
|
||||
#### **--leave-running**, **-R**
|
||||
|
||||
Leave the container running after checkpointing instead of stopping it.
|
||||
|
||||
#### **--pre-checkpoint**, **-P**
|
||||
|
||||
Dump the container's memory information only, leaving the container running. Later
|
||||
operations will supersede prior dumps. It only works on runc 1.0-rc3 or higher.
|
||||
|
||||
#### **--tcp-established**
|
||||
|
||||
Checkpoint a container with established TCP connections. If the checkpoint
|
||||
image contains established TCP connections, this options is required during
|
||||
restore. Defaults to not checkpointing containers with established TCP
|
||||
connections.
|
||||
|
||||
#### **--with-previous**
|
||||
|
||||
Check out the container with previous criu image files in pre-dump. It only works
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/containers/podman/v3/libpod/define"
|
||||
"github.com/containers/podman/v3/libpod/events"
|
||||
"github.com/containers/podman/v3/pkg/signal"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -776,6 +777,9 @@ type ContainerCheckpointOptions struct {
|
||||
// ImportPrevious tells the API to restore container with two
|
||||
// images. One is TargetFile, the other is ImportPrevious.
|
||||
ImportPrevious string
|
||||
// Compression tells the API which compression to use for
|
||||
// the exported checkpoint archive.
|
||||
Compression archive.Compression
|
||||
}
|
||||
|
||||
// Checkpoint checkpoints a container
|
||||
|
@ -985,7 +985,7 @@ func (c *Container) exportCheckpoint(options ContainerCheckpointOptions) error {
|
||||
}
|
||||
|
||||
input, err := archive.TarWithOptions(c.bundlePath(), &archive.TarOptions{
|
||||
Compression: archive.Gzip,
|
||||
Compression: options.Compression,
|
||||
IncludeSourceDir: true,
|
||||
IncludeFiles: includeFiles,
|
||||
})
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/podman/v3/libpod/define"
|
||||
"github.com/containers/podman/v3/pkg/specgen"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
)
|
||||
|
||||
@ -178,6 +179,7 @@ type CheckpointOptions struct {
|
||||
TCPEstablished bool
|
||||
PreCheckPoint bool
|
||||
WithPrevious bool
|
||||
Compression archive.Compression
|
||||
}
|
||||
|
||||
type CheckpointReport struct {
|
||||
|
@ -483,6 +483,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
|
||||
KeepRunning: options.LeaveRunning,
|
||||
PreCheckPoint: options.PreCheckPoint,
|
||||
WithPrevious: options.WithPrevious,
|
||||
Compression: options.Compression,
|
||||
}
|
||||
|
||||
if options.All {
|
||||
|
@ -425,6 +425,106 @@ var _ = Describe("Podman checkpoint", func() {
|
||||
// Remove exported checkpoint
|
||||
os.Remove(fileName)
|
||||
})
|
||||
// This test does the same steps which are necessary for migrating
|
||||
// a container from one host to another
|
||||
It("podman checkpoint container with export and different compression algorithms", func() {
|
||||
localRunString := getRunString([]string{"--rm", ALPINE, "top"})
|
||||
session := podmanTest.Podman(localRunString)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
cid := session.OutputToString()
|
||||
fileName := "/tmp/checkpoint-" + cid + ".tar"
|
||||
|
||||
// Checkpoint with the default algorithm
|
||||
result := podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
// As the container has been started with '--rm' it will be completely
|
||||
// cleaned up after checkpointing.
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
|
||||
|
||||
// Restore container
|
||||
result = podmanTest.Podman([]string{"container", "restore", "-i", fileName})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||
|
||||
// Checkpoint with the zstd algorithm
|
||||
result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "--compress", "zstd"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
// As the container has been started with '--rm' it will be completely
|
||||
// cleaned up after checkpointing.
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
|
||||
|
||||
// Restore container
|
||||
result = podmanTest.Podman([]string{"container", "restore", "-i", fileName})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||
|
||||
// Checkpoint with the none algorithm
|
||||
result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "none"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
// As the container has been started with '--rm' it will be completely
|
||||
// cleaned up after checkpointing.
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
|
||||
|
||||
// Restore container
|
||||
result = podmanTest.Podman([]string{"container", "restore", "-i", fileName})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||
|
||||
// Checkpoint with the gzip algorithm
|
||||
result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "gzip"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
// As the container has been started with '--rm' it will be completely
|
||||
// cleaned up after checkpointing.
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
|
||||
|
||||
// Restore container
|
||||
result = podmanTest.Podman([]string{"container", "restore", "-i", fileName})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||
|
||||
// Checkpoint with the non-existing algorithm
|
||||
result = podmanTest.Podman([]string{"container", "checkpoint", "-l", "-e", fileName, "-c", "non-existing"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
||||
Expect(result.ExitCode()).To(Equal(125))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
|
||||
|
||||
result = podmanTest.Podman([]string{"rm", "-fa"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
|
||||
|
||||
// Remove exported checkpoint
|
||||
os.Remove(fileName)
|
||||
})
|
||||
|
||||
It("podman checkpoint and restore container with root file-system changes", func() {
|
||||
// Start the container
|
||||
|
Reference in New Issue
Block a user