From fe99e6f2a616d96f90811c1dfae064d4dac28728 Mon Sep 17 00:00:00 2001 From: Jordan Keister Date: Thu, 12 Dec 2024 15:23:29 -0600 Subject: [PATCH] provide an optional base image flag for generated dockerfiles from bundle build commands Signed-off-by: Jordan Keister --- cmd/opm/alpha/bundle/build.go | 5 +++++ cmd/opm/alpha/bundle/generate.go | 2 ++ pkg/lib/bundle/build.go | 4 ++-- pkg/lib/bundle/generate.go | 8 ++++---- pkg/lib/bundle/generate_test.go | 21 ++++++++++++++++----- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/cmd/opm/alpha/bundle/build.go b/cmd/opm/alpha/bundle/build.go index c35ce80c9..bb392ada2 100644 --- a/cmd/opm/alpha/bundle/build.go +++ b/cmd/opm/alpha/bundle/build.go @@ -15,6 +15,7 @@ var ( defaultChannel string outputDir string overwrite bool + baseImage string ) // newBundleBuildCmd returns a command that will build operator bundle image. @@ -76,6 +77,9 @@ Note: bundleBuildCmd.Flags().StringVarP(&outputDir, "output-dir", "u", "", "Optional output directory for operator manifests") + bundleBuildCmd.Flags().StringVar(&baseImage, "base-image", "scratch", + "Use a custom image pullspec as the base bundle image") + return bundleBuildCmd } @@ -89,5 +93,6 @@ func buildFunc(cmd *cobra.Command, _ []string) error { channels, defaultChannel, overwrite, + baseImage, ) } diff --git a/cmd/opm/alpha/bundle/generate.go b/cmd/opm/alpha/bundle/generate.go index 417a22c37..3a65f2ae3 100644 --- a/cmd/opm/alpha/bundle/generate.go +++ b/cmd/opm/alpha/bundle/generate.go @@ -45,6 +45,7 @@ Note: bundleGenerateCmd.Flags().StringVarP(&outputDir, "output-dir", "u", "", "Optional output directory for operator manifests") + bundleGenerateCmd.Flags().StringVar(&baseImage, "base-image", "scratch", "Use a custom image pullspec as the base bundle image") return bundleGenerateCmd } @@ -56,5 +57,6 @@ func generateFunc(cmd *cobra.Command, _ []string) error { channels, defaultChannel, true, + baseImage, ) } diff --git a/pkg/lib/bundle/build.go b/pkg/lib/bundle/build.go index ca2b2d776..08b0fa808 100644 --- a/pkg/lib/bundle/build.go +++ b/pkg/lib/bundle/build.go @@ -51,14 +51,14 @@ func ExecuteCommand(cmd *exec.Cmd) error { // @channelDefault: The default channel for the bundle image // @overwrite: Boolean flag to enable overwriting annotations.yaml locally if existed func BuildFunc(directory, outputDir, imageTag, imageBuilder, packageName, channels, channelDefault string, - overwrite bool) error { + overwrite bool, baseImage string) error { _, err := os.Stat(directory) if os.IsNotExist(err) { return err } // Generate annotations.yaml and Dockerfile - err = GenerateFunc(directory, outputDir, packageName, channels, channelDefault, overwrite) + err = GenerateFunc(directory, outputDir, packageName, channels, channelDefault, overwrite, baseImage) if err != nil { return err } diff --git a/pkg/lib/bundle/generate.go b/pkg/lib/bundle/generate.go index 5b9d82153..7f20e4288 100644 --- a/pkg/lib/bundle/generate.go +++ b/pkg/lib/bundle/generate.go @@ -46,7 +46,7 @@ type AnnotationMetadata struct { // @channels: The list of channels that bundle image belongs to // @channelDefault: The default channel for the bundle image // @overwrite: Boolean flag to enable overwriting annotations.yaml locally if existed -func GenerateFunc(directory, outputDir, packageName, channels, channelDefault string, overwrite bool) error { +func GenerateFunc(directory, outputDir, packageName, channels, channelDefault string, overwrite bool, baseImage string) error { // clean the input so that we know the absolute paths of input directories directory, err := filepath.Abs(directory) if err != nil { @@ -132,7 +132,7 @@ func GenerateFunc(directory, outputDir, packageName, channels, channelDefault st log.Info("Building Dockerfile") // Generate Dockerfile - content, err = GenerateDockerfile(mediaType, ManifestsDir, MetadataDir, outManifestDir, outMetadataDir, workingDir, packageName, channels, channelDefault) + content, err = GenerateDockerfile(mediaType, ManifestsDir, MetadataDir, outManifestDir, outMetadataDir, workingDir, packageName, channels, channelDefault, baseImage) if err != nil { return err } @@ -319,7 +319,7 @@ func GenerateAnnotations(mediaType, manifests, metadata, packageName, channels, // GenerateDockerfile builds Dockerfile with mediatype, manifests & // metadata directories in bundle image, package name, channels and default // channels information in LABEL section. -func GenerateDockerfile(mediaType, manifests, metadata, copyManifestDir, copyMetadataDir, workingDir, packageName, channels, channelDefault string) ([]byte, error) { +func GenerateDockerfile(mediaType, manifests, metadata, copyManifestDir, copyMetadataDir, workingDir, packageName, channels, channelDefault string, baseImage string) ([]byte, error) { var fileContent string relativeManifestDirectory, err := filepath.Rel(workingDir, copyManifestDir) @@ -335,7 +335,7 @@ func GenerateDockerfile(mediaType, manifests, metadata, copyManifestDir, copyMet relativeMetadataDirectory = filepath.ToSlash(relativeMetadataDirectory) // FROM - fileContent += "FROM scratch\n\n" + fileContent += fmt.Sprintf("FROM %s\n\n", baseImage) // LABEL fileContent += fmt.Sprintf("LABEL %s=%s\n", MediatypeLabel, mediaType) diff --git a/pkg/lib/bundle/generate_test.go b/pkg/lib/bundle/generate_test.go index 2727855a2..6130fe1fd 100644 --- a/pkg/lib/bundle/generate_test.go +++ b/pkg/lib/bundle/generate_test.go @@ -163,7 +163,7 @@ func TestGenerateAnnotationsFunc(t *testing.T) { } func TestGenerateDockerfile(t *testing.T) { - expected := `FROM scratch + expected := `FROM %s LABEL operators.operatorframework.io.bundle.mediatype.v1=test1 LABEL operators.operatorframework.io.bundle.manifests.v1=test2 @@ -174,9 +174,20 @@ COPY a/b/c /manifests/ COPY x/y/z /metadata/ ` - actual, err := GenerateDockerfile("test1", "test2", "metadata/", filepath.Join("a", "b", "c"), filepath.Join("x", "y", "z"), "./", "test4", "test5", "") - require.NoError(t, err) - require.Equal(t, expected, string(actual)) + type DockerfileTest struct { + baseImage string + } + tests := []DockerfileTest{ + {baseImage: "scratch"}, + {baseImage: "registry/group/image@tag"}, + } + + for _, tt := range tests { + tt_expected := fmt.Sprintf(expected, tt.baseImage) + actual, err := GenerateDockerfile("test1", "test2", "metadata/", filepath.Join("a", "b", "c"), filepath.Join("x", "y", "z"), "./", "test4", "test5", "", tt.baseImage) + require.NoError(t, err) + require.Equal(t, tt_expected, string(actual)) + } } func TestCopyYamlOutput(t *testing.T) { @@ -248,7 +259,7 @@ func TestGenerateFunc(t *testing.T) { etcdPkgPath := "./testdata/etcd" outputPath := "./testdata/tmp_output" defer os.RemoveAll(outputPath) - err := GenerateFunc(filepath.Join(etcdPkgPath, "0.6.1"), outputPath, "", "", "", true) + err := GenerateFunc(filepath.Join(etcdPkgPath, "0.6.1"), outputPath, "", "", "", true, "scratch") require.NoError(t, err) os.Remove(filepath.Join("./", DockerFile))