diff options
author | baude <bbaude@redhat.com> | 2019-01-11 10:33:25 -0600 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2019-01-30 08:44:58 -0600 |
commit | 735f0de6336fa8db7465ce4aaa5b6de203816aa9 (patch) | |
tree | 25ec04f14357a7a65aed89b3ca5d5a33c45d6ef5 /libpod/image/pull.go | |
parent | b71088a01e1e43b87214aaca87c73865fa3b990e (diff) | |
download | podman-735f0de6336fa8db7465ce4aaa5b6de203816aa9.tar.gz podman-735f0de6336fa8db7465ce4aaa5b6de203816aa9.tar.bz2 podman-735f0de6336fa8db7465ce4aaa5b6de203816aa9.zip |
Changes to container runlabel for toolbox project
The toolbox project would benefit from a few changes to more closely
resembe the original atomic cli project. Changes made are:
* only pull image for container runlabel if the label exists in the image
* if a container image does not have the desired label, exit with non-zero
Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'libpod/image/pull.go')
-rw-r--r-- | libpod/image/pull.go | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 434b83520..6fef96e37 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "strings" cp "github.com/containers/image/copy" "github.com/containers/image/directory" @@ -192,7 +193,7 @@ func (ir *Runtime) pullGoalFromImageReference(ctx context.Context, srcRef types. // 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) ([]string, error) { +func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName string, writer io.Writer, authfile, signaturePolicyPath string, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, label *string) ([]string, error) { var goal *pullGoal sc := GetSystemContext(signaturePolicyPath, authfile, false) srcRef, err := alltransports.ParseImageName(inputName) @@ -208,7 +209,7 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s return nil, errors.Wrapf(err, "error determining pull goal for image %q", inputName) } } - return ir.doPullImage(ctx, sc, *goal, writer, signingOptions, dockerOptions) + return ir.doPullImage(ctx, sc, *goal, writer, signingOptions, dockerOptions, label) } // pullImageFromReference pulls an image from a types.imageReference. @@ -218,11 +219,11 @@ func (ir *Runtime) pullImageFromReference(ctx context.Context, srcRef types.Imag if err != nil { return nil, errors.Wrapf(err, "error determining pull goal for image %q", transports.ImageName(srcRef)) } - return ir.doPullImage(ctx, sc, *goal, writer, signingOptions, dockerOptions) + return ir.doPullImage(ctx, sc, *goal, writer, signingOptions, dockerOptions, nil) } // 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) ([]string, error) { +func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goal pullGoal, writer io.Writer, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, label *string) ([]string, error) { policyContext, err := getPolicyContext(sc) if err != nil { return nil, err @@ -230,8 +231,12 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa defer policyContext.Destroy() systemRegistriesConfPath := registries.SystemRegistriesConfPath() - var images []string - var pullErrors *multierror.Error + + var ( + images []string + pullErrors *multierror.Error + ) + for _, imageInfo := range goal.refPairs { copyOptions := getCopyOptions(sc, writer, dockerOptions, nil, signingOptions, "", nil) copyOptions.SourceCtx.SystemRegistriesConfPath = 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. @@ -239,6 +244,13 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa if writer != nil && (imageInfo.srcRef.Transport().Name() == DockerTransport || imageInfo.srcRef.Transport().Name() == AtomicTransport) { io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image)) } + // If the label is not nil, check if the label exists and if not, return err + if label != nil { + if err := checkRemoteImageForLabel(ctx, *label, imageInfo, sc); err != nil { + return nil, err + } + } + _, err = cp.Image(ctx, policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions) if err != nil { pullErrors = multierror.Append(pullErrors, err) @@ -314,3 +326,23 @@ func (ir *Runtime) pullGoalFromPossiblyUnqualifiedName(inputName string) (*pullG searchedRegistries: searchRegistries, }, nil } + +// checkRemoteImageForLabel checks if the remote image has a specific label. if the label exists, we +// return nil, else we return an error +func checkRemoteImageForLabel(ctx context.Context, label string, imageInfo pullRefPair, sc *types.SystemContext) error { + labelImage, err := imageInfo.srcRef.NewImage(ctx, sc) + if err != nil { + return err + } + remoteInspect, err := labelImage.Inspect(ctx) + if err != nil { + return err + } + // Labels are case insensitive; so we iterate instead of simple lookup + for k := range remoteInspect.Labels { + if strings.ToLower(label) == strings.ToLower(k) { + return nil + } + } + return errors.Errorf("%s has no label %s", imageInfo.image, label) +} |