Skip to content

Commit 7bc3660

Browse files
committed
auto-update: validate container image
Auto updates using the "registry" policy require container to be created with a fully-qualified image reference. Short names are not supported due the ambiguity of their source registry. Initially, container creation errored out for non FQN images but it seems that Podman has regressed. Fixes: containers#15879 Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
1 parent 17f3756 commit 7bc3660

File tree

6 files changed

+67
-91
lines changed

6 files changed

+67
-91
lines changed

libpod/container_validate.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package libpod
33
import (
44
"fmt"
55

6+
"github.com/containers/image/v5/docker"
7+
"github.com/containers/image/v5/pkg/shortnames"
8+
"github.com/containers/image/v5/transports/alltransports"
69
"github.com/containers/podman/v4/libpod/define"
710
spec "github.com/opencontainers/runtime-spec/specs-go"
811
)
@@ -141,5 +144,35 @@ func (c *Container) validate() error {
141144
if c.config.HealthCheckOnFailureAction != define.HealthCheckOnFailureActionNone && c.config.HealthCheckConfig == nil {
142145
return fmt.Errorf("cannot set on-failure action to %s without a health check", c.config.HealthCheckOnFailureAction.String())
143146
}
147+
148+
if value, exists := c.config.Labels[define.AutoUpdateLabel]; exists {
149+
// TODO: we cannot reference pkg/autoupdate here due to
150+
// circular dependencies. It's worth considering moving the
151+
// auto-update logic into the libpod package.
152+
if value == "registry" || value == "image" {
153+
if err := validateAutoUpdateImageReference(c.config.RawImageName); err != nil {
154+
return err
155+
}
156+
}
157+
}
158+
159+
return nil
160+
}
161+
162+
// validateAutoUpdateImageReference checks if the specified imageName is a
163+
// fully-qualified image reference to the docker transport. Such a reference
164+
// includes a domain, name and tag (e.g., quay.io/podman/stable:latest). The
165+
// reference may also be prefixed with "docker://" explicitly indicating that
166+
// it's a reference to the docker transport.
167+
func validateAutoUpdateImageReference(imageName string) error {
168+
// Make sure the input image is a docker.
169+
imageRef, err := alltransports.ParseImageName(imageName)
170+
if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
171+
return fmt.Errorf("auto updates require the docker image transport but image is of transport %q", imageRef.Transport().Name())
172+
} else if err != nil {
173+
if shortnames.IsShortName(imageName) {
174+
return fmt.Errorf("short name: auto updates require fully-qualified image reference: %q", imageName)
175+
}
176+
}
144177
return nil
145178
}

libpod/define/autoupdate.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package define
2+
3+
// AutoUpdateLabel denotes the container/pod label key to specify auto-update
4+
// policies in container labels.
5+
const AutoUpdateLabel = "io.containers.autoupdate"
6+
7+
// AutoUpdateAuthfileLabel denotes the container label key to specify authfile
8+
// in container labels.
9+
const AutoUpdateAuthfileLabel = "io.containers.autoupdate.authfile"

