summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_api.go13
-rw-r--r--libpod/container_inspect.go2
-rw-r--r--libpod/container_internal.go28
-rw-r--r--libpod/container_internal_linux.go60
-rw-r--r--libpod/define/container_inspect.go9
-rw-r--r--libpod/define/errors.go13
-rw-r--r--libpod/driver/driver.go37
-rw-r--r--libpod/image/image.go19
-rw-r--r--libpod/image/prune.go2
-rw-r--r--libpod/image/pull.go7
-rw-r--r--libpod/in_memory_state.go20
-rw-r--r--libpod/network/netconflist.go2
-rw-r--r--libpod/oci_attach_linux.go29
-rw-r--r--libpod/oci_attach_linux_cgo.go11
-rw-r--r--libpod/oci_attach_linux_nocgo.go7
-rw-r--r--libpod/oci_conmon_exec_linux.go6
-rw-r--r--libpod/oci_conmon_linux.go22
-rw-r--r--libpod/oci_util.go12
-rw-r--r--libpod/options.go2
-rw-r--r--libpod/runtime_img.go7
20 files changed, 182 insertions, 126 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 12207ed0a..0d62a2dd7 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -712,6 +712,13 @@ type ContainerCheckpointOptions struct {
// IgnoreVolumes tells the API to not export or not to import
// the content of volumes associated with the container
IgnoreVolumes bool
+ // Pre Checkpoint container and leave container running
+ PreCheckPoint bool
+ // Dump container with Pre Checkpoint images
+ WithPrevious bool
+ // ImportPrevious tells the API to restore container with two
+ // images. One is TargetFile, the other is ImportPrevious.
+ ImportPrevious string
}
// Checkpoint checkpoints a container
@@ -724,6 +731,12 @@ func (c *Container) Checkpoint(ctx context.Context, options ContainerCheckpointO
}
}
+ if options.WithPrevious {
+ if err := c.canWithPrevious(); err != nil {
+ return err
+ }
+ }
+
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 51474471b..870d92ca9 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -49,7 +49,7 @@ func (c *Container) Inspect(size bool) (*define.InspectContainerData, error) {
return c.inspectLocked(size)
}
-func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) (*define.InspectContainerData, error) {
+func (c *Container) getContainerInspectData(size bool, driverData *define.DriverData) (*define.InspectContainerData, error) {
config := c.config
runtimeInfo := c.state
ctrSpec, err := c.specFromState()
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 028710849..6d4d3ade0 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1,6 +1,7 @@
package libpod
import (
+ "bufio"
"bytes"
"context"
"fmt"
@@ -134,6 +135,11 @@ func (c *Container) CheckpointPath() string {
return filepath.Join(c.bundlePath(), "checkpoint")
}
+// PreCheckpointPath returns the path to the directory containing the pre-checkpoint-images
+func (c *Container) PreCheckPointPath() string {
+ return filepath.Join(c.bundlePath(), "pre-checkpoint")
+}
+
// AttachSocketPath retrieves the path of the container's attach socket
func (c *Container) AttachSocketPath() (string, error) {
return c.ociRuntime.AttachSocketPath(c)
@@ -1899,16 +1905,26 @@ func (c *Container) writeStringToStaticDir(filename, contents string) (string, e
return destFileName, nil
}
-// appendStringToRundir appends the provided string to the runtimedir file
-func (c *Container) appendStringToRundir(destFile, output string) (string, error) {
+// appendStringToRunDir appends the provided string to the runtimedir file
+func (c *Container) appendStringToRunDir(destFile, output string) (string, error) {
destFileName := filepath.Join(c.state.RunDir, destFile)
- f, err := os.OpenFile(destFileName, os.O_APPEND|os.O_WRONLY, 0600)
+ f, err := os.OpenFile(destFileName, os.O_APPEND|os.O_RDWR, 0600)
if err != nil {
return "", err
}
defer f.Close()
+ compareStr := strings.TrimRight(output, "\n")
+ scanner := bufio.NewScanner(f)
+ scanner.Split(bufio.ScanLines)
+
+ for scanner.Scan() {
+ if strings.Compare(scanner.Text(), compareStr) == 0 {
+ return filepath.Join(c.state.RunDir, destFile), nil
+ }
+ }
+
if _, err := f.WriteString(output); err != nil {
return "", errors.Wrapf(err, "unable to write %s", destFileName)
}
@@ -2062,6 +2078,12 @@ func (c *Container) checkReadyForRemoval() error {
return nil
}
+// canWithPrevious return the stat of the preCheckPoint dir
+func (c *Container) canWithPrevious() error {
+ _, err := os.Stat(c.PreCheckPointPath())
+ return err
+}
+
// writeJSONFile marshalls and writes the given data to a JSON file
// in the bundle path
func (c *Container) writeJSONFile(v interface{}, file string) error {
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index ac20e1f25..ce2b52234 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -40,7 +40,6 @@ import (
"github.com/containers/storage/pkg/idtools"
securejoin "github.com/cyphar/filepath-securejoin"
runcuser "github.com/opencontainers/runc/libcontainer/user"
- "github.com/opencontainers/runtime-spec/specs-go"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -284,7 +283,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, err
}
- g := generate.NewFromSpec(c.config.Spec)
+ g := generate.Generator{Config: c.config.Spec}
// If network namespace was requested, add it now
if c.config.CreateNetNS {
@@ -400,7 +399,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, errors.Wrapf(err, "failed to create TempDir in the %s directory", c.config.StaticDir)
}
- var overlayMount specs.Mount
+ var overlayMount spec.Mount
if volume.ReadWrite {
overlayMount, err = overlay.Mount(contentDir, mountPoint, volume.Dest, c.RootUID(), c.RootGID(), c.runtime.store.GraphOptions())
} else {
@@ -812,6 +811,9 @@ func (c *Container) exportCheckpoint(options ContainerCheckpointOptions) error {
"spec.dump",
"network.status"}
+ if options.PreCheckPoint {
+ includeFiles[0] = "pre-checkpoint"
+ }
// Get root file-system changes included in the checkpoint archive
rootfsDiffPath := filepath.Join(c.bundlePath(), "rootfs-diff.tar")
deleteFilesList := filepath.Join(c.bundlePath(), "deleted.files")
@@ -1015,6 +1017,15 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
defer c.newContainerEvent(events.Checkpoint)
+ // There is a bug from criu: https://github.com/checkpoint-restore/criu/issues/116
+ // We have to change the symbolic link from absolute path to relative path
+ if options.WithPrevious {
+ os.Remove(path.Join(c.CheckpointPath(), "parent"))
+ if err := os.Symlink("../pre-checkpoint", path.Join(c.CheckpointPath(), "parent")); err != nil {
+ return err
+ }
+ }
+
if options.TargetFile != "" {
if err = c.exportCheckpoint(options); err != nil {
return err
@@ -1023,7 +1034,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
logrus.Debugf("Checkpointed container %s", c.ID())
- if !options.KeepRunning {
+ if !options.KeepRunning && !options.PreCheckPoint {
c.state.State = define.ContainerStateStopped
// Cleanup Storage and Network
@@ -1032,7 +1043,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
}
}
- if !options.Keep {
+ if !options.Keep && !options.PreCheckPoint {
cleanup := []string{
"dump.log",
"stats-dump",
@@ -1080,6 +1091,21 @@ func (c *Container) importCheckpoint(input string) error {
return nil
}
+func (c *Container) importPreCheckpoint(input string) error {
+ archiveFile, err := os.Open(input)
+ if err != nil {
+ return errors.Wrap(err, "failed to open pre-checkpoint archive for import")
+ }
+
+ defer archiveFile.Close()
+
+ err = archive.Untar(archiveFile, c.bundlePath(), nil)
+ if err != nil {
+ return errors.Wrapf(err, "Unpacking of pre-checkpoint archive %s failed", input)
+ }
+ return nil
+}
+
func (c *Container) restore(ctx context.Context, options ContainerCheckpointOptions) (retErr error) {
if err := c.checkpointRestoreSupported(); err != nil {
return err
@@ -1089,6 +1115,12 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
return errors.Wrapf(define.ErrCtrStateInvalid, "container %s is running or paused, cannot restore", c.ID())
}
+ if options.ImportPrevious != "" {
+ if err := c.importPreCheckpoint(options.ImportPrevious); err != nil {
+ return err
+ }
+ }
+
if options.TargetFile != "" {
if err := c.importCheckpoint(options.TargetFile); err != nil {
return err
@@ -1322,6 +1354,10 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
if err != nil {
logrus.Debugf("Non-fatal: removal of checkpoint directory (%s) failed: %v", c.CheckpointPath(), err)
}
+ err = os.RemoveAll(c.PreCheckPointPath())
+ if err != nil {
+ logrus.Debugf("Non-fatal: removal of pre-checkpoint directory (%s) failed: %v", c.PreCheckPointPath(), err)
+ }
cleanup := [...]string{"restore.log", "dump.log", "stats-dump", "stats-restore", "network.status", "rootfs-diff.tar", "deleted.files"}
for _, del := range cleanup {
file := filepath.Join(c.bundlePath(), del)
@@ -1482,18 +1518,14 @@ func (c *Container) makeBindMounts() error {
}
if newPasswd != "" {
// Make /etc/passwd
- if _, ok := c.state.BindMounts["/etc/passwd"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/passwd")
- }
+ // If it already exists, delete so we can recreate
+ delete(c.state.BindMounts, "/etc/passwd")
c.state.BindMounts["/etc/passwd"] = newPasswd
}
if newGroup != "" {
// Make /etc/group
- if _, ok := c.state.BindMounts["/etc/group"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/group")
- }
+ // If it already exists, delete so we can recreate
+ delete(c.state.BindMounts, "/etc/group")
c.state.BindMounts["/etc/group"] = newGroup
}
@@ -1710,7 +1742,7 @@ func (c *Container) generateHosts(path string) (string, error) {
// FIXME. Path should be used by this function,but I am not sure what is correct; remove //lint
// once this is fixed
func (c *Container) appendHosts(path string, netCtr *Container) (string, error) { //nolint
- return c.appendStringToRundir("hosts", netCtr.getHosts())
+ return c.appendStringToRunDir("hosts", netCtr.getHosts())
}
// getHosts finds the pertinent information for a container's host file in its config and state
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index c61f7c159..9a93e2ffd 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -4,7 +4,6 @@ import (
"time"
"github.com/containers/image/v5/manifest"
- "github.com/containers/podman/v2/libpod/driver"
)
// InspectContainerConfig holds further data about how a container was initially
@@ -635,7 +634,7 @@ type InspectContainerData struct {
EffectiveCaps []string `json:"EffectiveCaps"`
BoundingCaps []string `json:"BoundingCaps"`
ExecIDs []string `json:"ExecIDs"`
- GraphDriver *driver.Data `json:"GraphDriver"`
+ GraphDriver *DriverData `json:"GraphDriver"`
SizeRw *int64 `json:"SizeRw,omitempty"`
SizeRootFs int64 `json:"SizeRootFs,omitempty"`
Mounts []InspectMount `json:"Mounts"`
@@ -700,3 +699,9 @@ type InspectExecProcess struct {
// User is the user the exec session was started as.
User string `json:"user"`
}
+
+// DriverData handles the data for a storage driver
+type DriverData struct {
+ Name string `json:"Name"`
+ Data map[string]string `json:"Data"`
+}
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index b96d36429..568f8e88d 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -2,6 +2,7 @@ package define
import (
"errors"
+ "fmt"
)
var (
@@ -181,4 +182,16 @@ var (
// ErrNoNetwork indicates that a container has no net namespace, like network=none
ErrNoNetwork = errors.New("container has no network namespace")
+
+ // ErrSetSecurityAttribute indicates that a request to set a container's security attribute
+ // was not possible.
+ ErrSetSecurityAttribute = fmt.Errorf("%w: unable to assign security attribute", ErrOCIRuntime)
+
+ // ErrGetSecurityAttribute indicates that a request to get a container's security attribute
+ // was not possible.
+ ErrGetSecurityAttribute = fmt.Errorf("%w: unable to get security attribute", ErrOCIRuntime)
+
+ // ErrSecurityAttribute indicates that an error processing security attributes
+ // for the container
+ ErrSecurityAttribute = fmt.Errorf("%w: unable to process security attribute", ErrOCIRuntime)
)
diff --git a/libpod/driver/driver.go b/libpod/driver/driver.go
index 85eda5a21..de71c1f6e 100644
--- a/libpod/driver/driver.go
+++ b/libpod/driver/driver.go
@@ -1,40 +1,17 @@
package driver
import (
- cstorage "github.com/containers/storage"
+ "github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/storage"
)
-// Data handles the data for a storage driver
-type Data struct {
- Name string `json:"Name"`
- Data map[string]string `json:"Data"`
-}
-
-// GetDriverName returns the name of the driver for the given store
-func GetDriverName(store cstorage.Store) (string, error) {
- driver, err := store.GraphDriver()
- if err != nil {
- return "", err
- }
- return driver.String(), nil
-}
-
-// GetDriverMetadata returns the metadata regarding the driver for the layer in the given store
-func GetDriverMetadata(store cstorage.Store, layerID string) (map[string]string, error) {
+// GetDriverData returns information on a given store's running graph driver.
+func GetDriverData(store storage.Store, layerID string) (*define.DriverData, error) {
driver, err := store.GraphDriver()
if err != nil {
return nil, err
}
- return driver.Metadata(layerID)
-}
-
-// GetDriverData returns the Data struct with information of the driver used by the store
-func GetDriverData(store cstorage.Store, layerID string) (*Data, error) {
- name, err := GetDriverName(store)
- if err != nil {
- return nil, err
- }
- metaData, err := GetDriverMetadata(store, layerID)
+ metaData, err := driver.Metadata(layerID)
if err != nil {
return nil, err
}
@@ -42,8 +19,8 @@ func GetDriverData(store cstorage.Store, layerID string) (*Data, error) {
delete(metaData, "MergedDir")
}
- return &Data{
- Name: name,
+ return &define.DriverData{
+ Name: driver.String(),
Data: metaData,
}, nil
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index a9082b2c6..d732aecfe 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -17,7 +17,6 @@ import (
"github.com/containers/common/pkg/retry"
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/directory"
- "github.com/containers/image/v5/docker/archive"
dockerarchive "github.com/containers/image/v5/docker/archive"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/image"
@@ -30,6 +29,7 @@ import (
"github.com/containers/image/v5/transports"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
+ "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/driver"
"github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/pkg/inspect"
@@ -37,7 +37,6 @@ import (
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/storage"
digest "github.com/opencontainers/go-digest"
- imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
@@ -185,7 +184,7 @@ func (ir *Runtime) SaveImages(ctx context.Context, namesOrIDs []string, format s
sys := GetSystemContext("", "", false)
- archWriter, err := archive.NewWriter(sys, outputFile)
+ archWriter, err := dockerarchive.NewWriter(sys, outputFile)
if err != nil {
return err
}
@@ -291,7 +290,7 @@ func (ir *Runtime) LoadAllImagesFromDockerArchive(ctx context.Context, fileName
}
sc := GetSystemContext(signaturePolicyPath, "", false)
- reader, err := archive.NewReader(sc, fileName)
+ reader, err := dockerarchive.NewReader(sc, fileName)
if err != nil {
return nil, err
}
@@ -972,7 +971,7 @@ func (i *Image) toImageRef(ctx context.Context) (types.Image, error) {
}
// DriverData gets the driver data from the store on a layer
-func (i *Image) DriverData() (*driver.Data, error) {
+func (i *Image) DriverData() (*define.DriverData, error) {
return driver.GetDriverData(i.imageruntime.store, i.TopLayer())
}
@@ -1148,7 +1147,7 @@ func (i *Image) GetLabel(ctx context.Context, label string) (string, error) {
}
for k, v := range labels {
- if strings.ToLower(k) == strings.ToLower(label) {
+ if strings.EqualFold(k, label) {
return v, nil
}
}
@@ -1326,7 +1325,7 @@ func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io
annotations := make(map[string]string)
- // config imgspecv1.Image
+ // config ociv1.Image
err = updater.ConfigUpdate(imageConfig, annotations)
if err != nil {
return nil, errors.Wrapf(err, "error updating image config")
@@ -1435,7 +1434,7 @@ func (i *Image) IsParent(ctx context.Context) (bool, error) {
// historiesMatch returns the number of entries in the histories which have the
// same contents
-func historiesMatch(a, b []imgspecv1.History) int {
+func historiesMatch(a, b []ociv1.History) int {
i := 0
for i < len(a) && i < len(b) {
if a[i].Created != nil && b[i].Created == nil {
@@ -1468,7 +1467,7 @@ func historiesMatch(a, b []imgspecv1.History) int {
// areParentAndChild checks diff ID and history in the two images and return
// true if the second should be considered to be directly based on the first
-func areParentAndChild(parent, child *imgspecv1.Image) bool {
+func areParentAndChild(parent, child *ociv1.Image) bool {
// the child and candidate parent should share all of the
// candidate parent's diff IDs, which together would have
// controlled which layers were used
@@ -1621,7 +1620,7 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag
if err != nil {
return errors.Wrapf(err, "error getting the OCI directory ImageReference for (%q, %q)", output, destImageName)
}
- manifestType = imgspecv1.MediaTypeImageManifest
+ manifestType = ociv1.MediaTypeImageManifest
case "docker-dir":
destRef, err = directory.NewReference(output)
if err != nil {
diff --git a/libpod/image/prune.go b/libpod/image/prune.go
index 3c06a89c2..587c99333 100644
--- a/libpod/image/prune.go
+++ b/libpod/image/prune.go
@@ -29,7 +29,7 @@ func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) {
return false
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
return true
}
}
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index c37929927..996b5995a 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -11,7 +11,6 @@ import (
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/directory"
"github.com/containers/image/v5/docker"
- "github.com/containers/image/v5/docker/archive"
dockerarchive "github.com/containers/image/v5/docker/archive"
ociarchive "github.com/containers/image/v5/oci/archive"
oci "github.com/containers/image/v5/oci/layout"
@@ -130,7 +129,7 @@ func (ir *Runtime) getSinglePullRefPairGoal(srcRef types.ImageReference, destNam
// getPullRefPairsFromDockerArchiveReference returns a slice of pullRefPairs
// for the specified docker reference and the corresponding archive.Reader.
-func (ir *Runtime) getPullRefPairsFromDockerArchiveReference(ctx context.Context, reader *archive.Reader, ref types.ImageReference, sc *types.SystemContext) ([]pullRefPair, error) {
+func (ir *Runtime) getPullRefPairsFromDockerArchiveReference(ctx context.Context, reader *dockerarchive.Reader, ref types.ImageReference, sc *types.SystemContext) ([]pullRefPair, error) {
destNames, err := reader.ManifestTagsForReference(ref)
if err != nil {
return nil, err
@@ -178,7 +177,7 @@ func (ir *Runtime) pullGoalFromImageReference(ctx context.Context, srcRef types.
// supports pulling from docker-archive, oci, and registries
switch srcRef.Transport().Name() {
case DockerArchive:
- reader, readerRef, err := archive.NewReaderForReference(sc, srcRef)
+ reader, readerRef, err := dockerarchive.NewReaderForReference(sc, srcRef)
if err != nil {
return nil, err
}
@@ -432,7 +431,7 @@ func checkRemoteImageForLabel(ctx context.Context, label string, imageInfo pullR
}
// Labels are case insensitive; so we iterate instead of simple lookup
for k := range remoteInspect.Labels {
- if strings.ToLower(label) == strings.ToLower(k) {
+ if strings.EqualFold(label, k) {
return nil
}
}
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
index 6c0cde531..9285589b1 100644
--- a/libpod/in_memory_state.go
+++ b/libpod/in_memory_state.go
@@ -437,12 +437,8 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error {
}
// Remove our network aliases
- if _, ok := s.ctrNetworkAliases[ctr.ID()]; ok {
- delete(s.ctrNetworkAliases, ctr.ID())
- }
- if _, ok := s.ctrNetworks[ctr.ID()]; ok {
- delete(s.ctrNetworks, ctr.ID())
- }
+ delete(s.ctrNetworkAliases, ctr.ID())
+ delete(s.ctrNetworks, ctr.ID())
return nil
}
@@ -680,9 +676,7 @@ func (s *InMemoryState) NetworkDisconnect(ctr *Container, network string) error
ctrAliases = make(map[string][]string)
s.ctrNetworkAliases[ctr.ID()] = ctrAliases
}
- if _, ok := ctrAliases[network]; ok {
- delete(ctrAliases, network)
- }
+ delete(ctrAliases, network)
return nil
}
@@ -1523,12 +1517,8 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error {
}
// Remove our network aliases
- if _, ok := s.ctrNetworkAliases[ctr.ID()]; ok {
- delete(s.ctrNetworkAliases, ctr.ID())
- }
- if _, ok := s.ctrNetworks[ctr.ID()]; ok {
- delete(s.ctrNetworks, ctr.ID())
- }
+ delete(s.ctrNetworkAliases, ctr.ID())
+ delete(s.ctrNetworks, ctr.ID())
return nil
}
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index bf7d03501..165a9067b 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -216,7 +216,7 @@ func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]stri
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
result = true
continue outer
}
diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go
index fbc95510e..4556eba94 100644
--- a/libpod/oci_attach_linux.go
+++ b/libpod/oci_attach_linux.go
@@ -28,6 +28,15 @@ const (
AttachPipeStderr = 3
)
+func openUnixSocket(path string) (*net.UnixConn, error) {
+ fd, err := unix.Open(path, unix.O_PATH, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer unix.Close(fd)
+ return net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: fmt.Sprintf("/proc/self/fd/%d", fd), Net: "unixpacket"})
+}
+
// Attach to the given container
// Does not check if state is appropriate
// started is only required if startContainer is true
@@ -52,11 +61,10 @@ func (c *Container) attach(streams *define.AttachStreams, keys string, resize <-
if err != nil {
return err
}
- socketPath := buildSocketPath(attachSock)
- conn, err := net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: socketPath, Net: "unixpacket"})
+ conn, err := openUnixSocket(attachSock)
if err != nil {
- return errors.Wrapf(err, "failed to connect to container's attach socket: %v", socketPath)
+ return errors.Wrapf(err, "failed to connect to container's attach socket: %v", attachSock)
}
defer func() {
if err := conn.Close(); err != nil {
@@ -124,7 +132,6 @@ func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, se
if err != nil {
return err
}
- socketPath := buildSocketPath(sockPath)
// 2: read from attachFd that the parent process has set up the console socket
if _, err := readConmonPipeData(attachFd, ""); err != nil {
@@ -132,9 +139,9 @@ func (c *Container) attachToExec(streams *define.AttachStreams, keys *string, se
}
// 2: then attach
- conn, err := net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: socketPath, Net: "unixpacket"})
+ conn, err := openUnixSocket(sockPath)
if err != nil {
- return errors.Wrapf(err, "failed to connect to container's attach socket: %v", socketPath)
+ return errors.Wrapf(err, "failed to connect to container's attach socket: %v", sockPath)
}
defer func() {
if err := conn.Close(); err != nil {
@@ -182,16 +189,6 @@ func registerResizeFunc(resize <-chan remotecommand.TerminalSize, bundlePath str
})
}
-func buildSocketPath(socketPath string) string {
- maxUnixLength := unixPathLength()
- if maxUnixLength < len(socketPath) {
- socketPath = socketPath[0:maxUnixLength]
- }
-
- logrus.Debug("connecting to socket ", socketPath)
- return socketPath
-}
-
func setupStdioChannels(streams *define.AttachStreams, conn *net.UnixConn, detachKeys []byte) (chan error, chan error) {
receiveStdoutError := make(chan error)
go func() {
diff --git a/libpod/oci_attach_linux_cgo.go b/libpod/oci_attach_linux_cgo.go
deleted file mode 100644
index d81243360..000000000
--- a/libpod/oci_attach_linux_cgo.go
+++ /dev/null
@@ -1,11 +0,0 @@
-//+build linux,cgo
-
-package libpod
-
-//#include <sys/un.h>
-// extern int unix_path_length(){struct sockaddr_un addr; return sizeof(addr.sun_path) - 1;}
-import "C"
-
-func unixPathLength() int {
- return int(C.unix_path_length())
-}
diff --git a/libpod/oci_attach_linux_nocgo.go b/libpod/oci_attach_linux_nocgo.go
deleted file mode 100644
index a514a555d..000000000
--- a/libpod/oci_attach_linux_nocgo.go
+++ /dev/null
@@ -1,7 +0,0 @@
-//+build linux,!cgo
-
-package libpod
-
-func unixPathLength() int {
- return 107
-}
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index d6b63f25e..dc5dd03df 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -2,7 +2,6 @@ package libpod
import (
"fmt"
- "net"
"net/http"
"os"
"os/exec"
@@ -512,7 +511,6 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
if err != nil {
return err
}
- socketPath := buildSocketPath(sockPath)
// 2: read from attachFd that the parent process has set up the console socket
if _, err := readConmonPipeData(pipes.attachPipe, ""); err != nil {
@@ -520,9 +518,9 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
}
// 2: then attach
- conn, err := net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: socketPath, Net: "unixpacket"})
+ conn, err := openUnixSocket(sockPath)
if err != nil {
- return errors.Wrapf(err, "failed to connect to container's attach socket: %v", socketPath)
+ return errors.Wrapf(err, "failed to connect to container's attach socket: %v", sockPath)
}
defer func() {
if err := conn.Close(); err != nil {
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 16b9f0eac..23bfb29d7 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -529,13 +529,12 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
if err != nil {
return err
}
- socketPath := buildSocketPath(attachSock)
var conn *net.UnixConn
if streamAttach {
- newConn, err := net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: socketPath, Net: "unixpacket"})
+ newConn, err := openUnixSocket(attachSock)
if err != nil {
- return errors.Wrapf(err, "failed to connect to container's attach socket: %v", socketPath)
+ return errors.Wrapf(err, "failed to connect to container's attach socket: %v", attachSock)
}
conn = newConn
defer func() {
@@ -544,7 +543,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
}
}()
- logrus.Debugf("Successfully connected to container %s attach socket %s", ctr.ID(), socketPath)
+ logrus.Debugf("Successfully connected to container %s attach socket %s", ctr.ID(), attachSock)
}
detachString := ctr.runtime.config.Engine.DetachKeys
@@ -769,10 +768,14 @@ func (r *ConmonOCIRuntime) CheckpointContainer(ctr *Container, options Container
}
// imagePath is used by CRIU to store the actual checkpoint files
imagePath := ctr.CheckpointPath()
+ if options.PreCheckPoint {
+ imagePath = ctr.PreCheckPointPath()
+ }
// workPath will be used to store dump.log and stats-dump
workPath := ctr.bundlePath()
logrus.Debugf("Writing checkpoint to %s", imagePath)
logrus.Debugf("Writing checkpoint logs to %s", workPath)
+ logrus.Debugf("Pre-dump the container %t", options.PreCheckPoint)
args := []string{}
args = append(args, r.runtimeFlags...)
args = append(args, "checkpoint")
@@ -786,6 +789,15 @@ func (r *ConmonOCIRuntime) CheckpointContainer(ctr *Container, options Container
if options.TCPEstablished {
args = append(args, "--tcp-established")
}
+ if !options.PreCheckPoint && options.KeepRunning {
+ args = append(args, "--leave-running")
+ }
+ if options.PreCheckPoint {
+ args = append(args, "--pre-dump")
+ }
+ if !options.PreCheckPoint && options.WithPrevious {
+ args = append(args, "--parent-path", ctr.PreCheckPointPath())
+ }
runtimeDir, err := util.GetRuntimeDir()
if err != nil {
return err
@@ -794,6 +806,7 @@ func (r *ConmonOCIRuntime) CheckpointContainer(ctr *Container, options Container
return errors.Wrapf(err, "cannot set XDG_RUNTIME_DIR")
}
args = append(args, ctr.ID())
+ logrus.Debugf("the args to checkpoint: %s %s", r.path, strings.Join(args, " "))
return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, nil, r.path, args...)
}
@@ -1374,6 +1387,7 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p
logDriverArg = define.NoLogging
case define.JSONLogging:
fallthrough
+ //lint:ignore ST1015 the default case has to be here
default: //nolint-stylecheck
// No case here should happen except JSONLogging, but keep this here in case the options are extended
logrus.Errorf("%s logging specified but not supported. Choosing k8s-file logging instead", ctr.LogDriver())
diff --git a/libpod/oci_util.go b/libpod/oci_util.go
index 2ba85c4b3..d40cf13bd 100644
--- a/libpod/oci_util.go
+++ b/libpod/oci_util.go
@@ -126,5 +126,17 @@ func getOCIRuntimeError(runtimeMsg string) error {
}
return errors.Wrapf(define.ErrOCIRuntimeNotFound, "%s", strings.Trim(errStr, "\n"))
}
+ if match := regexp.MustCompile("`/proc/[a-z0-9-].+/attr.*`").FindString(runtimeMsg); match != "" {
+ errStr := match
+ if includeFullOutput {
+ errStr = runtimeMsg
+ }
+ if strings.HasSuffix(match, "/exec`") {
+ return errors.Wrapf(define.ErrSetSecurityAttribute, "%s", strings.Trim(errStr, "\n"))
+ } else if strings.HasSuffix(match, "/current`") {
+ return errors.Wrapf(define.ErrGetSecurityAttribute, "%s", strings.Trim(errStr, "\n"))
+ }
+ return errors.Wrapf(define.ErrSecurityAttribute, "%s", strings.Trim(errStr, "\n"))
+ }
return errors.Wrapf(define.ErrOCIRuntime, "%s", strings.Trim(runtimeMsg, "\n"))
}
diff --git a/libpod/options.go b/libpod/options.go
index ef7db3235..31c0b9ac9 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -910,7 +910,7 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption {
ctr.config.UserNsCtr = nsCtr.ID()
ctr.config.IDMappings = nsCtr.config.IDMappings
- g := generate.NewFromSpec(ctr.config.Spec)
+ g := generate.Generator{Config: ctr.config.Spec}
g.ClearLinuxUIDMappings()
for _, uidmap := range nsCtr.config.IDMappings.UIDMap {
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 965333f77..2c5442bd2 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -279,6 +279,7 @@ func (r *Runtime) LoadImage(ctx context.Context, inputFile string, writer io.Wri
if newImages, err := r.LoadAllImageFromArchive(ctx, writer, inputFile, signaturePolicy); err == nil {
return newImages, nil
}
+
return r.LoadImageFromSingleImageArchive(ctx, writer, inputFile, signaturePolicy)
}
@@ -293,7 +294,7 @@ func (r *Runtime) LoadAllImageFromArchive(ctx context.Context, writer io.Writer,
// LoadImageFromSingleImageArchive load image from the archive of single image that inputFile points to.
func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io.Writer, inputFile, signaturePolicy string) (string, error) {
- var err error
+ var saveErr error
for _, referenceFn := range []func() (types.ImageReference, error){
func() (types.ImageReference, error) {
return dockerarchive.ParseReference(inputFile)
@@ -312,10 +313,12 @@ func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io
if err == nil && src != nil {
if newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer); err == nil {
return getImageNames(newImages), nil
+ } else {
+ saveErr = err
}
}
}
- return "", errors.Wrapf(err, "error pulling image")
+ return "", errors.Wrapf(saveErr, "error pulling image")
}
func getImageNames(images []*image.Image) string {