Skip to content

Commit 4c106e2

Browse files
authored
generate binary-less dockerfiles (#1338)
* generate binary-less dockerfiles Signed-off-by: Jordan Keister <[email protected]> * two-flag approach (with cleanup of old dockerfile) Signed-off-by: Jordan Keister <[email protected]> --------- Signed-off-by: Jordan Keister <[email protected]>
1 parent ea4e736 commit 4c106e2

File tree

4 files changed

+182
-42
lines changed

4 files changed

+182
-42
lines changed

Diff for: alpha/action/generate_dockerfile.go

+28-10
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import (
99
)
1010

1111
type GenerateDockerfile struct {
12-
BaseImage string
13-
IndexDir string
14-
ExtraLabels map[string]string
15-
Writer io.Writer
12+
BaseImage string
13+
BuilderImage string
14+
IndexDir string
15+
ExtraLabels map[string]string
16+
Writer io.Writer
1617
}
1718

1819
func (i GenerateDockerfile) Run() error {
@@ -39,19 +40,36 @@ func (i GenerateDockerfile) validate() error {
3940
return nil
4041
}
4142

42-
const dockerfileTmpl = `# The base image is expected to contain
43-
# /bin/opm (with a serve subcommand) and /bin/grpc_health_probe
43+
const dockerfileTmpl = `# The builder image is expected to contain
44+
# /bin/opm (with serve subcommand)
45+
FROM {{.BuilderImage}} as builder
46+
47+
# Copy FBC root into image at /configs and pre-populate serve cache
48+
ADD {{.IndexDir}} /configs
49+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
50+
4451
FROM {{.BaseImage}}
4552
53+
{{- if ne .BaseImage "scratch" }}
54+
# The base image is expected to contain
55+
# /bin/opm (with serve subcommand) and /bin/grpc_health_probe
56+
4657
# Configure the entrypoint and command
4758
ENTRYPOINT ["/bin/opm"]
4859
CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
60+
{{- else }}
61+
# OLMv0 CatalogSources that use binary-less images must set:
62+
# spec:
63+
# grpcPodConfig:
64+
# extractContent:
65+
# catalogDir: /configs
66+
# cacheDir: /tmp/cache
67+
{{- end }}
4968
50-
# Copy declarative config root into image at /configs and pre-populate serve cache
51-
ADD {{.IndexDir}} /configs
52-
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
69+
COPY --from=builder /configs /configs
70+
COPY --from=builder /tmp/cache /tmp/cache
5371
54-
# Set DC-specific label for the location of the DC root directory
72+
# Set FBC-specific label for the location of the FBC root directory
5573
# in the image
5674
LABEL ` + containertools.ConfigsLocationLabel + `=/configs
5775
{{- if .ExtraLabels }}

Diff for: alpha/action/generate_dockerfile_test.go

+125-14
Original file line numberDiff line numberDiff line change
@@ -41,49 +41,160 @@ func TestGenerateDockerfile(t *testing.T) {
4141
{
4242
name: "Success/WithoutExtraLabels",
4343
gen: GenerateDockerfile{
44-
BaseImage: "foo",
45-
IndexDir: "bar",
44+
BuilderImage: "foo",
45+
BaseImage: "foo",
46+
IndexDir: "bar",
4647
},
47-
expectedDockerfile: `# The base image is expected to contain
48-
# /bin/opm (with a serve subcommand) and /bin/grpc_health_probe
48+
expectedDockerfile: `# The builder image is expected to contain
49+
# /bin/opm (with serve subcommand)
50+
FROM foo as builder
51+
52+
# Copy FBC root into image at /configs and pre-populate serve cache
53+
ADD bar /configs
54+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
55+
4956
FROM foo
57+
# The base image is expected to contain
58+
# /bin/opm (with serve subcommand) and /bin/grpc_health_probe
5059
5160
# Configure the entrypoint and command
5261
ENTRYPOINT ["/bin/opm"]
5362
CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
5463
55-
# Copy declarative config root into image at /configs and pre-populate serve cache
56-
ADD bar /configs
57-
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
64+
COPY --from=builder /configs /configs
65+
COPY --from=builder /tmp/cache /tmp/cache
5866
59-
# Set DC-specific label for the location of the DC root directory
67+
# Set FBC-specific label for the location of the FBC root directory
6068
# in the image
6169
LABEL operators.operatorframework.io.index.configs.v1=/configs
6270
`,
6371
},
6472
{
6573
name: "Success/WithExtraLabels",
6674
gen: GenerateDockerfile{
67-
BaseImage: "foo",
68-
IndexDir: "bar",
75+
BuilderImage: "foo",
76+
BaseImage: "foo",
77+
IndexDir: "bar",
6978
ExtraLabels: map[string]string{
7079
"key1": "value1",
7180
"key2": "value2",
7281
},
7382
},
74-
expectedDockerfile: `# The base image is expected to contain
75-
# /bin/opm (with a serve subcommand) and /bin/grpc_health_probe
83+
expectedDockerfile: `# The builder image is expected to contain
84+
# /bin/opm (with serve subcommand)
85+
FROM foo as builder
86+
87+
# Copy FBC root into image at /configs and pre-populate serve cache
88+
ADD bar /configs
89+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
90+
7691
FROM foo
92+
# The base image is expected to contain
93+
# /bin/opm (with serve subcommand) and /bin/grpc_health_probe
7794
7895
# Configure the entrypoint and command
7996
ENTRYPOINT ["/bin/opm"]
8097
CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
8198
82-
# Copy declarative config root into image at /configs and pre-populate serve cache
99+
COPY --from=builder /configs /configs
100+
COPY --from=builder /tmp/cache /tmp/cache
101+
102+
# Set FBC-specific label for the location of the FBC root directory
103+
# in the image
104+
LABEL operators.operatorframework.io.index.configs.v1=/configs
105+
106+
# Set other custom labels
107+
LABEL "key1"="value1"
108+
LABEL "key2"="value2"
109+
`,
110+
},
111+
112+
{
113+
name: "Scratch/Fail/EmptyBaseImage",
114+
gen: GenerateDockerfile{
115+
BuilderImage: "foo",
116+
IndexDir: "bar",
117+
ExtraLabels: map[string]string{
118+
"key1": "value1",
119+
"key2": "value2",
120+
},
121+
},
122+
expectedErr: "base image is unset",
123+
},
124+
{
125+
name: "Scratch/Fail/EmptyFromDir",
126+
gen: GenerateDockerfile{
127+
BuilderImage: "foo",
128+
BaseImage: "scratch",
129+
ExtraLabels: map[string]string{
130+
"key1": "value1",
131+
"key2": "value2",
132+
},
133+
},
134+
expectedErr: "index directory is unset",
135+
},
136+
{
137+
name: "Scratch/Success/WithoutExtraLabels",
138+
gen: GenerateDockerfile{
139+
BuilderImage: "foo",
140+
BaseImage: "scratch",
141+
IndexDir: "bar",
142+
},
143+
expectedDockerfile: `# The builder image is expected to contain
144+
# /bin/opm (with serve subcommand)
145+
FROM foo as builder
146+
147+
# Copy FBC root into image at /configs and pre-populate serve cache
83148
ADD bar /configs
84149
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
85150
86-
# Set DC-specific label for the location of the DC root directory
151+
FROM scratch
152+
# OLMv0 CatalogSources that use binary-less images must set:
153+
# spec:
154+
# grpcPodConfig:
155+
# extractContent:
156+
# catalogDir: /configs
157+
# cacheDir: /tmp/cache
158+
159+
COPY --from=builder /configs /configs
160+
COPY --from=builder /tmp/cache /tmp/cache
161+
162+
# Set FBC-specific label for the location of the FBC root directory
163+
# in the image
164+
LABEL operators.operatorframework.io.index.configs.v1=/configs
165+
`,
166+
},
167+
{
168+
name: "Scratch/Success/WithExtraLabels",
169+
gen: GenerateDockerfile{
170+
BuilderImage: "foo",
171+
BaseImage: "scratch",
172+
IndexDir: "bar",
173+
ExtraLabels: map[string]string{
174+
"key1": "value1",
175+
"key2": "value2",
176+
},
177+
},
178+
expectedDockerfile: `# The builder image is expected to contain
179+
# /bin/opm (with serve subcommand)
180+
FROM foo as builder
181+
182+
# Copy FBC root into image at /configs and pre-populate serve cache
183+
ADD bar /configs
184+
RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
185+
186+
FROM scratch
187+
# OLMv0 CatalogSources that use binary-less images must set:
188+
# spec:
189+
# grpcPodConfig:
190+
# extractContent:
191+
# catalogDir: /configs
192+
# cacheDir: /tmp/cache
193+
194+
COPY --from=builder /configs /configs
195+
COPY --from=builder /tmp/cache /tmp/cache
196+
197+
# Set FBC-specific label for the location of the FBC root directory
87198
# in the image
88199
LABEL operators.operatorframework.io.index.configs.v1=/configs
89200

Diff for: cmd/opm/generate/cmd.go

+29-12
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
func NewCmd() *cobra.Command {
1818
cmd := &cobra.Command{
1919
Use: "generate",
20-
Short: "Generate various artifacts for declarative config indexes",
20+
Short: "Generate various artifacts for file-based catalogs",
2121
}
2222
cmd.AddCommand(
2323
newDockerfileCmd(),
@@ -28,24 +28,36 @@ func NewCmd() *cobra.Command {
2828
func newDockerfileCmd() *cobra.Command {
2929
var (
3030
baseImage string
31+
builderImage string
3132
extraLabelStrs []string
3233
)
3334
cmd := &cobra.Command{
34-
Use: "dockerfile <dcRootDir>",
35+
Use: "dockerfile <fbcRootDir>",
3536
Args: cobra.ExactArgs(1),
36-
Short: "Generate a Dockerfile for a declarative config index",
37-
Long: `Generate a Dockerfile for a declarative config index.
37+
Short: "Generate a Dockerfile for a file-based catalog",
38+
Long: `Generate a Dockerfile for a file-based catalog.
3839
39-
This command creates a Dockerfile in the same directory as the <dcRootDir>
40-
(named <dcDirName>.Dockerfile) that can be used to build the index. If a
40+
This command creates a Dockerfile in the same directory as the <fbcRootDir>
41+
(named <fbcRootDir>.Dockerfile) that can be used to build the index. If a
4142
Dockerfile with the same name already exists, this command will fail.
4243
4344
When specifying extra labels, note that if duplicate keys exist, only the last
4445
value of each duplicate key will be added to the generated Dockerfile.
46+
47+
A separate builder and base image can be specified. The builder image may not be "scratch".
4548
`,
46-
RunE: func(_ *cobra.Command, args []string) error {
49+
RunE: func(inCmd *cobra.Command, args []string) error {
4750
fromDir := filepath.Clean(args[0])
4851

52+
if builderImage == "scratch" {
53+
return fmt.Errorf("invalid builder image: %q", builderImage)
54+
}
55+
56+
// preserving old behavior, if binary-image is set but not builder-image, set builder-image to binary-image
57+
if inCmd.Flags().Changed("binary-image") && !inCmd.Flags().Changed("builder-image") {
58+
builderImage = baseImage
59+
}
60+
4961
extraLabels, err := parseLabels(extraLabelStrs)
5062
if err != nil {
5163
return err
@@ -71,19 +83,24 @@ value of each duplicate key will be added to the generated Dockerfile.
7183
defer f.Close()
7284

7385
gen := action.GenerateDockerfile{
74-
BaseImage: baseImage,
75-
IndexDir: indexName,
76-
ExtraLabels: extraLabels,
77-
Writer: f,
86+
BaseImage: baseImage,
87+
BuilderImage: builderImage,
88+
IndexDir: indexName,
89+
ExtraLabels: extraLabels,
90+
Writer: f,
7891
}
7992
if err := gen.Run(); err != nil {
8093
log.Fatal(err)
8194
}
8295
return nil
8396
},
8497
}
85-
cmd.Flags().StringVarP(&baseImage, "binary-image", "i", containertools.DefaultBinarySourceImage, "Image in which to build catalog.")
98+
cmd.Flags().StringVar(&baseImage, "binary-image", containertools.DefaultBinarySourceImage, "Image in which to build catalog.")
99+
cmd.Flags().StringVarP(&baseImage, "base-image", "i", containertools.DefaultBinarySourceImage, "Image base to use to build catalog.")
100+
cmd.Flags().StringVarP(&builderImage, "builder-image", "b", containertools.DefaultBinarySourceImage, "Image to use as a build stage.")
86101
cmd.Flags().StringSliceVarP(&extraLabelStrs, "extra-labels", "l", []string{}, "Extra labels to include in the generated Dockerfile. Labels should be of the form 'key=value'.")
102+
cmd.Flags().MarkDeprecated("binary-image", "use --base-image instead")
103+
cmd.MarkFlagsMutuallyExclusive("binary-image", "base-image")
87104
return cmd
88105
}
89106

Diff for: ohio.Dockerfile

-6
This file was deleted.

0 commit comments

Comments
 (0)