diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/boltdb_state.go | 6 | ||||
-rw-r--r-- | libpod/boltdb_state_internal.go | 4 | ||||
-rw-r--r-- | libpod/container_api.go | 9 | ||||
-rw-r--r-- | libpod/container_copy_linux.go | 70 | ||||
-rw-r--r-- | libpod/container_internal.go | 29 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 5 | ||||
-rw-r--r-- | libpod/container_stat_linux.go | 42 | ||||
-rw-r--r-- | libpod/define/mount.go | 12 | ||||
-rw-r--r-- | libpod/image/image.go | 27 | ||||
-rw-r--r-- | libpod/image/pull.go | 13 | ||||
-rw-r--r-- | libpod/kube.go | 12 | ||||
-rw-r--r-- | libpod/options.go | 11 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 13 | ||||
-rw-r--r-- | libpod/runtime_img.go | 12 | ||||
-rw-r--r-- | libpod/runtime_img_test.go | 4 | ||||
-rw-r--r-- | libpod/storage.go | 5 |
16 files changed, 127 insertions, 147 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 122dd080f..5df3e8961 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -879,7 +879,7 @@ func (s *BoltState) ContainerInUse(ctr *Container) ([]string, error) { ctrDB := ctrBucket.Bucket([]byte(ctr.ID())) if ctrDB == nil { ctr.valid = false - return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %s found in DB", ctr.ID()) + return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %q found in DB", ctr.ID()) } dependsBkt := ctrDB.Bucket(dependenciesBkt) @@ -1669,7 +1669,7 @@ func (s *BoltState) RewriteContainerConfig(ctr *Container, newCfg *ContainerConf ctrDB := ctrBkt.Bucket([]byte(ctr.ID())) if ctrDB == nil { ctr.valid = false - return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %s found in DB", ctr.ID()) + return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %q found in DB", ctr.ID()) } if err := ctrDB.Put(configKey, newCfgJSON); err != nil { @@ -1767,7 +1767,7 @@ func (s *BoltState) SafeRewriteContainerConfig(ctr *Container, oldName, newName ctrDB := ctrBkt.Bucket([]byte(ctr.ID())) if ctrDB == nil { ctr.valid = false - return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %s found in DB", ctr.ID()) + return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %q found in DB", ctr.ID()) } if err := ctrDB.Put(configKey, newCfgJSON); err != nil { diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go index cf8f1c175..d4994334f 100644 --- a/libpod/boltdb_state_internal.go +++ b/libpod/boltdb_state_internal.go @@ -1055,9 +1055,9 @@ func (s *BoltState) lookupContainerID(idOrName string, ctrBucket, namesBucket, n return nil, err } else if !exists { if isPod { - return nil, errors.Wrapf(define.ErrNoSuchCtr, "%s is a pod, not a container", idOrName) + return nil, errors.Wrapf(define.ErrNoSuchCtr, "%q is a pod, not a container", idOrName) } - return nil, errors.Wrapf(define.ErrNoSuchCtr, "no container with name or ID %s found", idOrName) + return nil, errors.Wrapf(define.ErrNoSuchCtr, "no container with name or ID %q found", idOrName) } return id, nil } diff --git a/libpod/container_api.go b/libpod/container_api.go index 6fa8b27cd..4ccb240e7 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -12,7 +12,6 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/pkg/signal" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -28,10 +27,6 @@ import ( // containers). The `recursive` parameter will, if set to true, start these // dependency containers before initializing this container. func (c *Container) Init(ctx context.Context, recursive bool) error { - span, _ := opentracing.StartSpanFromContext(ctx, "containerInit") - span.SetTag("struct", "container") - defer span.Finish() - if !c.batched { c.lock.Lock() defer c.lock.Unlock() @@ -84,10 +79,6 @@ func (c *Container) Init(ctx context.Context, recursive bool) error { // running before being run. The recursive parameter, if set, will start all // dependencies before starting this container. func (c *Container) Start(ctx context.Context, recursive bool) error { - span, _ := opentracing.StartSpanFromContext(ctx, "containerStart") - span.SetTag("struct", "container") - defer span.Finish() - if !c.batched { c.lock.Lock() defer c.lock.Unlock() diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go index 66ccd2f1f..5c275c641 100644 --- a/libpod/container_copy_linux.go +++ b/libpod/container_copy_linux.go @@ -14,7 +14,7 @@ import ( "github.com/containers/buildah/pkg/chrootuser" "github.com/containers/buildah/util" "github.com/containers/podman/v3/libpod/define" - "github.com/containers/storage" + "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/storage/pkg/idtools" "github.com/docker/docker/pkg/archive" "github.com/opencontainers/runtime-spec/specs-go" @@ -62,15 +62,16 @@ func (c *Container) copyFromArchive(ctx context.Context, path string, reader io. } } - decompressed, err := archive.DecompressStream(reader) + // Make sure we chown the files to the container's main user and group ID. + user, err := getContainerUser(c, mountPoint) if err != nil { unmount() return nil, err } + idPair := idtools.IDPair{UID: int(user.UID), GID: int(user.GID)} - idMappings, idPair, err := getIDMappingsAndPair(c, mountPoint) + decompressed, err := archive.DecompressStream(reader) if err != nil { - decompressed.Close() unmount() return nil, err } @@ -81,10 +82,10 @@ func (c *Container) copyFromArchive(ctx context.Context, path string, reader io. defer unmount() defer decompressed.Close() putOptions := buildahCopiah.PutOptions{ - UIDMap: idMappings.UIDMap, - GIDMap: idMappings.GIDMap, - ChownDirs: idPair, - ChownFiles: idPair, + UIDMap: c.config.IDMappings.UIDMap, + GIDMap: c.config.IDMappings.GIDMap, + ChownDirs: &idPair, + ChownFiles: &idPair, } return c.joinMountAndExec(ctx, @@ -121,11 +122,25 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr return nil, err } - idMappings, idPair, err := getIDMappingsAndPair(c, mountPoint) + // We optimistically chown to the host user. In case of a hypothetical + // container-to-container copy, the reading side will chown back to the + // container user. + user, err := getContainerUser(c, mountPoint) + if err != nil { + unmount() + return nil, err + } + hostUID, hostGID, err := util.GetHostIDs( + idtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), + idtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), + user.UID, + user.GID, + ) if err != nil { unmount() return nil, err } + idPair := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} logrus.Debugf("Container copy *from* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) @@ -134,11 +149,16 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr getOptions := buildahCopiah.GetOptions{ // Unless the specified points to ".", we want to copy the base directory. KeepDirectoryNames: statInfo.IsDir && filepath.Base(path) != ".", - UIDMap: idMappings.UIDMap, - GIDMap: idMappings.GIDMap, - ChownDirs: idPair, - ChownFiles: idPair, + UIDMap: c.config.IDMappings.UIDMap, + GIDMap: c.config.IDMappings.GIDMap, + ChownDirs: &idPair, + ChownFiles: &idPair, Excludes: []string{"dev", "proc", "sys"}, + // Ignore EPERMs when copying from rootless containers + // since we cannot read TTY devices. Those are owned + // by the host's root and hence "nobody" inside the + // container's user namespace. + IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning, } return c.joinMountAndExec(ctx, func() error { @@ -148,29 +168,7 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr }, nil } -// getIDMappingsAndPair returns the ID mappings for the container and the host -// ID pair. -func getIDMappingsAndPair(container *Container, containerMount string) (*storage.IDMappingOptions, *idtools.IDPair, error) { - user, err := getContainerUser(container, containerMount) - if err != nil { - return nil, nil, err - } - - idMappingOpts, err := container.IDMappings() - if err != nil { - return nil, nil, err - } - - hostUID, hostGID, err := util.GetHostIDs(idtoolsToRuntimeSpec(idMappingOpts.UIDMap), idtoolsToRuntimeSpec(idMappingOpts.GIDMap), user.UID, user.GID) - if err != nil { - return nil, nil, err - } - - idPair := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} - return &idMappingOpts, &idPair, nil -} - -// getContainerUser returns the specs.User of the container. +// getContainerUser returns the specs.User and ID mappings of the container. func getContainerUser(container *Container, mountPoint string) (specs.User, error) { userspec := container.Config().User diff --git a/libpod/container_internal.go b/libpod/container_internal.go index af57aaca0..1614211fb 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -33,7 +33,6 @@ import ( spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/selinux/go-selinux/label" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -399,10 +398,6 @@ func (c *Container) setupStorageMapping(dest, from *storage.IDMappingOptions) { // Create container root filesystem for use func (c *Container) setupStorage(ctx context.Context) error { - span, _ := opentracing.StartSpanFromContext(ctx, "setupStorage") - span.SetTag("type", "container") - defer span.Finish() - if !c.valid { return errors.Wrapf(define.ErrCtrRemoved, "container %s is not valid", c.ID()) } @@ -1035,10 +1030,6 @@ func (c *Container) cniHosts() string { // Initialize a container, creating it in the runtime func (c *Container) init(ctx context.Context, retainRetries bool) error { - span, _ := opentracing.StartSpanFromContext(ctx, "init") - span.SetTag("struct", "container") - defer span.Finish() - // Unconditionally remove conmon temporary files. // We've been running into far too many issues where they block startup. if err := c.removeConmonFiles(); err != nil { @@ -1111,10 +1102,6 @@ func (c *Container) init(ctx context.Context, retainRetries bool) error { // Deletes the container in the runtime, and resets its state to Exited. // The container can be restarted cleanly after this. func (c *Container) cleanupRuntime(ctx context.Context) error { - span, _ := opentracing.StartSpanFromContext(ctx, "cleanupRuntime") - span.SetTag("struct", "container") - defer span.Finish() - // If the container is not ContainerStateStopped or // ContainerStateCreated, do nothing. if !c.ensureState(define.ContainerStateStopped, define.ContainerStateCreated) { @@ -1156,10 +1143,6 @@ func (c *Container) cleanupRuntime(ctx context.Context) error { // Not necessary for ContainerStateExited - the container has already been // removed from the runtime, so init() can proceed freely. func (c *Container) reinit(ctx context.Context, retainRetries bool) error { - span, _ := opentracing.StartSpanFromContext(ctx, "reinit") - span.SetTag("struct", "container") - defer span.Finish() - logrus.Debugf("Recreating container %s in OCI runtime", c.ID()) if err := c.cleanupRuntime(ctx); err != nil { @@ -1820,10 +1803,6 @@ func (c *Container) cleanupStorage() error { func (c *Container) cleanup(ctx context.Context) error { var lastError error - span, _ := opentracing.StartSpanFromContext(ctx, "cleanup") - span.SetTag("struct", "container") - defer span.Finish() - logrus.Debugf("Cleaning up container %s", c.ID()) // Remove healthcheck unit/timer file if it execs @@ -1884,10 +1863,6 @@ func (c *Container) cleanup(ctx context.Context) error { // delete deletes the container and runs any configured poststop // hooks. func (c *Container) delete(ctx context.Context) error { - span, _ := opentracing.StartSpanFromContext(ctx, "delete") - span.SetTag("struct", "container") - defer span.Finish() - if err := c.ociRuntime.DeleteContainer(c); err != nil { return errors.Wrapf(err, "error removing container %s from runtime", c.ID()) } @@ -1903,10 +1878,6 @@ func (c *Container) delete(ctx context.Context) error { // the OCI Runtime Specification (which requires them to run // post-delete, despite the stage name). func (c *Container) postDeleteHooks(ctx context.Context) error { - span, _ := opentracing.StartSpanFromContext(ctx, "postDeleteHooks") - span.SetTag("struct", "container") - defer span.Finish() - if c.state.ExtensionStageHooks != nil { extensionHooks, ok := c.state.ExtensionStageHooks["poststop"] if ok { diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 2684c2845..24319f4b5 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -49,7 +49,6 @@ import ( spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/selinux/go-selinux/label" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -322,10 +321,6 @@ func (c *Container) getUserOverrides() *lookup.Overrides { // Generate spec for a container // Accepts a map of the container's dependencies func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "generateSpec") - span.SetTag("type", "container") - defer span.Finish() - overrides := c.getUserOverrides() execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, overrides) if err != nil { diff --git a/libpod/container_stat_linux.go b/libpod/container_stat_linux.go index 307b75c14..0b4d9e2df 100644 --- a/libpod/container_stat_linux.go +++ b/libpod/container_stat_linux.go @@ -64,6 +64,13 @@ func (c *Container) stat(ctx context.Context, containerMountPoint string, contai containerPath = "/." } + // Wildcards are not allowed. + // TODO: it's now technically possible wildcards. + // We may consider enabling support in the future. + if strings.Contains(containerPath, "*") { + return nil, "", "", copy.ErrENOENT + } + if c.state.State == define.ContainerStateRunning { // If the container is running, we need to join it's mount namespace // and stat there. @@ -88,7 +95,8 @@ func (c *Container) stat(ctx context.Context, containerMountPoint string, contai } if statInfo.IsSymlink { - // Evaluated symlinks are always relative to the container's mount point. + // Symlinks are already evaluated and always relative to the + // container's mount point. absContainerPath = statInfo.ImmediateTarget } else if strings.HasPrefix(resolvedPath, containerMountPoint) { // If the path is on the container's mount point, strip it off. @@ -143,15 +151,31 @@ func secureStat(root string, path string) (*copier.StatForItem, error) { if len(globStats) != 1 { return nil, errors.Errorf("internal error: secureStat: expected 1 item but got %d", len(globStats)) } - - stat, exists := globStats[0].Results[glob] // only one glob passed, so that's okay - if !exists { - return nil, copy.ErrENOENT + if len(globStats) != 1 { + return nil, errors.Errorf("internal error: secureStat: expected 1 result but got %d", len(globStats[0].Results)) } - var statErr error - if stat.Error != "" { - statErr = errors.New(stat.Error) + // NOTE: the key in the map differ from `glob` when hitting symlink. + // Hence, we just take the first (and only) key/value pair. + for _, stat := range globStats[0].Results { + var statErr error + if stat.Error != "" { + statErr = errors.New(stat.Error) + } + // If necessary evaluate the symlink + if stat.IsSymlink { + target, err := copier.Eval(root, path, copier.EvalOptions{}) + if err != nil { + return nil, errors.Wrap(err, "error evaluating symlink in container") + } + // Need to make sure the symlink is relative to the root! + target = strings.TrimPrefix(target, root) + target = filepath.Join("/", target) + stat.ImmediateTarget = target + } + return stat, statErr } - return stat, statErr + + // Nothing found! + return nil, copy.ErrENOENT } diff --git a/libpod/define/mount.go b/libpod/define/mount.go new file mode 100644 index 000000000..1b0d019c8 --- /dev/null +++ b/libpod/define/mount.go @@ -0,0 +1,12 @@ +package define + +const ( + // TypeBind is the type for mounting host dir + TypeBind = "bind" + // TypeVolume is the type for named volumes + TypeVolume = "volume" + // TypeTmpfs is the type for mounting tmpfs + TypeTmpfs = "tmpfs" + // TypeDevpts is the type for creating a devpts + TypeDevpts = "devpts" +) diff --git a/libpod/image/image.go b/libpod/image/image.go index 265178ad5..12dc22360 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -38,7 +38,6 @@ import ( "github.com/containers/storage" digest "github.com/opencontainers/go-digest" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -144,10 +143,6 @@ func (ir *Runtime) NewFromLocal(name string) (*Image, error) { // New creates a new image object where the image could be local // or remote func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *DockerRegistryOptions, signingoptions SigningOptions, label *string, pullType util.PullType, progress chan types.ProgressProperties) (*Image, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "newImage") - span.SetTag("type", "runtime") - defer span.Finish() - // We don't know if the image is local or not ... check local first if pullType != util.PullImageAlways { newImage, err := ir.NewFromLocal(name) @@ -816,7 +811,7 @@ func (i *Image) UntagImage(tag string) error { // PushImageToHeuristicDestination pushes the given image to "destination", which is heuristically parsed. // Use PushImageToReference if the destination is known precisely. -func (i *Image) PushImageToHeuristicDestination(ctx context.Context, destination, manifestMIMEType, authFile, digestFile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions SigningOptions, dockerRegistryOptions *DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { +func (i *Image) PushImageToHeuristicDestination(ctx context.Context, destination, manifestMIMEType, authFile, digestFile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions SigningOptions, dockerRegistryOptions *DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged, progress chan types.ProgressProperties) error { if destination == "" { return errors.Wrapf(syscall.EINVAL, "destination image name must be specified") } @@ -834,11 +829,11 @@ func (i *Image) PushImageToHeuristicDestination(ctx context.Context, destination return err } } - return i.PushImageToReference(ctx, dest, manifestMIMEType, authFile, digestFile, signaturePolicyPath, writer, forceCompress, signingOptions, dockerRegistryOptions, additionalDockerArchiveTags) + return i.PushImageToReference(ctx, dest, manifestMIMEType, authFile, digestFile, signaturePolicyPath, writer, forceCompress, signingOptions, dockerRegistryOptions, additionalDockerArchiveTags, progress) } // PushImageToReference pushes the given image to a location described by the given path -func (i *Image) PushImageToReference(ctx context.Context, dest types.ImageReference, manifestMIMEType, authFile, digestFile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions SigningOptions, dockerRegistryOptions *DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { +func (i *Image) PushImageToReference(ctx context.Context, dest types.ImageReference, manifestMIMEType, authFile, digestFile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions SigningOptions, dockerRegistryOptions *DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged, progress chan types.ProgressProperties) error { sc := GetSystemContext(signaturePolicyPath, authFile, forceCompress) sc.BlobInfoCacheDir = filepath.Join(i.imageruntime.store.GraphRoot(), "cache") @@ -859,6 +854,10 @@ func (i *Image) PushImageToReference(ctx context.Context, dest types.ImageRefere } copyOptions := getCopyOptions(sc, writer, nil, dockerRegistryOptions, signingOptions, manifestMIMEType, additionalDockerArchiveTags) copyOptions.DestinationCtx.SystemRegistriesConfPath = registries.SystemRegistriesConfPath() // FIXME: Set this more globally. Probably no reason not to have it in every types.SystemContext, and to compute the value just once in one place. + if progress != nil { + copyOptions.Progress = progress + copyOptions.ProgressInterval = time.Second + } // Copy the image to the remote destination manifestBytes, err := cp.Image(ctx, policyContext, dest, src, copyOptions) if err != nil { @@ -1293,21 +1292,11 @@ func (i *Image) inspect(ctx context.Context, calculateSize bool) (*inspect.Image // Inspect returns an image's inspect data func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "imageInspect") - - span.SetTag("type", "image") - defer span.Finish() - return i.inspect(ctx, true) } // InspectNoSize returns an image's inspect data without calculating the size for the image func (i *Image) InspectNoSize(ctx context.Context) (*inspect.ImageData, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "imageInspectNoSize") - - span.SetTag("type", "image") - defer span.Finish() - return i.inspect(ctx, false) } @@ -1648,7 +1637,7 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag return err } } - if err := i.PushImageToReference(ctx, destRef, manifestType, "", "", "", writer, compress, SigningOptions{RemoveSignatures: removeSignatures}, &DockerRegistryOptions{}, additionaltags); err != nil { + if err := i.PushImageToReference(ctx, destRef, manifestType, "", "", "", writer, compress, SigningOptions{RemoveSignatures: removeSignatures}, &DockerRegistryOptions{}, additionaltags, nil); err != nil { return errors.Wrapf(err, "unable to save %q", source) } i.newImageEvent(events.Save) diff --git a/libpod/image/pull.go b/libpod/image/pull.go index c5fafc25d..58160b52f 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -23,7 +23,6 @@ import ( "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/registries" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -172,9 +171,6 @@ func (ir *Runtime) getPullRefPairsFromDockerArchiveReference(ctx context.Context // pullGoalFromImageReference returns a pull goal for a single ImageReference, depending on the used transport. // Note that callers are responsible for invoking (*pullGoal).cleanUp() to clean up possibly open resources. func (ir *Runtime) pullGoalFromImageReference(ctx context.Context, srcRef types.ImageReference, imgName string, sc *types.SystemContext) (*pullGoal, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "pullGoalFromImageReference") - defer span.Finish() - // supports pulling from docker-archive, oci, and registries switch srcRef.Transport().Name() { case DockerArchive: @@ -243,9 +239,6 @@ func toLocalImageName(imageName string) string { // pullImageFromHeuristicSource pulls an image based on inputName, which is heuristically parsed and may involve configured registries. // Use pullImageFromReference if the source is known precisely. func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName string, writer io.Writer, authfile, signaturePolicyPath string, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, retryOptions *retry.RetryOptions, label *string, progress chan types.ProgressProperties) ([]string, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "pullImageFromHeuristicSource") - defer span.Finish() - var goal *pullGoal sc := GetSystemContext(signaturePolicyPath, authfile, false) if dockerOptions != nil { @@ -281,9 +274,6 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s // pullImageFromReference pulls an image from a types.imageReference. func (ir *Runtime) pullImageFromReference(ctx context.Context, srcRef types.ImageReference, writer io.Writer, authfile, signaturePolicyPath string, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, retryOptions *retry.RetryOptions) ([]string, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "pullImageFromReference") - defer span.Finish() - sc := GetSystemContext(signaturePolicyPath, authfile, false) if dockerOptions != nil { sc.OSChoice = dockerOptions.OSChoice @@ -306,9 +296,6 @@ func cleanErrorMessage(err error) string { // doPullImage is an internal helper interpreting pullGoal. Almost everyone should call one of the callers of doPullImage instead. func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goal pullGoal, writer io.Writer, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, retryOptions *retry.RetryOptions, label *string, progress chan types.ProgressProperties) ([]string, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "doPullImage") - defer span.Finish() - policyContext, err := getPolicyContext(sc) if err != nil { return nil, err diff --git a/libpod/kube.go b/libpod/kube.go index 0c4f9f0a0..6feb69fea 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -676,8 +676,18 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) { return nil, errors.Wrapf(err, "unable to sync container during YAML generation") } + mountpoint := c.state.Mountpoint + if mountpoint == "" { + var err error + mountpoint, err = c.mount() + if err != nil { + return nil, errors.Wrapf(err, "failed to mount %s mountpoint", c.ID()) + } + defer c.unmount(false) + } logrus.Debugf("Looking in container for user: %s", c.User()) - execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.User(), nil) + + execUser, err := lookup.GetUserGroupInfo(mountpoint, c.User(), nil) if err != nil { return nil, err } diff --git a/libpod/options.go b/libpod/options.go index 6344e1acc..48888a2f2 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -64,15 +64,22 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption { setField = true } + graphDriverChanged := false if config.GraphDriverName != "" { rt.storageConfig.GraphDriverName = config.GraphDriverName rt.storageSet.GraphDriverNameSet = true setField = true + graphDriverChanged = true } if config.GraphDriverOptions != nil { - rt.storageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions)) - copy(rt.storageConfig.GraphDriverOptions, config.GraphDriverOptions) + if graphDriverChanged { + rt.storageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions)) + copy(rt.storageConfig.GraphDriverOptions, config.GraphDriverOptions) + } else { + // append new options after what is specified in the config files + rt.storageConfig.GraphDriverOptions = append(rt.storageConfig.GraphDriverOptions, config.GraphDriverOptions...) + } setField = true } diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 301c4627d..19690d79b 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -22,7 +22,6 @@ import ( "github.com/docker/go-units" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -179,10 +178,6 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf } func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) { - span, _ := opentracing.StartSpanFromContext(ctx, "newContainer") - span.SetTag("type", "runtime") - defer span.Finish() - ctr, err := r.initContainerVariables(rSpec, nil) if err != nil { return nil, errors.Wrapf(err, "error initializing container variables") @@ -472,10 +467,6 @@ func (r *Runtime) RemoveContainer(ctx context.Context, c *Container, force bool, // infra container protections, and *not* remove from the database (as pod // remove will handle that). func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, removeVolume, removePod bool) error { - span, _ := opentracing.StartSpanFromContext(ctx, "removeContainer") - span.SetTag("type", "runtime") - defer span.Finish() - if !c.valid { if ok, _ := r.state.HasContainer(c.ID()); !ok { // Container probably already removed @@ -723,7 +714,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol id, err := r.state.LookupContainerID(idOrName) if err != nil { - return "", errors.Wrapf(err, "failed to find container %q in state", idOrName) + return "", err } // Begin by trying a normal removal. Valid containers will be removed normally. @@ -753,7 +744,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol return id, err } if !exists { - return id, errors.Wrapf(err, "failed to find container ID %q for eviction", id) + return id, err } // Re-create a container struct for removal purposes diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 6e1105b9e..90b11f8ca 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -316,7 +316,8 @@ func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io } { src, err := referenceFn() if err == nil && src != nil { - if newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer); err == nil { + newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer) + if err == nil { return getImageNames(newImages), nil } saveErr = err @@ -325,6 +326,15 @@ func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io return "", errors.Wrapf(saveErr, "error pulling image") } +// RemoveImageFromStorage goes directly to storage and attempts to remove +// the specified image. This is dangerous and should only be done if libpod +// reports that image is not known. This call is useful if you have a corrupted +// image that was never fully added to the libpod database. +func (r *Runtime) RemoveImageFromStorage(id string) error { + _, err := r.store.DeleteImage(id, true) + return err +} + func getImageNames(images []*image.Image) string { var names string for i := range images { diff --git a/libpod/runtime_img_test.go b/libpod/runtime_img_test.go index 7d6390c85..c25f3f08c 100644 --- a/libpod/runtime_img_test.go +++ b/libpod/runtime_img_test.go @@ -37,7 +37,7 @@ func TestGetRegistries(t *testing.T) { registryPath, err := createTmpFile([]byte(registry)) assert.NoError(t, err) defer os.Remove(registryPath) - os.Setenv("REGISTRIES_CONFIG_PATH", registryPath) + os.Setenv("CONTAINERS_REGISTRIES_CONF", registryPath) registries, err := sysreg.GetRegistries() assert.NoError(t, err) assert.True(t, reflect.DeepEqual(registries, []string{"one"})) @@ -46,7 +46,7 @@ func TestGetRegistries(t *testing.T) { func TestGetInsecureRegistries(t *testing.T) { registryPath, err := createTmpFile([]byte(registry)) assert.NoError(t, err) - os.Setenv("REGISTRIES_CONFIG_PATH", registryPath) + os.Setenv("CONTAINERS_REGISTRIES_CONF", registryPath) defer os.Remove(registryPath) registries, err := sysreg.GetInsecureRegistries() assert.NoError(t, err) diff --git a/libpod/storage.go b/libpod/storage.go index 418eb3151..4aa42dc8e 100644 --- a/libpod/storage.go +++ b/libpod/storage.go @@ -10,7 +10,6 @@ import ( "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" v1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -67,10 +66,6 @@ func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) { // CreateContainerStorage creates the storage end of things. We already have the container spec created // TO-DO We should be passing in an Image object in the future. func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID string, options storage.ContainerOptions) (_ ContainerInfo, retErr error) { - span, _ := opentracing.StartSpanFromContext(ctx, "createContainerStorage") - span.SetTag("type", "storageService") - defer span.Finish() - var imageConfig *v1.Image if imageName != "" { var ref types.ImageReference |