Merge pull request #19092 from vrothberg/bz-2218315

auto update: fix usage of --authfile
This commit is contained in:
OpenShift Merge Robot
2023-07-05 08:02:46 -04:00
committed by GitHub
12 changed files with 117 additions and 13 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/containers/common/pkg/auth" "github.com/containers/common/pkg/auth"
"github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report" "github.com/containers/common/pkg/report"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
@ -17,7 +18,8 @@ import (
type cliAutoUpdateOptions struct { type cliAutoUpdateOptions struct {
entities.AutoUpdateOptions entities.AutoUpdateOptions
format string format string
tlsVerify bool
} }
var ( var (
@ -56,6 +58,8 @@ func init() {
flags.StringVar(&autoUpdateOptions.format, "format", "", "Change the output format to JSON or a Go template") flags.StringVar(&autoUpdateOptions.format, "format", "", "Change the output format to JSON or a Go template")
_ = autoUpdateCommand.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&autoUpdateOutput{})) _ = autoUpdateCommand.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&autoUpdateOutput{}))
flags.BoolVarP(&autoUpdateOptions.tlsVerify, "tls-verify", "", true, "Require HTTPS and verify certificates when contacting registries")
} }
func autoUpdate(cmd *cobra.Command, args []string) error { func autoUpdate(cmd *cobra.Command, args []string) error {
@ -64,6 +68,10 @@ func autoUpdate(cmd *cobra.Command, args []string) error {
return fmt.Errorf("`%s` takes no arguments", cmd.CommandPath()) return fmt.Errorf("`%s` takes no arguments", cmd.CommandPath())
} }
if cmd.Flags().Changed("tls-verify") {
autoUpdateOptions.InsecureSkipTLSVerify = types.NewOptionalBool(!autoUpdateOptions.tlsVerify)
}
allReports, failures := registry.ContainerEngine().AutoUpdate(registry.GetContext(), autoUpdateOptions.AutoUpdateOptions) allReports, failures := registry.ContainerEngine().AutoUpdate(registry.GetContext(), autoUpdateOptions.AutoUpdateOptions)
if allReports == nil { if allReports == nil {
return errorhandling.JoinErrors(failures) return errorhandling.JoinErrors(failures)

View File

@ -1,5 +1,5 @@
####> This option file is used in: ####> This option file is used in:
####> podman build, container runlabel, create, kube play, login, manifest add, manifest create, manifest inspect, manifest push, pull, push, run, search ####> podman auto update, build, container runlabel, create, kube play, login, manifest add, manifest create, manifest inspect, manifest push, pull, push, run, search
####> If file is edited, make sure the changes ####> If file is edited, make sure the changes
####> are applicable to all of those. ####> are applicable to all of those.
#### **--tls-verify** #### **--tls-verify**

View File

@ -79,6 +79,7 @@ Please note that detecting if a systemd unit has failed is best done by the cont
For a container to send the READY message via SDNOTIFY it must be created with the `--sdnotify=container` option (see podman-run(1)). The application running inside the container can then execute `systemd-notify --ready` when ready or use the sdnotify bindings of the specific programming language (e.g., sd_notify(3)). For a container to send the READY message via SDNOTIFY it must be created with the `--sdnotify=container` option (see podman-run(1)). The application running inside the container can then execute `systemd-notify --ready` when ready or use the sdnotify bindings of the specific programming language (e.g., sd_notify(3)).
@@option tls-verify
## EXAMPLES ## EXAMPLES
Autoupdate with registry policy Autoupdate with registry policy

2
go.mod
View File

@ -180,3 +180,5 @@ require (
) )
replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc
replace github.com/containers/common => github.com/containers/common v0.55.1-0.20230703090011-0ab70cf5664d

4
go.sum
View File

@ -241,8 +241,8 @@ github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q
github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0= github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0=
github.com/containers/buildah v1.31.0 h1:NgVtEyTsR7e/XLTSJElbInnGPjdDGNHqLKADPHzaUGg= github.com/containers/buildah v1.31.0 h1:NgVtEyTsR7e/XLTSJElbInnGPjdDGNHqLKADPHzaUGg=
github.com/containers/buildah v1.31.0/go.mod h1:tcgXcGhqw3kw49RapUS7tskEhxKLG4eVFJKA/QzgwNU= github.com/containers/buildah v1.31.0/go.mod h1:tcgXcGhqw3kw49RapUS7tskEhxKLG4eVFJKA/QzgwNU=
github.com/containers/common v0.55.1 h1:sOlcIxEYXoR3OSHufew7CuSeOWr7a2jHGYw3r+xKA1k= github.com/containers/common v0.55.1-0.20230703090011-0ab70cf5664d h1:qtrq0ZsAAd+lI9eYBpq/1Fz9cxE1D95AvoB6g4ES0wg=
github.com/containers/common v0.55.1/go.mod h1:ZKPllYOZ2xj2rgWRdnHHVvWg6ru4BT28En8mO8DMMPk= github.com/containers/common v0.55.1-0.20230703090011-0ab70cf5664d/go.mod h1:c+q6NRSLy4pKMYzb7Hsu6NPy0LnIjH2CJnplR5w3Bk8=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.26.1 h1:8y3xq8GO/6y8FR+nAedHPsAFiAtOrab9qHTBpbqaX8g= github.com/containers/image/v5 v5.26.1 h1:8y3xq8GO/6y8FR+nAedHPsAFiAtOrab9qHTBpbqaX8g=

View File

@ -282,7 +282,10 @@ func (t *task) registryUpdateAvailable(ctx context.Context) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
options := &libimage.HasDifferentDigestOptions{AuthFilePath: t.authfile} options := &libimage.HasDifferentDigestOptions{
AuthFilePath: t.authfile,
InsecureSkipTLSVerify: t.auto.options.InsecureSkipTLSVerify,
}
return t.image.HasDifferentDigest(ctx, remoteRef, options) return t.image.HasDifferentDigest(ctx, remoteRef, options)
} }
@ -296,6 +299,7 @@ func (t *task) registryUpdate(ctx context.Context) error {
pullOptions := &libimage.PullOptions{} pullOptions := &libimage.PullOptions{}
pullOptions.AuthFilePath = t.authfile pullOptions.AuthFilePath = t.authfile
pullOptions.Writer = os.Stderr pullOptions.Writer = os.Stderr
pullOptions.InsecureSkipTLSVerify = t.auto.options.InsecureSkipTLSVerify
if _, err := t.auto.runtime.LibimageRuntime().Pull(ctx, t.rawImageName, config.PullPolicyAlways, pullOptions); err != nil { if _, err := t.auto.runtime.LibimageRuntime().Pull(ctx, t.rawImageName, config.PullPolicyAlways, pullOptions); err != nil {
return err return err
} }
@ -416,8 +420,14 @@ func (u *updater) assembleTasks(ctx context.Context) []error {
continue continue
} }
// Use user-specified auth file (CLI or env variable) unless
// the container was created with the auth-file label.
authfile := u.options.Authfile
if fromContainer, ok := labels[define.AutoUpdateAuthfileLabel]; ok {
authfile = fromContainer
}
t := task{ t := task{
authfile: labels[define.AutoUpdateAuthfileLabel], authfile: authfile,
auto: u, auto: u,
container: ctr, container: ctr,
policy: policy, policy: policy,

View File

@ -1,5 +1,7 @@
package entities package entities
import "github.com/containers/image/v5/types"
// AutoUpdateOptions are the options for running auto-update. // AutoUpdateOptions are the options for running auto-update.
type AutoUpdateOptions struct { type AutoUpdateOptions struct {
// Authfile to use when contacting registries. // Authfile to use when contacting registries.
@ -11,6 +13,9 @@ type AutoUpdateOptions struct {
// If restarting the service with the new image failed, restart it // If restarting the service with the new image failed, restart it
// another time with the previous image. // another time with the previous image.
Rollback bool Rollback bool
// Allow contacting registries over HTTP, or HTTPS with failed TLS
// verification. Note that this does not affect other TLS connections.
InsecureSkipTLSVerify types.OptionalBool
} }
// AutoUpdateReport contains the results from running auto-update. // AutoUpdateReport contains the results from running auto-update.

View File

@ -4,6 +4,8 @@
# #
load helpers load helpers
load helpers.network
load helpers.registry
load helpers.systemd load helpers.systemd
SNAME_FILE=$BATS_TMPDIR/services SNAME_FILE=$BATS_TMPDIR/services
@ -47,6 +49,7 @@ function teardown() {
# 4. Generate the service file from the container # 4. Generate the service file from the container
# 5. Remove the origin container # 5. Remove the origin container
# 6. Start the container from service # 6. Start the container from service
# 7. Use this fully-qualified image instead of 2)
function generate_service() { function generate_service() {
local target_img_basename=$1 local target_img_basename=$1
local autoupdate=$2 local autoupdate=$2
@ -64,6 +67,9 @@ function generate_service() {
# IMPORTANT: variable 'cname' is passed (out of scope) up to caller! # IMPORTANT: variable 'cname' is passed (out of scope) up to caller!
cname=c_${autoupdate//\'/}_$(random_string) cname=c_${autoupdate//\'/}_$(random_string)
target_img="quay.io/libpod/$target_img_basename:latest" target_img="quay.io/libpod/$target_img_basename:latest"
if [[ -n "$7" ]]; then
target_img="$7"
fi
if [[ -z "$noTag" ]]; then if [[ -z "$noTag" ]]; then
run_podman tag $IMAGE $target_img run_podman tag $IMAGE $target_img
@ -623,4 +629,62 @@ EOF
systemctl daemon-reload systemctl daemon-reload
} }
@test "podman-auto-update --authfile" {
# Test the three supported ways of using authfiles with auto updates
# 1) Passed via --authfile CLI flag
# 2) Passed via the REGISTRY_AUTH_FILE env variable
# 3) Via a label at container creation where 1) and 2) will be ignored
registry=localhost:${PODMAN_LOGIN_REGISTRY_PORT}
image_on_local_registry=$registry/name:tag
authfile=$PODMAN_TMPDIR/authfile.json
# First, start the registry and populate the authfile that we can use for the test.
start_registry
run_podman login --authfile=$authfile \
--tls-verify=false \
--username ${PODMAN_LOGIN_USER} \
--password ${PODMAN_LOGIN_PASS} \
$registry
run_podman tag $IMAGE $image_on_local_registry
run_podman push --tls-verify=false --creds "${PODMAN_LOGIN_USER}:${PODMAN_LOGIN_PASS}" $image_on_local_registry
# Generate a systemd service with the "registry" auto-update policy running
# "top" inside the image we just pushed to the local registry.
generate_service "" registry top "" "" "" $image_on_local_registry
ctr=$cname
_wait_service_ready container-$ctr.service
run_podman 125 auto-update
is "$output" \
".*Error: checking image updates for container .*: x509: .*"
run_podman 125 auto-update --tls-verify=false
is "$output" \
".*Error: checking image updates for container .*: authentication required"
# Test 1)
run_podman auto-update --authfile=$authfile --tls-verify=false --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
is "$output" "container-$ctr.service,$image_on_local_registry,false,registry" "auto-update works with authfile"
# Test 2)
REGISTRY_AUTH_FILE=$authfile run_podman auto-update --tls-verify=false --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
is "$output" "container-$ctr.service,$image_on_local_registry,false,registry" "auto-update works with env var"
systemctl stop container-$ctr.service
run_podman rm -f -t0 --ignore $ctr
# Create a container with the auth-file label
generate_service "" registry top "--label io.containers.autoupdate.authfile=$authfile" "" "" $image_on_local_registry
ctr=$cname
_wait_service_ready container-$ctr.service
# Test 3)
# Also make sure that the label takes precedence over the CLI flag.
run_podman auto-update --authfile=/dev/null --tls-verify=false --dry-run --format "{{.Unit}},{{.Image}},{{.Updated}},{{.Policy}}"
is "$output" "container-$ctr.service,$image_on_local_registry,false,registry" "auto-update works with authfile container label"
run_podman rm -f -t0 --ignore $ctr
run_podman rmi $image_on_local_registry
}
# vim: filetype=sh # vim: filetype=sh

View File

@ -806,6 +806,9 @@ type HasDifferentDigestOptions struct {
// containers-auth.json(5) file to use when authenticating against // containers-auth.json(5) file to use when authenticating against
// container registries. // container registries.
AuthFilePath string AuthFilePath string
// Allow contacting registries over HTTP, or HTTPS with failed TLS
// verification. Note that this does not affect other TLS connections.
InsecureSkipTLSVerify types.OptionalBool
} }
// HasDifferentDigest returns true if the image specified by `remoteRef` has a // HasDifferentDigest returns true if the image specified by `remoteRef` has a
@ -831,8 +834,15 @@ func (i *Image) HasDifferentDigest(ctx context.Context, remoteRef types.ImageRef
sys.VariantChoice = inspectInfo.Variant sys.VariantChoice = inspectInfo.Variant
} }
if options != nil && options.AuthFilePath != "" { if options != nil {
sys.AuthFilePath = options.AuthFilePath if options.AuthFilePath != "" {
sys.AuthFilePath = options.AuthFilePath
}
if options.InsecureSkipTLSVerify != types.OptionalBoolUndefined {
sys.DockerInsecureSkipTLSVerify = options.InsecureSkipTLSVerify
sys.OCIInsecureSkipTLSVerify = options.InsecureSkipTLSVerify == types.OptionalBoolTrue
sys.DockerDaemonInsecureSkipTLSVerify = options.InsecureSkipTLSVerify == types.OptionalBoolTrue
}
} }
return i.hasDifferentDigestWithSystemContext(ctx, remoteRef, sys) return i.hasDifferentDigestWithSystemContext(ctx, remoteRef, sys)

View File

@ -217,9 +217,12 @@ func (s *SecretsManager) Store(name string, data []byte, driverType string, opti
} }
if options.Replace { if options.Replace {
err = driver.Delete(secr.ID) if err := driver.Delete(secr.ID); err != nil {
if err != nil { return "", fmt.Errorf("deleting secret %s: %w", secr.ID, err)
return "", fmt.Errorf("replacing secret %s: %w", name, err) }
if err := s.delete(secr.ID); err != nil {
return "", fmt.Errorf("deleting secret %s: %w", secr.ID, err)
} }
} }

View File

@ -1,4 +1,4 @@
package version package version
// Version is the version of the build. // Version is the version of the build.
const Version = "0.55.1" const Version = "0.56.0-dev"

3
vendor/modules.txt vendored
View File

@ -128,7 +128,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util github.com/containers/buildah/pkg/util
github.com/containers/buildah/util github.com/containers/buildah/util
# github.com/containers/common v0.55.1 # github.com/containers/common v0.55.1 => github.com/containers/common v0.55.1-0.20230703090011-0ab70cf5664d
## explicit; go 1.18 ## explicit; go 1.18
github.com/containers/common/libimage github.com/containers/common/libimage
github.com/containers/common/libimage/define github.com/containers/common/libimage/define
@ -1154,3 +1154,4 @@ gopkg.in/yaml.v3
## explicit; go 1.12 ## explicit; go 1.12
sigs.k8s.io/yaml sigs.k8s.io/yaml
# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc # github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc
# github.com/containers/common => github.com/containers/common v0.55.1-0.20230703090011-0ab70cf5664d