diff options
Diffstat (limited to 'pkg/domain/infra/abi')
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 116 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 14 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images_list.go | 24 | ||||
-rw-r--r-- | pkg/domain/infra/abi/manifest.go | 85 | ||||
-rw-r--r-- | pkg/domain/infra/abi/network.go | 16 | ||||
-rw-r--r-- | pkg/domain/infra/abi/play.go | 18 | ||||
-rw-r--r-- | pkg/domain/infra/abi/system_varlink.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/terminal/terminal.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/volumes.go | 2 |
9 files changed, 184 insertions, 95 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 21618f555..8b0d53940 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -1142,12 +1142,12 @@ func (ic *ContainerEngine) Shutdown(_ context.Context) { }) } -func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) error { - defer close(options.StatChan) +func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) { + statsChan = make(chan entities.ContainerStatsReport, 1) + containerFunc := ic.Libpod.GetRunningContainers + queryAll := false switch { - case len(namesOrIds) > 0: - containerFunc = func() ([]*libpod.Container, error) { return ic.Libpod.GetContainersByList(namesOrIds) } case options.Latest: containerFunc = func() ([]*libpod.Container, error) { lastCtr, err := ic.Libpod.GetLatestContainer() @@ -1156,62 +1156,76 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri } return []*libpod.Container{lastCtr}, nil } - case options.All: + case len(namesOrIds) > 0: + containerFunc = func() ([]*libpod.Container, error) { return ic.Libpod.GetContainersByList(namesOrIds) } + default: + // No containers, no latest -> query all! + queryAll = true containerFunc = ic.Libpod.GetAllContainers } - ctrs, err := containerFunc() - if err != nil { - return errors.Wrapf(err, "unable to get list of containers") - } - containerStats := map[string]*define.ContainerStats{} - for _, ctr := range ctrs { - initialStats, err := ctr.GetContainerStats(&define.ContainerStats{}) - if err != nil { - // when doing "all", don't worry about containers that are not running - cause := errors.Cause(err) - if options.All && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) { - continue - } - if cause == cgroups.ErrCgroupV1Rootless { - err = cause - } - return err + go func() { + defer close(statsChan) + var ( + err error + containers []*libpod.Container + containerStats map[string]*define.ContainerStats + ) + containerStats = make(map[string]*define.ContainerStats) + + stream: // label to flatten the scope + select { + case <-ctx.Done(): + // client cancelled + logrus.Debugf("Container stats stopped: context cancelled") + return + default: + // just fall through and do work } - containerStats[ctr.ID()] = initialStats - } - for { - reportStats := []*define.ContainerStats{} - for _, ctr := range ctrs { - id := ctr.ID() - if _, ok := containerStats[ctr.ID()]; !ok { - initialStats, err := ctr.GetContainerStats(&define.ContainerStats{}) - if errors.Cause(err) == define.ErrCtrRemoved || errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == define.ErrCtrStateInvalid { - // skip dealing with a container that is gone - continue + + // Anonymous func to easily use the return values for streaming. + computeStats := func() ([]define.ContainerStats, error) { + containers, err = containerFunc() + if err != nil { + return nil, errors.Wrapf(err, "unable to get list of containers") + } + + reportStats := []define.ContainerStats{} + for _, ctr := range containers { + prev, ok := containerStats[ctr.ID()] + if !ok { + prev = &define.ContainerStats{} } + + stats, err := ctr.GetContainerStats(prev) if err != nil { - return err + cause := errors.Cause(err) + if queryAll && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) { + continue + } + if cause == cgroups.ErrCgroupV1Rootless { + err = cause + } + return nil, err } - containerStats[id] = initialStats - } - stats, err := ctr.GetContainerStats(containerStats[id]) - if err != nil && errors.Cause(err) != define.ErrNoSuchCtr { - return err + + containerStats[ctr.ID()] = stats + reportStats = append(reportStats, *stats) } - // replace the previous measurement with the current one - containerStats[id] = stats - reportStats = append(reportStats, stats) + return reportStats, nil } - ctrs, err = containerFunc() - if err != nil { - return err - } - options.StatChan <- reportStats - if options.NoStream { - break + + report := entities.ContainerStatsReport{} + report.Stats, report.Error = computeStats() + statsChan <- report + + if report.Error != nil || !options.Stream { + return } + time.Sleep(time.Second) - } - return nil + goto stream + }() + + return statsChan, nil } diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 23aef9573..d56dc7d94 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -191,6 +191,15 @@ func (ir *ImageEngine) Unmount(ctx context.Context, nameOrIDs []string, options reports := []*entities.ImageUnmountReport{} for _, img := range images { report := entities.ImageUnmountReport{Id: img.ID()} + mounted, _, err := img.Mounted() + if err != nil { + // Errors will be caught in Unmount call below + // Default assumption to mounted + mounted = true + } + if !mounted { + continue + } if err := img.Unmount(options.Force); err != nil { if options.All && errors.Cause(err) == storage.ErrLayerNotMounted { logrus.Debugf("Error umounting image %s, storage.ErrLayerNotMounted", img.ID()) @@ -246,7 +255,7 @@ func pull(ctx context.Context, runtime *image.Runtime, rawImage string, options } if !options.AllTags { - newImage, err := runtime.New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, label, util.PullImageAlways) + newImage, err := runtime.New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, label, options.PullPolicy) if err != nil { return nil, err } @@ -467,7 +476,7 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) } func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) { - id, err := ir.Libpod.Import(ctx, opts.Source, opts.Reference, opts.Changes, opts.Message, opts.Quiet) + id, err := ir.Libpod.Import(ctx, opts.Source, opts.Reference, opts.SignaturePolicy, opts.Changes, opts.Message, opts.Quiet) if err != nil { return nil, err } @@ -535,6 +544,7 @@ func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { } func (ir *ImageEngine) Build(ctx context.Context, containerFiles []string, opts entities.BuildOptions) (*entities.BuildReport, error) { + id, _, err := ir.Libpod.Build(ctx, opts.BuildOptions, containerFiles...) if err != nil { return nil, err diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go index 7ec84246d..3e47dc67a 100644 --- a/pkg/domain/infra/abi/images_list.go +++ b/pkg/domain/infra/abi/images_list.go @@ -23,33 +23,13 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) summaries := []*entities.ImageSummary{} for _, img := range images { - var repoTags []string - if opts.All { - pairs, err := libpodImage.ReposToMap(img.Names()) - if err != nil { - return nil, err - } - - for repo, tags := range pairs { - for _, tag := range tags { - repoTags = append(repoTags, repo+":"+tag) - } - } - } else { - repoTags, err = img.RepoTags() - if err != nil { - return nil, err - } - } - digests := make([]string, len(img.Digests())) for j, d := range img.Digests() { digests[j] = string(d) } e := entities.ImageSummary{ - ID: img.ID(), - + ID: img.ID(), ConfigDigest: string(img.ConfigDigest), Created: img.Created().Unix(), Dangling: img.Dangling(), @@ -61,7 +41,7 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ReadOnly: img.IsReadOnly(), SharedSize: 0, VirtualSize: img.VirtualSize, - RepoTags: repoTags, + RepoTags: img.Names(), // may include tags and digests } e.Labels, _ = img.Labels(context.TODO()) diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go index 672d0a69f..6c518e678 100644 --- a/pkg/domain/infra/abi/manifest.go +++ b/pkg/domain/infra/abi/manifest.go @@ -3,6 +3,7 @@ package abi import ( + "bytes" "context" "encoding/json" "fmt" @@ -11,15 +12,17 @@ import ( "strings" "github.com/containers/buildah/manifests" + buildahManifests "github.com/containers/buildah/pkg/manifests" + "github.com/containers/buildah/util" buildahUtil "github.com/containers/buildah/util" cp "github.com/containers/image/v5/copy" "github.com/containers/image/v5/docker" "github.com/containers/image/v5/manifest" + "github.com/containers/image/v5/transports" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" libpodImage "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/pkg/domain/entities" - "github.com/containers/podman/v2/pkg/util" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" @@ -41,28 +44,82 @@ func (ir *ImageEngine) ManifestCreate(ctx context.Context, names, images []strin // ManifestInspect returns the content of a manifest list or image func (ir *ImageEngine) ManifestInspect(ctx context.Context, name string) ([]byte, error) { - dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name()) - _, err := alltransports.ParseImageName(name) + if newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(name); err == nil { + // return the manifest in local storage + if list, err := newImage.InspectManifest(); err == nil { + buf, err := json.MarshalIndent(list, "", " ") + if err != nil { + return buf, errors.Wrapf(err, "error rendering manifest %s for display", name) + } + return buf, nil + // no return if local image is not a list of images type + // continue on getting valid manifest through remote serice + } else if errors.Cause(err) != buildahManifests.ErrManifestTypeNotSupported { + return nil, errors.Wrapf(err, "loading manifest %q", name) + } + } + sc := ir.Libpod.SystemContext() + refs, err := util.ResolveNameToReferences(ir.Libpod.GetStore(), sc, name) if err != nil { - _, err = alltransports.ParseImageName(dockerPrefix + name) + return nil, err + } + var ( + latestErr error + result []byte + manType string + b bytes.Buffer + ) + appendErr := func(e error) { + if latestErr == nil { + latestErr = e + } else { + latestErr = errors.Wrapf(latestErr, "tried %v\n", e) + } + } + for _, ref := range refs { + src, err := ref.NewImageSource(ctx, sc) + if err != nil { + appendErr(errors.Wrapf(err, "reading image %q", transports.ImageName(ref))) + continue + } + defer src.Close() + + manifestBytes, manifestType, err := src.GetManifest(ctx, nil) if err != nil { - return nil, errors.Errorf("invalid image reference %q", name) + appendErr(errors.Wrapf(err, "loading manifest %q", transports.ImageName(ref))) + continue } + + if !manifest.MIMETypeIsMultiImage(manifestType) { + appendErr(errors.Errorf("manifest is of type %s (not a list type)", manifestType)) + continue + } + result = manifestBytes + manType = manifestType + break } - image, err := ir.Libpod.ImageRuntime().New(ctx, name, "", "", nil, nil, libpodImage.SigningOptions{}, nil, util.PullImageMissing) - if err != nil { - return nil, errors.Wrapf(err, "reading image %q", name) + if len(result) == 0 && latestErr != nil { + return nil, latestErr } + if manType != manifest.DockerV2ListMediaType { + listBlob, err := manifest.ListFromBlob(result, manType) + if err != nil { + return nil, errors.Wrapf(err, "error parsing manifest blob %q as a %q", string(result), manType) + } + list, err := listBlob.ConvertToMIMEType(manifest.DockerV2ListMediaType) + if err != nil { + return nil, err + } + if result, err = list.Serialize(); err != nil { + return nil, err + } - list, err := image.InspectManifest() - if err != nil { - return nil, errors.Wrapf(err, "loading manifest %q", name) } - buf, err := json.MarshalIndent(list, "", " ") + err = json.Indent(&b, result, "", " ") if err != nil { - return buf, errors.Wrapf(err, "error rendering manifest for display") + return nil, errors.Wrapf(err, "error rendering manifest %s for display", name) } - return buf, nil + return b.Bytes(), nil } // ManifestAdd adds images to the manifest list diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 807e4b272..5acfea853 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -12,6 +12,7 @@ import ( "github.com/containernetworking/cni/libcni" cniversion "github.com/containernetworking/cni/pkg/version" "github.com/containers/podman/v2/libpod" + "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/network" "github.com/containers/podman/v2/pkg/util" @@ -82,12 +83,21 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o // We need to iterate containers looking to see if they belong to the given network for _, c := range containers { if util.StringInSlice(name, c.Config().Networks) { - // if user passes force, we nuke containers + // if user passes force, we nuke containers and pods if !options.Force { // Without the force option, we return an error - return reports, errors.Errorf("%q has associated containers with it. Use -f to forcibly delete containers", name) + return reports, errors.Wrapf(define.ErrNetworkInUse, "%q has associated containers with it. Use -f to forcibly delete containers and pods", name) } - if err := ic.Libpod.RemoveContainer(ctx, c, true, true); err != nil { + if c.IsInfra() { + // if we have a infra container we need to remove the pod + pod, err := ic.Libpod.GetPod(c.PodID()) + if err != nil { + return reports, err + } + if err := ic.Libpod.RemovePod(ctx, pod, true, true); err != nil { + return reports, err + } + } else if err := ic.Libpod.RemoveContainer(ctx, c, true, true); err != nil { return reports, err } } diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 6dfb52c63..aa6aeede2 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -132,6 +132,11 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY libpod.WithInfraContainer(), libpod.WithPodName(podName), } + + if podYAML.ObjectMeta.Labels != nil { + podOptions = append(podOptions, libpod.WithPodLabels(podYAML.ObjectMeta.Labels)) + } + // TODO we only configure Process namespace. We also need to account for Host{IPC,Network,PID} // which is not currently possible with pod create if podYAML.Spec.ShareProcessNamespace != nil && *podYAML.Spec.ShareProcessNamespace { @@ -294,6 +299,18 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY return nil, err } + var ctrRestartPolicy string + switch podYAML.Spec.RestartPolicy { + case v1.RestartPolicyAlways: + ctrRestartPolicy = libpod.RestartPolicyAlways + case v1.RestartPolicyOnFailure: + ctrRestartPolicy = libpod.RestartPolicyOnFailure + case v1.RestartPolicyNever: + ctrRestartPolicy = libpod.RestartPolicyNo + default: // Default to Always + ctrRestartPolicy = libpod.RestartPolicyAlways + } + containers := make([]*libpod.Container, 0, len(podYAML.Spec.Containers)) for _, container := range podYAML.Spec.Containers { pullPolicy := util.PullImageMissing @@ -321,6 +338,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY if err != nil { return nil, err } + conf.RestartPolicy = ctrRestartPolicy ctr, err := createconfig.CreateContainerFromCreateConfig(ctx, ic.Libpod, conf, pod) if err != nil { return nil, err diff --git a/pkg/domain/infra/abi/system_varlink.go b/pkg/domain/infra/abi/system_varlink.go index d0a5c5407..ead84fc84 100644 --- a/pkg/domain/infra/abi/system_varlink.go +++ b/pkg/domain/infra/abi/system_varlink.go @@ -22,7 +22,7 @@ func (ic *ContainerEngine) VarlinkService(_ context.Context, opts entities.Servi service, err := varlink.NewService( "Atomic", "podman", - version.Version, + version.Version.String(), "https://github.com/containers/podman", ) if err != nil { diff --git a/pkg/domain/infra/abi/terminal/terminal.go b/pkg/domain/infra/abi/terminal/terminal.go index 0b6e57f49..48f5749d5 100644 --- a/pkg/domain/infra/abi/terminal/terminal.go +++ b/pkg/domain/infra/abi/terminal/terminal.go @@ -6,7 +6,7 @@ import ( "os/signal" lsignal "github.com/containers/podman/v2/pkg/signal" - "github.com/docker/docker/pkg/term" + "github.com/moby/term" "github.com/pkg/errors" "github.com/sirupsen/logrus" "k8s.io/client-go/tools/remotecommand" diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go index 340f00953..946f258af 100644 --- a/pkg/domain/infra/abi/volumes.go +++ b/pkg/domain/infra/abi/volumes.go @@ -120,7 +120,7 @@ func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []strin return reports, nil } -func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) { +func (ic *ContainerEngine) VolumePrune(ctx context.Context) ([]*entities.VolumePruneReport, error) { return ic.pruneVolumesHelper(ctx) } |