pkg/autoupdate/autoupdate.go

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import (
99
"github.com/containers/common/libimage"
1010
"github.com/containers/common/pkg/config"
1111
"github.com/containers/image/v5/docker"
12-
"github.com/containers/image/v5/docker/reference"
13-
"github.com/containers/image/v5/transports/alltransports"
1412
"github.com/containers/podman/v4/libpod"
1513
"github.com/containers/podman/v4/libpod/define"
1614
"github.com/containers/podman/v4/libpod/events"
@@ -21,14 +19,6 @@ import (
2119
"github.com/sirupsen/logrus"
2220
)
2321

24-
// Label denotes the container/pod label key to specify auto-update policies in
25-
// container labels.
26-
const Label = "io.containers.autoupdate"
27-
28-
// Label denotes the container label key to specify authfile in
29-
// container labels.
30-
const AuthfileLabel = "io.containers.autoupdate.authfile"
31-
3222
// Policy represents an auto-update policy.
3323
type Policy string
3424

@@ -102,32 +92,7 @@ func LookupPolicy(s string) (Policy, error) {
10292
return "", fmt.Errorf("invalid auto-update policy %q: valid policies are %+q", s, keys)
10393
}
10494

105-
// ValidateImageReference checks if the specified imageName is a fully-qualified
106-
// image reference to the docker transport (without digest). Such a reference
107-
// includes a domain, name and tag (e.g., quay.io/podman/stable:latest). The
108-
// reference may also be prefixed with "docker://" explicitly indicating that
109-
// it's a reference to the docker transport.
110-
func ValidateImageReference(imageName string) error {
111-
// Make sure the input image is a docker.
112-
imageRef, err := alltransports.ParseImageName(imageName)
113-
if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
114-
return fmt.Errorf("auto updates require the docker image transport but image is of transport %q", imageRef.Transport().Name())
115-
} else if err != nil {
116-
repo, err := reference.Parse(imageName)
117-
if err != nil {
118-
return fmt.Errorf("enforcing fully-qualified docker transport reference for auto updates: %w", err)
119-
}
120-
if _, ok := repo.(reference.NamedTagged); !ok {
121-
return fmt.Errorf("auto updates require fully-qualified image references (no tag): %q", imageName)
122-
}
123-
if _, ok := repo.(reference.Digested); ok {
124-
return fmt.Errorf("auto updates require fully-qualified image references without digest: %q", imageName)
125-
}
126-
}
127-
return nil
128-
}
129-
130-
// AutoUpdate looks up containers with a specified auto-update policy and acts
95+
/// AutoUpdate looks up containers with a specified auto-update policy and acts
13196
// accordingly.
13297
//
13398
// If the policy is set to PolicyRegistryImage, it checks if the image
@@ -418,7 +383,7 @@ func (u *updater) assembleTasks(ctx context.Context) []error {
418383
// Check the container's auto-update policy which is configured
419384
// as a label.
420385
labels := ctr.Labels()
421-
value, exists := labels[Label]
386+
value, exists := labels[define.AutoUpdateLabel]
422387
if !exists {
423388
continue
424389
}
@@ -454,7 +419,7 @@ func (u *updater) assembleTasks(ctx context.Context) []error {
454419
}
455420

456421
t := task{
457-
authfile: labels[AuthfileLabel],
422+
authfile: labels[define.AutoUpdateAuthfileLabel],
458423
auto: u,
459424
container: ctr,
460425
policy: policy,

pkg/autoupdate/autoupdate_test.go

Lines changed: 0 additions & 50 deletions
This file was deleted.

pkg/domain/infra/abi/play.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/containers/image/v5/types"
2020
"github.com/containers/podman/v4/libpod"
2121
"github.com/containers/podman/v4/libpod/define"
22-
"github.com/containers/podman/v4/pkg/autoupdate"
2322
"github.com/containers/podman/v4/pkg/domain/entities"
2423
v1apps "github.com/containers/podman/v4/pkg/k8s.io/api/apps/v1"
2524
v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1"
@@ -800,8 +799,8 @@ func (ic *ContainerEngine) getImageAndLabelInfo(ctx context.Context, cwd string,
800799
}
801800
}
802801

803-
setLabel(autoupdate.Label)
804-
setLabel(autoupdate.AuthfileLabel)
802+
setLabel(define.AutoUpdateLabel)
803+
setLabel(define.AutoUpdateAuthfileLabel)
805804

806805
return pulledImage, labels, nil
807806
}

test/system/255-auto-update.bats

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,26 @@ function _confirm_update() {
133133
die "Timed out waiting for $cname to update; old IID=$old_iid"
134134
}
135135

136+
@test "podman auto-update - validate input" {
137+
# Fully-qualified image reference is required
138+
run_podman create --label io.containers.autoupdate=registry $IMAGE
139+
run_podman rm -f "$output"
140+
141+
# Short name does not work
142+
shortname="shortname:latest"
143+
run_podman image tag $IMAGE $shortname
144+
run_podman 125 create --label io.containers.autoupdate=registry $shortname
145+
is "$output" "Error: short name: auto updates require fully-qualified image reference: \"$shortname\""
146+
147+
# Requires docker (or no) transport
148+
archive=$PODMAN_TMPDIR/archive.tar
149+
run_podman save -o $archive $IMAGE
150+
run_podman 125 create --label io.containers.autoupdate=registry docker-archive:$archive
151+
is "$output" ".*Error: auto updates require the docker image transport but image is of transport \"docker-archive\""
152+
153+
run_podman rmi $shortname
154+
}
155+
136156
# This test can fail in dev. environment because of SELinux.
137157
# quick fix: chcon -t container_runtime_exec_t ./bin/podman
138158
@test "podman auto-update - label io.containers.autoupdate=image" {

0 commit comments

Comments
 (0)