diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal.go | 6 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 27 | ||||
-rw-r--r-- | libpod/define/config.go | 4 | ||||
-rw-r--r-- | libpod/define/errors.go | 3 | ||||
-rw-r--r-- | libpod/define/pod_inspect.go | 2 | ||||
-rw-r--r-- | libpod/healthcheck.go | 2 | ||||
-rw-r--r-- | libpod/image/docker_registry_options.go | 3 | ||||
-rw-r--r-- | libpod/image/image.go | 112 | ||||
-rw-r--r-- | libpod/image/manifests.go | 6 | ||||
-rw-r--r-- | libpod/image/prune.go | 22 | ||||
-rw-r--r-- | libpod/image/pull.go | 4 | ||||
-rw-r--r-- | libpod/networking_linux.go | 14 | ||||
-rw-r--r-- | libpod/options.go | 7 | ||||
-rw-r--r-- | libpod/pod.go | 21 | ||||
-rw-r--r-- | libpod/pod_api.go | 7 | ||||
-rw-r--r-- | libpod/runtime.go | 5 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 3 | ||||
-rw-r--r-- | libpod/runtime_img.go | 6 | ||||
-rw-r--r-- | libpod/runtime_pod.go | 3 |
19 files changed, 192 insertions, 65 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 50bd9bc25..3fcf687ec 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -19,7 +19,7 @@ import ( "github.com/containers/libpod/pkg/hooks" "github.com/containers/libpod/pkg/hooks/exec" "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/util" + "github.com/containers/libpod/pkg/selinux" "github.com/containers/storage" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/mount" @@ -435,12 +435,12 @@ func (c *Container) setupStorage(ctx context.Context) error { processLabel := containerInfo.ProcessLabel switch { case c.ociRuntime.SupportsKVM(): - processLabel, err = util.SELinuxKVMLabel(processLabel) + processLabel, err = selinux.KVMLabel(processLabel) if err != nil { return err } case c.config.Systemd: - processLabel, err = util.SELinuxInitLabel(processLabel) + processLabel, err = selinux.InitLabel(processLabel) if err != nil { return err } diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index c40ad45b9..8ee0fb456 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -20,11 +20,11 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" "github.com/containers/buildah/pkg/secrets" + "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/pkg/annotations" - "github.com/containers/libpod/pkg/apparmor" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/criu" "github.com/containers/libpod/pkg/lookup" @@ -385,6 +385,16 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { g.AddLinuxGIDMapping(uint32(0), uint32(0), uint32(1)) } } + + for _, i := range c.config.Spec.Linux.Namespaces { + if i.Type == spec.UTSNamespace { + hostname := c.Hostname() + g.SetHostname(hostname) + g.AddProcessEnv("HOSTNAME", hostname) + break + } + } + if c.config.UTSNsCtr != "" { if err := c.addNamespaceContainer(&g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil { return nil, err @@ -418,15 +428,6 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { g.AddAnnotation(annotations.ContainerManager, annotations.ContainerManagerLibpod) } - for _, i := range c.config.Spec.Linux.Namespaces { - if i.Type == spec.UTSNamespace { - hostname := c.Hostname() - g.SetHostname(hostname) - g.AddProcessEnv("HOSTNAME", hostname) - break - } - } - // Only add container environment variable if not already present foundContainerEnv := false for _, env := range g.Config.Process.Env { @@ -583,6 +584,12 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr return errors.Wrapf(err, "error retrieving dependency %s of container %s from state", ctr, c.ID()) } + if specNS == spec.UTSNamespace { + hostname := nsCtr.Hostname() + g.SetHostname(hostname) + g.AddProcessEnv("HOSTNAME", hostname) + } + // TODO need unlocked version of this for use in pods nsPath, err := nsCtr.NamespacePath(ns) if err != nil { diff --git a/libpod/define/config.go b/libpod/define/config.go index 17d764c65..692eafb04 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -6,10 +6,6 @@ import ( ) var ( - // DefaultInfraImage to use for infra container - DefaultInfraImage = "k8s.gcr.io/pause:3.2" - // DefaultInfraCommand to be run in an infra container - DefaultInfraCommand = "/pause" // DefaultSHMLockPath is the default path for SHM locks DefaultSHMLockPath = "/libpod_lock" // DefaultRootlessSHMLockPath is the default path for rootless SHM locks diff --git a/libpod/define/errors.go b/libpod/define/errors.go index 3ba343789..16df2a1cc 100644 --- a/libpod/define/errors.go +++ b/libpod/define/errors.go @@ -141,4 +141,7 @@ var ( // ErrConmonOutdated indicates the version of conmon found (whether via the configuration or $PATH) // is out of date for the current podman version ErrConmonOutdated = errors.New("outdated conmon version") + + // ErrImageInUse indicates the requested operation failed because the image was in use + ErrImageInUse = errors.New("image is being used") ) diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go index 8558c149b..26fd2cab4 100644 --- a/libpod/define/pod_inspect.go +++ b/libpod/define/pod_inspect.go @@ -18,6 +18,8 @@ type InspectPodData struct { Namespace string `json:"Namespace,omitempty"` // Created is the time when the pod was created. Created time.Time + // State represents the current state of the pod. + State string `json:"State"` // Hostname is the hostname that the pod will set. Hostname string // Labels is a set of key-value labels that have been applied to the diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go index daddb6561..aec5fa4e0 100644 --- a/libpod/healthcheck.go +++ b/libpod/healthcheck.go @@ -238,7 +238,7 @@ func (c *Container) updateHealthCheckLog(hcl define.HealthCheckLog, inStartPerio // HealthCheckLogPath returns the path for where the health check log is func (c *Container) healthCheckLogPath() string { - return filepath.Join(filepath.Dir(c.LogPath()), "healthcheck.log") + return filepath.Join(filepath.Dir(c.state.RunDir), "healthcheck.log") } // GetHealthCheckLog returns HealthCheck results by reading the container's diff --git a/libpod/image/docker_registry_options.go b/libpod/image/docker_registry_options.go index 62a4af465..01b5558af 100644 --- a/libpod/image/docker_registry_options.go +++ b/libpod/image/docker_registry_options.go @@ -3,9 +3,9 @@ package image import ( "fmt" + "github.com/containers/buildah/pkg/parse" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" - podmanVersion "github.com/containers/libpod/version" ) @@ -41,6 +41,7 @@ func (o DockerRegistryOptions) GetSystemContext(parent *types.SystemContext, add DockerArchiveAdditionalTags: additionalDockerArchiveTags, OSChoice: o.OSChoice, ArchitectureChoice: o.ArchitectureChoice, + BigFilesTemporaryDir: parse.GetTempDir(), } if parent != nil { sc.SignaturePolicyPath = parent.SignaturePolicyPath diff --git a/libpod/image/image.go b/libpod/image/image.go index 80cc6f15a..60787b826 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -32,10 +32,10 @@ import ( "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" - "github.com/opencontainers/go-digest" + digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/opentracing/opentracing-go" + opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -847,22 +847,97 @@ func (i *Image) Dangling() bool { return len(i.Names()) == 0 } +// Intermediate returns true if the image is cache or intermediate image. +// Cache image has parent and child. +func (i *Image) Intermediate(ctx context.Context) (bool, error) { + parent, err := i.IsParent(ctx) + if err != nil { + return false, err + } + if !parent { + return false, nil + } + img, err := i.GetParent(ctx) + if err != nil { + return false, err + } + if img != nil { + return true, nil + } + return false, nil +} + +// User returns the image's user +func (i *Image) User(ctx context.Context) (string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return "", err + } + return imgInspect.Config.User, nil +} + +// StopSignal returns the image's StopSignal +func (i *Image) StopSignal(ctx context.Context) (string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return "", err + } + return imgInspect.Config.StopSignal, nil +} + +// WorkingDir returns the image's WorkingDir +func (i *Image) WorkingDir(ctx context.Context) (string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return "", err + } + return imgInspect.Config.WorkingDir, nil +} + +// Cmd returns the image's cmd +func (i *Image) Cmd(ctx context.Context) ([]string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return nil, err + } + return imgInspect.Config.Cmd, nil +} + +// Entrypoint returns the image's entrypoint +func (i *Image) Entrypoint(ctx context.Context) ([]string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return nil, err + } + return imgInspect.Config.Entrypoint, nil +} + +// Env returns the image's env +func (i *Image) Env(ctx context.Context) ([]string, error) { + imgInspect, err := i.imageInspectInfo(ctx) + if err != nil { + return nil, err + } + return imgInspect.Env, nil +} + // Labels returns the image's labels func (i *Image) Labels(ctx context.Context) (map[string]string, error) { imgInspect, err := i.imageInspectInfo(ctx) if err != nil { - return nil, nil + return nil, err } return imgInspect.Labels, nil } // GetLabel Returns a case-insensitive match of a given label func (i *Image) GetLabel(ctx context.Context, label string) (string, error) { - imageLabels, err := i.Labels(ctx) + labels, err := i.Labels(ctx) if err != nil { return "", err } - for k, v := range imageLabels { + + for k, v := range labels { if strings.ToLower(k) == strings.ToLower(label) { return v, nil } @@ -1412,14 +1487,14 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag } manifestType = manifest.DockerV2Schema2MediaType case "docker-archive", "": - dst := output destImageName := imageNameForSaveDestination(i, source) - if destImageName != "" { - dst = fmt.Sprintf("%s:%s", dst, destImageName) + ref, err := dockerArchiveDstReference(destImageName) + if err != nil { + return err } - destRef, err = dockerarchive.ParseReference(dst) // FIXME? Add dockerarchive.NewReference + destRef, err = dockerarchive.NewReference(output, ref) if err != nil { - return errors.Wrapf(err, "error getting Docker archive ImageReference for %q", dst) + return errors.Wrapf(err, "error getting Docker archive ImageReference for %s:%v", output, ref) } default: return errors.Errorf("unknown format option %q", format) @@ -1439,6 +1514,23 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag return nil } +// dockerArchiveDestReference returns a NamedTagged reference for a tagged image and nil for untagged image. +func dockerArchiveDstReference(normalizedInput string) (reference.NamedTagged, error) { + if normalizedInput == "" { + return nil, nil + } + ref, err := reference.ParseNormalizedNamed(normalizedInput) + if err != nil { + return nil, errors.Wrapf(err, "docker-archive parsing reference %s", normalizedInput) + } + ref = reference.TagNameOnly(ref) + namedTagged, isTagged := ref.(reference.NamedTagged) + if !isTagged { + namedTagged = nil + } + return namedTagged, nil +} + // GetConfigBlob returns a schema2image. If the image is not a schema2, then // it will return an error func (i *Image) GetConfigBlob(ctx context.Context) (*manifest.Schema2Image, error) { diff --git a/libpod/image/manifests.go b/libpod/image/manifests.go index 9dbeb4cc5..7ca17f86c 100644 --- a/libpod/image/manifests.go +++ b/libpod/image/manifests.go @@ -19,6 +19,7 @@ type ManifestAddOpts struct { Arch string `json:"arch"` Features []string `json:"features"` Images []string `json:"images"` + OS string `json:"os"` OSVersion string `json:"os_version"` Variant string `json:"variant"` } @@ -86,6 +87,11 @@ func addManifestToList(ref types.ImageReference, list manifests.List, systemCont if err != nil { return nil, err } + if opts.OS != "" { + if err := list.SetOS(d, opts.OS); err != nil { + return nil, err + } + } if len(opts.OSVersion) > 0 { if err := list.SetOSVersion(d, opts.OSVersion); err != nil { return nil, err diff --git a/libpod/image/prune.go b/libpod/image/prune.go index 3afff22af..3b4ea74c4 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -57,7 +57,7 @@ func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) { } // GetPruneImages returns a slice of images that have no names/unused -func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image, error) { +func (ir *Runtime) GetPruneImages(ctx context.Context, all bool, filterFuncs []ImageFilter) ([]*Image, error) { var ( pruneImages []*Image ) @@ -74,10 +74,6 @@ func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image } } - if len(i.Names()) == 0 { - pruneImages = append(pruneImages, i) - continue - } if all { containers, err := i.Containers() if err != nil { @@ -85,8 +81,22 @@ func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image } if len(containers) < 1 { pruneImages = append(pruneImages, i) + continue } } + + //skip the cache or intermediate images + intermediate, err := i.Intermediate(ctx) + if err != nil { + return nil, err + } + if intermediate { + continue + } + + if i.Dangling() { + pruneImages = append(pruneImages, i) + } } return pruneImages, nil } @@ -111,7 +121,7 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ( filterFuncs = append(filterFuncs, generatedFunc) } - pruneImages, err := ir.GetPruneImages(all, filterFuncs) + pruneImages, err := ir.GetPruneImages(ctx, all, filterFuncs) if err != nil { return nil, errors.Wrap(err, "unable to get images to prune") } diff --git a/libpod/image/pull.go b/libpod/image/pull.go index fd359d593..6b4c40ba2 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -334,11 +334,11 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa // If the image passed in was fully-qualified, we will have 1 refpair. Bc the image is fq'd, we don't need to yap about registries. if !goal.usedSearchRegistries { if pullErrors != nil && len(pullErrors.Errors) > 0 { // this should always be true - return nil, errors.Wrap(pullErrors.Errors[0], "unable to pull image") + return nil, pullErrors.Errors[0] } return nil, errors.Errorf("unable to pull image, or you do not have pull access") } - return nil, pullErrors + return nil, errors.Cause(pullErrors) } if len(images) > 0 { ir.newImageEvent(events.Pull, images[0]) diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index c3a90f481..83344ebbe 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -101,7 +101,19 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re requestedMAC = ctr.config.StaticMAC } - podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP, requestedMAC) + // If we are in a pod use the pod name for the network, otherwise the container name + var podName string + if ctr.PodID() != "" { + pod, err := r.GetPod(ctr.PodID()) + if err == nil { + podName = pod.Name() + } + } + if podName == "" { + podName = ctr.Name() + } + + podNetwork := r.getPodNetwork(ctr.ID(), podName, ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP, requestedMAC) results, err := r.netPlugin.SetUpPod(podNetwork) if err != nil { diff --git a/libpod/options.go b/libpod/options.go index b4e436b63..33b423bce 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1400,8 +1400,13 @@ func WithVolumeDriver(driver string) VolumeCreateOption { if volume.valid { return define.ErrVolumeFinalized } + // only local driver is possible rn + if driver != define.VolumeDriverLocal { + return define.ErrNotImplemented - return define.ErrNotImplemented + } + volume.config.Driver = define.VolumeDriverLocal + return nil } } diff --git a/libpod/pod.go b/libpod/pod.go index 4cdeb1033..b5a14c165 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -76,27 +76,6 @@ type podState struct { InfraContainerID string } -// PodInspect represents the data we want to display for -// podman pod inspect -type PodInspect struct { - Config *PodConfig - State *PodInspectState - Containers []PodContainerInfo -} - -// PodInspectState contains inspect data on the pod's state -type PodInspectState struct { - CgroupPath string `json:"cgroupPath"` - InfraContainerID string `json:"infraContainerID"` - Status string `json:"status"` -} - -// PodContainerInfo keeps information on a container in a pod -type PodContainerInfo struct { - ID string `json:"id"` - State string `json:"state"` -} - // InfraContainerConfig is the configuration for the pod's infra container type InfraContainerConfig struct { HasInfraContainer bool `json:"makeInfraContainer"` diff --git a/libpod/pod_api.go b/libpod/pod_api.go index ed4dc0727..45aa5cb8d 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -446,6 +446,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { if err != nil { return nil, err } + ctrStatuses := make(map[string]define.ContainerStatus, len(containers)) for _, c := range containers { containerStatus := "unknown" // Ignoring possible errors here because we don't want this to be @@ -459,12 +460,18 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { Name: c.Name(), State: containerStatus, }) + ctrStatuses[c.ID()] = c.state.State + } + podState, err := CreatePodStatusResults(ctrStatuses) + if err != nil { + return nil, err } inspectData := define.InspectPodData{ ID: p.ID(), Name: p.Name(), Namespace: p.Namespace(), Created: p.CreatedTime(), + State: podState, Hostname: "", Labels: p.Labels(), CreateCgroup: false, diff --git a/libpod/runtime.go b/libpod/runtime.go index 3b8f9e057..e71483ef9 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -733,6 +733,11 @@ func (r *Runtime) StorageConfig() storage.StoreOptions { return r.storageConfig } +// GetStore returns the runtime stores +func (r *Runtime) GetStore() storage.Store { + return r.store +} + // DBConfig is a set of Libpod runtime configuration settings that are saved in // a State when it is first created, and can subsequently be retrieved. type DBConfig struct { diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 3dc8d3d0f..1d880531e 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -869,7 +869,8 @@ func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) (map[string]int logrus.Error(err) return false } - if state == define.ContainerStateStopped || state == define.ContainerStateExited { + if state == define.ContainerStateStopped || state == define.ContainerStateExited || + state == define.ContainerStateCreated || state == define.ContainerStateConfigured { return true } return false diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 6ac32878b..919080c42 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -71,7 +71,8 @@ func (r *Runtime) RemoveImage(ctx context.Context, img *image.Image, force bool) // to and untag it. repoName, err := img.MatchRepoTag(img.InputName) if hasChildren && errors.Cause(err) == image.ErrRepoTagNotFound { - return nil, errors.Errorf("unable to delete %q (cannot be forced) - image has dependent child images", img.ID()) + return nil, errors.Wrapf(define.ErrImageInUse, + "unable to delete %q (cannot be forced) - image has dependent child images", img.ID()) } if err != nil { return nil, err @@ -84,7 +85,8 @@ func (r *Runtime) RemoveImage(ctx context.Context, img *image.Image, force bool) } else if len(img.Names()) > 1 && img.InputIsID() && !force { // If the user requests to delete an image by ID and the image has multiple // reponames and no force is applied, we error out. - return nil, fmt.Errorf("unable to delete %s (must force) - image is referred to in multiple tags", img.ID()) + return nil, errors.Wrapf(define.ErrImageInUse, + "unable to delete %s (must force) - image is referred to in multiple tags", img.ID()) } err = img.Remove(ctx, force) if err != nil && errors.Cause(err) == storage.ErrImageUsedByContainer { diff --git a/libpod/runtime_pod.go b/libpod/runtime_pod.go index be566e211..5b81e166a 100644 --- a/libpod/runtime_pod.go +++ b/libpod/runtime_pod.go @@ -176,8 +176,7 @@ func (r *Runtime) GetRunningPods() ([]*Pod, error) { } // PrunePods removes unused pods and their containers from local storage. -// If force is given, then running pods are also included in the pruning. -func (r *Runtime) PrunePods() (map[string]error, error) { +func (r *Runtime) PrunePods(ctx context.Context) (map[string]error, error) { response := make(map[string]error) states := []string{define.PodStateStopped, define.PodStateExited} filterFunc := func(p *Pod) bool { |