diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/checkpoint/checkpoint_restore.go | 26 | ||||
-rw-r--r-- | pkg/checkpoint/crutils/checkpoint_restore_utils.go | 55 | ||||
-rw-r--r-- | pkg/specgen/generate/ports.go | 36 | ||||
-rw-r--r-- | pkg/specgenutil/specgen.go | 2 | ||||
-rw-r--r-- | pkg/specgenutil/util.go | 4 | ||||
-rw-r--r-- | pkg/util/filters.go | 23 |
6 files changed, 75 insertions, 71 deletions
diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go index 85fe6a77e..c371adf5b 100644 --- a/pkg/checkpoint/checkpoint_restore.go +++ b/pkg/checkpoint/checkpoint_restore.go @@ -6,7 +6,6 @@ import ( "os" metadata "github.com/checkpoint-restore/checkpointctl/lib" - "github.com/checkpoint-restore/go-criu/v5/stats" "github.com/containers/common/libimage" "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod" @@ -14,10 +13,8 @@ import ( "github.com/containers/podman/v3/pkg/checkpoint/crutils" "github.com/containers/podman/v3/pkg/criu" "github.com/containers/podman/v3/pkg/domain/entities" - "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/specgen/generate" "github.com/containers/podman/v3/pkg/specgenutil" - "github.com/containers/storage/pkg/archive" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -30,24 +27,6 @@ import ( func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOptions entities.RestoreOptions) ([]*libpod.Container, error) { // First get the container definition from the // tarball to a temporary directory - archiveFile, err := os.Open(restoreOptions.Import) - if err != nil { - return nil, errors.Wrap(err, "failed to open checkpoint archive for import") - } - defer errorhandling.CloseQuiet(archiveFile) - options := &archive.TarOptions{ - // Here we only need the files config.dump and spec.dump - ExcludePatterns: []string{ - "volumes", - "ctr.log", - "artifacts", - stats.StatsDump, - metadata.RootFsDiffTar, - metadata.DeletedFilesFile, - metadata.NetworkStatusFile, - metadata.CheckpointDirectory, - }, - } dir, err := ioutil.TempDir("", "checkpoint") if err != nil { return nil, err @@ -57,9 +36,8 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOpt logrus.Errorf("Could not recursively remove %s: %q", dir, err) } }() - err = archive.Untar(archiveFile, dir, options) - if err != nil { - return nil, errors.Wrapf(err, "Unpacking of checkpoint archive %s failed", restoreOptions.Import) + if err := crutils.CRImportCheckpointConfigOnly(dir, restoreOptions.Import); err != nil { + return nil, err } // Load spec.dump from temporary directory diff --git a/pkg/checkpoint/crutils/checkpoint_restore_utils.go b/pkg/checkpoint/crutils/checkpoint_restore_utils.go index 3b77368bb..2765d18e8 100644 --- a/pkg/checkpoint/crutils/checkpoint_restore_utils.go +++ b/pkg/checkpoint/crutils/checkpoint_restore_utils.go @@ -3,11 +3,13 @@ package crutils import ( "bytes" "io" + "io/ioutil" "os" "os/exec" "path/filepath" metadata "github.com/checkpoint-restore/checkpointctl/lib" + "github.com/checkpoint-restore/go-criu/v5/stats" "github.com/containers/storage/pkg/archive" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" @@ -39,6 +41,36 @@ func CRImportCheckpointWithoutConfig(destination, input string) error { return nil } +// CRImportCheckpointConfigOnly only imports the checkpoint configuration +// from the checkpoint archive (input) into the directory destination. +// Only the files "config.dump" and "spec.dump" are extracted. +func CRImportCheckpointConfigOnly(destination, input string) error { + archiveFile, err := os.Open(input) + if err != nil { + return errors.Wrapf(err, "Failed to open checkpoint archive %s for import", input) + } + + defer archiveFile.Close() + options := &archive.TarOptions{ + // Here we only need the files config.dump and spec.dump + ExcludePatterns: []string{ + "volumes", + "ctr.log", + "artifacts", + stats.StatsDump, + metadata.RootFsDiffTar, + metadata.DeletedFilesFile, + metadata.NetworkStatusFile, + metadata.CheckpointDirectory, + }, + } + if err = archive.Untar(archiveFile, destination, options); err != nil { + return errors.Wrapf(err, "Unpacking of checkpoint archive %s failed", input) + } + + return nil +} + // CRRemoveDeletedFiles loads the list of deleted files and if // it exists deletes all files listed. func CRRemoveDeletedFiles(id, baseDirectory, containerRootDirectory string) error { @@ -200,3 +232,26 @@ func CRRuntimeSupportsPodCheckpointRestore(runtimePath string) bool { out, _ := cmd.CombinedOutput() return bytes.Contains(out, []byte("flag needs an argument")) } + +// CRGetRuntimeFromArchive extracts the checkpoint metadata from the +// given checkpoint archive and returns the runtime used to create +// the given checkpoint archive. +func CRGetRuntimeFromArchive(input string) (*string, error) { + dir, err := ioutil.TempDir("", "checkpoint") + if err != nil { + return nil, err + } + defer os.RemoveAll(dir) + + if err := CRImportCheckpointConfigOnly(dir, input); err != nil { + return nil, err + } + + // Load config.dump from temporary directory + ctrConfig := new(metadata.ContainerConfig) + if _, err = metadata.ReadJSONFile(ctrConfig, dir, metadata.ConfigDumpFile); err != nil { + return nil, err + } + + return &ctrConfig.OCIRuntime, nil +} diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go index 53a5e5697..b60cc1e98 100644 --- a/pkg/specgen/generate/ports.go +++ b/pkg/specgen/generate/ports.go @@ -5,7 +5,6 @@ import ( "fmt" "net" "sort" - "strconv" "strings" "github.com/containers/common/libimage" @@ -13,6 +12,7 @@ import ( "github.com/containers/podman/v3/utils" "github.com/containers/podman/v3/pkg/specgen" + "github.com/containers/podman/v3/pkg/specgenutil" "github.com/containers/podman/v3/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -410,31 +410,13 @@ func checkProtocol(protocol string, allowSCTP bool) ([]string, error) { } func GenExposedPorts(exposedPorts map[string]struct{}) (map[uint16]string, error) { - expose := make(map[uint16]string, len(exposedPorts)) - for imgExpose := range exposedPorts { - // Expose format is portNumber[/protocol] - splitExpose := strings.SplitN(imgExpose, "/", 2) - num, err := strconv.Atoi(splitExpose[0]) - if err != nil { - return nil, errors.Wrapf(err, "unable to convert image EXPOSE statement %q to port number", imgExpose) - } - if num > 65535 || num < 1 { - return nil, errors.Errorf("%d from image EXPOSE statement %q is not a valid port number", num, imgExpose) - } - - // No need to validate protocol, we'll do it later. - newProto := "tcp" - if len(splitExpose) == 2 { - newProto = splitExpose[1] - } - - proto := expose[uint16(num)] - if len(proto) > 1 { - proto = proto + "," + newProto - } else { - proto = newProto - } - expose[uint16(num)] = proto + expose := make([]string, 0, len(exposedPorts)) + for e := range exposedPorts { + expose = append(expose, e) + } + toReturn, err := specgenutil.CreateExpose(expose) + if err != nil { + return nil, errors.Wrapf(err, "unable to convert image EXPOSE") } - return expose, nil + return toReturn, nil } diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index c110b9e97..7a572e730 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -314,7 +314,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions s.Pod = podID } - expose, err := createExpose(c.Expose) + expose, err := CreateExpose(c.Expose) if err != nil { return err } diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go index b47082b7f..534374e71 100644 --- a/pkg/specgenutil/util.go +++ b/pkg/specgenutil/util.go @@ -53,11 +53,11 @@ func ParseFilters(filter []string) (map[string][]string, error) { return filters, nil } -// createExpose parses user-provided exposed port definitions and converts them +// CreateExpose parses user-provided exposed port definitions and converts them // into SpecGen format. // TODO: The SpecGen format should really handle ranges more sanely - we could // be massively inflating what is sent over the wire with a large range. -func createExpose(expose []string) (map[uint16]string, error) { +func CreateExpose(expose []string) (map[uint16]string, error) { toReturn := make(map[uint16]string) for _, e := range expose { diff --git a/pkg/util/filters.go b/pkg/util/filters.go index 5af868873..99fac2478 100644 --- a/pkg/util/filters.go +++ b/pkg/util/filters.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" "net/http" - "regexp" + "path/filepath" "strings" "time" @@ -95,24 +95,13 @@ func PrepareFilters(r *http.Request) (*map[string][]string, error) { return &filterMap, nil } -func wildCardToRegexp(pattern string) string { - var result strings.Builder - for i, literal := range strings.Split(pattern, "*") { - // Replace * with .* - if i > 0 { - result.WriteString(".*") - } - // Quote any regular expression meta characters in the - // literal text. - result.WriteString(regexp.QuoteMeta(literal)) - } - return result.String() -} - func matchPattern(pattern string, value string) bool { if strings.Contains(pattern, "*") { - result, _ := regexp.MatchString(wildCardToRegexp(pattern), value) - return result + filter := fmt.Sprintf("*%s*", pattern) + filter = strings.ReplaceAll(filter, string(filepath.Separator), "|") + newName := strings.ReplaceAll(value, string(filepath.Separator), "|") + match, _ := filepath.Match(filter, newName) + return match } return false } |