introduce config --lock-image-digests
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
1f076a3781
commit
2352a4a016
@ -56,6 +56,7 @@ type configOptions struct {
|
|||||||
noConsistency bool
|
noConsistency bool
|
||||||
variables bool
|
variables bool
|
||||||
environment bool
|
environment bool
|
||||||
|
lockImageDigests bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *configOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
|
func (o *configOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
|
||||||
@ -98,6 +99,9 @@ func configCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
|
|||||||
if p.Compatibility {
|
if p.Compatibility {
|
||||||
opts.noNormalize = true
|
opts.noNormalize = true
|
||||||
}
|
}
|
||||||
|
if opts.lockImageDigests {
|
||||||
|
opts.resolveImageDigests = true
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}),
|
}),
|
||||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||||
@ -133,6 +137,7 @@ func configCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
|
|||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.StringVar(&opts.Format, "format", "", "Format the output. Values: [yaml | json]")
|
flags.StringVar(&opts.Format, "format", "", "Format the output. Values: [yaml | json]")
|
||||||
flags.BoolVar(&opts.resolveImageDigests, "resolve-image-digests", false, "Pin image tags to digests")
|
flags.BoolVar(&opts.resolveImageDigests, "resolve-image-digests", false, "Pin image tags to digests")
|
||||||
|
flags.BoolVar(&opts.lockImageDigests, "lock-image-digests", false, "Produces an override file with image digests")
|
||||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything")
|
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything")
|
||||||
flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables")
|
flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables")
|
||||||
flags.BoolVar(&opts.noNormalize, "no-normalize", false, "Don't normalize compose model")
|
flags.BoolVar(&opts.noNormalize, "no-normalize", false, "Don't normalize compose model")
|
||||||
@ -208,6 +213,10 @@ func runConfigInterpolate(ctx context.Context, dockerCli command.Cli, opts confi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.lockImageDigests {
|
||||||
|
project = imagesOnly(project)
|
||||||
|
}
|
||||||
|
|
||||||
var content []byte
|
var content []byte
|
||||||
switch opts.Format {
|
switch opts.Format {
|
||||||
case "json":
|
case "json":
|
||||||
@ -223,6 +232,18 @@ func runConfigInterpolate(ctx context.Context, dockerCli command.Cli, opts confi
|
|||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// imagesOnly return project with all attributes removed but service.images
|
||||||
|
func imagesOnly(project *types.Project) *types.Project {
|
||||||
|
digests := types.Services{}
|
||||||
|
for name, config := range project.Services {
|
||||||
|
digests[name] = types.ServiceConfig{
|
||||||
|
Image: config.Image,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project = &types.Project{Services: digests}
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
|
||||||
func runConfigNoInterpolate(ctx context.Context, dockerCli command.Cli, opts configOptions, services []string) ([]byte, error) {
|
func runConfigNoInterpolate(ctx context.Context, dockerCli command.Cli, opts configOptions, services []string) ([]byte, error) {
|
||||||
// we can't use ToProject, so the model we render here is only partially resolved
|
// we can't use ToProject, so the model we render here is only partially resolved
|
||||||
model, err := opts.ToModel(ctx, dockerCli, services)
|
model, err := opts.ToModel(ctx, dockerCli, services)
|
||||||
@ -237,6 +258,23 @@ func runConfigNoInterpolate(ctx context.Context, dockerCli command.Cli, opts con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.lockImageDigests {
|
||||||
|
for key, e := range model {
|
||||||
|
if key != "services" {
|
||||||
|
delete(model, key)
|
||||||
|
} else {
|
||||||
|
for _, s := range e.(map[string]any) {
|
||||||
|
service := s.(map[string]any)
|
||||||
|
for key := range service {
|
||||||
|
if key != "image" {
|
||||||
|
delete(service, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return formatModel(model, opts.Format)
|
return formatModel(model, opts.Format)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ the canonical format.
|
|||||||
| `--format` | `string` | | Format the output. Values: [yaml \| json] |
|
| `--format` | `string` | | Format the output. Values: [yaml \| json] |
|
||||||
| `--hash` | `string` | | Print the service config hash, one per line. |
|
| `--hash` | `string` | | Print the service config hash, one per line. |
|
||||||
| `--images` | `bool` | | Print the image names, one per line. |
|
| `--images` | `bool` | | Print the image names, one per line. |
|
||||||
|
| `--lock-image-digests` | `bool` | | Produces an override file with image digests |
|
||||||
| `--no-consistency` | `bool` | | Don't check model consistency - warning: may produce invalid Compose output |
|
| `--no-consistency` | `bool` | | Don't check model consistency - warning: may produce invalid Compose output |
|
||||||
| `--no-env-resolution` | `bool` | | Don't resolve service env files |
|
| `--no-env-resolution` | `bool` | | Don't resolve service env files |
|
||||||
| `--no-interpolate` | `bool` | | Don't interpolate environment variables |
|
| `--no-interpolate` | `bool` | | Don't interpolate environment variables |
|
||||||
|
@ -46,6 +46,16 @@ options:
|
|||||||
experimentalcli: false
|
experimentalcli: false
|
||||||
kubernetes: false
|
kubernetes: false
|
||||||
swarm: false
|
swarm: false
|
||||||
|
- option: lock-image-digests
|
||||||
|
value_type: bool
|
||||||
|
default_value: "false"
|
||||||
|
description: Produces an override file with image digests
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
- option: no-consistency
|
- option: no-consistency
|
||||||
value_type: bool
|
value_type: bool
|
||||||
default_value: "false"
|
default_value: "false"
|
||||||
|
@ -235,7 +235,7 @@ func TestCompatibility(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConfig(t *testing.T) {
|
func TestConfig(t *testing.T) {
|
||||||
const projectName = "compose-e2e-convert"
|
const projectName = "compose-e2e-config"
|
||||||
c := NewParallelCLI(t)
|
c := NewParallelCLI(t)
|
||||||
|
|
||||||
wd, err := os.Getwd()
|
wd, err := os.Getwd()
|
||||||
@ -253,24 +253,24 @@ services:
|
|||||||
default: null
|
default: null
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
name: compose-e2e-convert_default
|
name: compose-e2e-config_default
|
||||||
`, projectName, filepath.Join(wd, "fixtures", "simple-build-test", "nginx-build")), ExitCode: 0})
|
`, projectName, filepath.Join(wd, "fixtures", "simple-build-test", "nginx-build")), ExitCode: 0})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigInterpolate(t *testing.T) {
|
func TestConfigInterpolate(t *testing.T) {
|
||||||
const projectName = "compose-e2e-convert-interpolate"
|
const projectName = "compose-e2e-config-interpolate"
|
||||||
c := NewParallelCLI(t)
|
c := NewParallelCLI(t)
|
||||||
|
|
||||||
wd, err := os.Getwd()
|
wd, err := os.Getwd()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
t.Run("convert", func(t *testing.T) {
|
t.Run("config", func(t *testing.T) {
|
||||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-build-test/compose-interpolate.yaml", "-p", projectName, "config", "--no-interpolate")
|
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-build-test/compose-interpolate.yaml", "-p", projectName, "config", "--no-interpolate")
|
||||||
res.Assert(t, icmd.Expected{Out: fmt.Sprintf(`name: %s
|
res.Assert(t, icmd.Expected{Out: fmt.Sprintf(`name: %s
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
name: compose-e2e-convert-interpolate_default
|
name: compose-e2e-config-interpolate_default
|
||||||
services:
|
services:
|
||||||
nginx:
|
nginx:
|
||||||
build:
|
build:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user