Merge pull request #2710 from andya1lan/fix-sync-tls-verify-yaml

sync: honor CLI/global tls-verify unless YAML explicitly sets tls-verify
This commit is contained in:
Miloslav Trmač
2025-09-19 18:46:58 +02:00
committed by GitHub
2 changed files with 134 additions and 2 deletions

View File

@@ -289,8 +289,11 @@ func imagesToCopyFromRegistry(registryName string, cfg registrySyncConfig, sourc
// override ctx with per-registryName options // override ctx with per-registryName options
serverCtx.DockerCertPath = cfg.CertDir serverCtx.DockerCertPath = cfg.CertDir
serverCtx.DockerDaemonCertPath = cfg.CertDir serverCtx.DockerDaemonCertPath = cfg.CertDir
serverCtx.DockerDaemonInsecureSkipTLSVerify = (cfg.TLSVerify.skip == types.OptionalBoolTrue) // Only override TLS verification if explicitly specified in YAML; otherwise, keep CLI/global settings.
serverCtx.DockerInsecureSkipTLSVerify = cfg.TLSVerify.skip if cfg.TLSVerify.skip != types.OptionalBoolUndefined {
serverCtx.DockerDaemonInsecureSkipTLSVerify = (cfg.TLSVerify.skip == types.OptionalBoolTrue)
serverCtx.DockerInsecureSkipTLSVerify = cfg.TLSVerify.skip
}
if cfg.Credentials != (types.DockerAuthConfig{}) { if cfg.Credentials != (types.DockerAuthConfig{}) {
serverCtx.DockerAuthConfig = &cfg.Credentials serverCtx.DockerAuthConfig = &cfg.Credentials
} }

View File

@@ -59,3 +59,132 @@ func TestSync(t *testing.T) {
// FIXME: Much more test coverage // FIXME: Much more test coverage
// Actual feature tests exist in integration and systemtest // Actual feature tests exist in integration and systemtest
} }
// TestTLSPrecedence_YAMLOmitted verifies that when YAML omits tls-verify,
// imagesToCopyFromRegistry preserves the incoming SystemContext values
// (e.g., from CLI/global flags) for both DockerInsecureSkipTLSVerify and
// DockerDaemonInsecureSkipTLSVerify.
func TestTLSPrecedence_YAMLOmitted(t *testing.T) {
baseRegistry := "example.com"
imageName := "repo"
cfgBase := registrySyncConfig{
Images: map[string][]string{imageName: {"latest"}}, // avoid network
}
tests := []struct {
name string
incomingSkip types.OptionalBool
incomingDaemonSkip bool
yamlSkip types.OptionalBool // OptionalBoolUndefined means YAML omitted
wantSkip types.OptionalBool
wantDaemonSkip bool
}{
{
name: "YAML omitted preserves incoming skip=true",
incomingSkip: types.OptionalBoolTrue,
incomingDaemonSkip: true,
yamlSkip: types.OptionalBoolUndefined,
wantSkip: types.OptionalBoolTrue,
wantDaemonSkip: true,
},
{
name: "YAML omitted preserves incoming skip=false (CLI pass verify)",
incomingSkip: types.OptionalBoolFalse,
incomingDaemonSkip: false,
yamlSkip: types.OptionalBoolUndefined,
wantSkip: types.OptionalBoolFalse,
wantDaemonSkip: false,
},
{
name: "YAML omitted preserves daemon skip=true while docker skip=undefined",
incomingSkip: types.OptionalBoolUndefined,
incomingDaemonSkip: true,
yamlSkip: types.OptionalBoolUndefined,
wantSkip: types.OptionalBoolUndefined,
wantDaemonSkip: true,
},
{
name: "YAML omitted preserves mismatched incoming (docker skip=true, daemon skip=false)",
incomingSkip: types.OptionalBoolTrue,
incomingDaemonSkip: false,
yamlSkip: types.OptionalBoolUndefined,
wantSkip: types.OptionalBoolTrue,
wantDaemonSkip: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
src := types.SystemContext{
DockerInsecureSkipTLSVerify: tt.incomingSkip,
DockerDaemonInsecureSkipTLSVerify: tt.incomingDaemonSkip,
}
cfg := cfgBase
cfg.TLSVerify = tlsVerifyConfig{skip: tt.yamlSkip}
descs, err := imagesToCopyFromRegistry(baseRegistry, cfg, src)
require.NoError(t, err)
require.NotEmpty(t, descs)
ctx := descs[0].Context
require.NotNil(t, ctx)
assert.Equal(t, tt.wantSkip, ctx.DockerInsecureSkipTLSVerify)
assert.Equal(t, tt.wantDaemonSkip, ctx.DockerDaemonInsecureSkipTLSVerify)
})
}
}
// TestTLSPrecedence_YAMLSpecified verifies that when YAML explicitly specifies
// tls-verify, it overrides incoming SystemContext values (e.g., CLI/global flags)
// for both DockerInsecureSkipTLSVerify and DockerDaemonInsecureSkipTLSVerify.
func TestTLSPrecedence_YAMLSpecified(t *testing.T) {
baseRegistry := "example.com"
imageName := "repo"
cfgBase := registrySyncConfig{
Images: map[string][]string{imageName: {"latest"}}, // avoid network
}
tests := []struct {
name string
incomingSkip types.OptionalBool
incomingDaemonSkip bool
yamlSkip types.OptionalBool // YAML explicitly sets this
wantSkip types.OptionalBool
wantDaemonSkip bool
}{
{
name: "YAML tls-verify:true enforces verification",
incomingSkip: types.OptionalBoolTrue,
incomingDaemonSkip: true,
yamlSkip: types.OptionalBoolFalse,
wantSkip: types.OptionalBoolFalse,
wantDaemonSkip: false,
},
{
name: "YAML tls-verify:false disables verification",
incomingSkip: types.OptionalBoolFalse,
incomingDaemonSkip: false,
yamlSkip: types.OptionalBoolTrue,
wantSkip: types.OptionalBoolTrue,
wantDaemonSkip: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
src := types.SystemContext{
DockerInsecureSkipTLSVerify: tt.incomingSkip,
DockerDaemonInsecureSkipTLSVerify: tt.incomingDaemonSkip,
}
cfg := cfgBase
cfg.TLSVerify = tlsVerifyConfig{skip: tt.yamlSkip}
descs, err := imagesToCopyFromRegistry(baseRegistry, cfg, src)
require.NoError(t, err)
require.NotEmpty(t, descs)
ctx := descs[0].Context
require.NotNil(t, ctx)
assert.Equal(t, tt.wantSkip, ctx.DockerInsecureSkipTLSVerify)
assert.Equal(t, tt.wantDaemonSkip, ctx.DockerDaemonInsecureSkipTLSVerify)
})
}
}