Skip to content

Commit a88e167

Browse files
author
tkdchen
authored
Merge pull request #73 from tkdchen/STONEBLD-4388
Allow specifying alternative file name in containerfile artifact image
2 parents d483c42 + a6d2d92 commit a88e167

File tree

5 files changed

+143
-20
lines changed

5 files changed

+143
-20
lines changed

cmd/image/push_containerfile.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ and --containerfile.`,
4141
# Push source/Containerfile as artifact quay.io/org/app:sha256-1234567.containerfile by passing absolute source path
4242
konflux-build-cli image push-containerfile --image-url quay.io/org/app --image-digest sha256:1234567 \
4343
--source /path/to/source
44+
45+
# Use alternative file name in artifact image rather than the original file name
46+
konflux-build-cli image push-containerfile --image-url quay.io/org/app --image-digest sha256:1234567 \
47+
--source /path/to/source --context db --containerfile containerfiles/db \
48+
--alternative-filename Dockerfile
4449
`,
4550
Run: func(cmd *cobra.Command, args []string) {
4651
l.Logger.Debug("Starting push-containerfile")

integration_tests/push_containerfile_test.go

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ func setupPushContainerfileContainerWithCleanup(t *testing.T, imageRegistry Imag
4646
}
4747

4848
type PushContainerfileParams struct {
49-
source string
50-
context string
51-
containerfile string
52-
digest string
53-
tagSuffix string
54-
artifactType string
55-
resultPathImageRef string
49+
source string
50+
context string
51+
containerfile string
52+
digest string
53+
tagSuffix string
54+
artifactType string
55+
resultPathImageRef string
56+
alternativeFilename string
5657
}
5758

5859
func TestPushContainerfile(t *testing.T) {
@@ -78,7 +79,7 @@ func TestPushContainerfile(t *testing.T) {
7879
for i := 0; i < len(files); i += 2 {
7980
fileContent := files[i]
8081
fileName := files[i+1]
81-
script := fmt.Sprintf(`echo "%s" >%s`, fileContent, fileName)
82+
script := fmt.Sprintf(`echo -n "%s" >%s`, fileContent, fileName)
8283
err := container.ExecuteCommand("bash", "-c", script)
8384
g.Expect(err).ShouldNot(HaveOccurred())
8485
}
@@ -152,6 +153,18 @@ func TestPushContainerfile(t *testing.T) {
152153
expectedContainerfileDigest: sourceContainerfileContentDigest,
153154
expectedTitleAnnotationValue: "Containerfile",
154155
},
156+
{
157+
name: "Push with an alternative file name",
158+
params: PushContainerfileParams{
159+
source: "source",
160+
digest: "sha256:2788b272a5a7c0071906a9c6b654760e44a1fc8226f8268c70848148f19c35b0",
161+
containerfile: "./containerfiles/operator",
162+
alternativeFilename: "Dockerfile",
163+
},
164+
expectedTaggedDigest: "sha256-2788b272a5a7c0071906a9c6b654760e44a1fc8226f8268c70848148f19c35b0",
165+
expectedContainerfileDigest: sourceContainerfilesOperatorContentDigest,
166+
expectedTitleAnnotationValue: "Dockerfile",
167+
},
155168
}
156169

157170
for _, tc := range testCases {
@@ -177,6 +190,9 @@ func TestPushContainerfile(t *testing.T) {
177190
if tc.params.context != "" {
178191
cmd = append(cmd, "--context", tc.params.context)
179192
}
193+
if tc.params.alternativeFilename != "" {
194+
cmd = append(cmd, "--alternative-filename", tc.params.alternativeFilename)
195+
}
180196

181197
err := container.ExecuteBuildCli(cmd...)
182198
g.Expect(err).ShouldNot(HaveOccurred())
@@ -202,7 +218,7 @@ func TestPushContainerfile(t *testing.T) {
202218
if title, exists := layerAnnotations["org.opencontainers.image.title"]; exists {
203219
g.Expect(title).Should(Equal(tc.expectedTitleAnnotationValue))
204220
}
205-
g.Expect(layerDescriptor.Digest, tc.expectedContainerfileDigest)
221+
g.Expect(string(layerDescriptor.Digest)).Should(Equal("sha256:"+tc.expectedContainerfileDigest))
206222

207223
expectedArtifactType := tc.params.artifactType
208224
if expectedArtifactType == "" {

pkg/commands/build_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,7 @@ with.hash.char=this comment # is not a comment
12851285
c := &Build{
12861286
Params: &BuildParams{
12871287
SourceDateEpoch: "1767225600",
1288-
AnnotationsFile: filepath.Join(tempDir, "annotations.cfg"),
1288+
AnnotationsFile: filepath.Join(tempDir, "annotations.cfg"),
12891289
},
12901290
}
12911291

pkg/commands/push_containerfile.go

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,26 @@ var PushContainerfileParamsConfig = map[string]common.Parameter{
9393
Usage: "Write digested image reference of the pushed Containerfile image into this file.",
9494
Required: false,
9595
},
96+
"alternative-filename": {
97+
Name: "alternative-filename",
98+
ShortName: "n",
99+
EnvVarName: "KBC_PUSH_CONTAINERFILE_ALTERNATIVE_FILENAME",
100+
TypeKind: reflect.String,
101+
Usage: "Alternative file name in the artifact image, e.g. Dockerfile.",
102+
Required: false,
103+
},
96104
}
97105

98106
type PushContainerfileParams struct {
99-
ImageUrl string `paramName:"image-url"`
100-
ImageDigest string `paramName:"image-digest"`
101-
Containerfile string `paramName:"containerfile"`
102-
Context string `paramName:"context"`
103-
TagSuffix string `paramName:"tag-suffix"`
104-
ArtifactType string `paramName:"artifact-type"`
105-
Source string `paramName:"source"`
106-
ResultPathImageRef string `paramName:"result-path-image-ref"`
107+
ImageUrl string `paramName:"image-url"`
108+
ImageDigest string `paramName:"image-digest"`
109+
Containerfile string `paramName:"containerfile"`
110+
Context string `paramName:"context"`
111+
TagSuffix string `paramName:"tag-suffix"`
112+
ArtifactType string `paramName:"artifact-type"`
113+
Source string `paramName:"source"`
114+
ResultPathImageRef string `paramName:"result-path-image-ref"`
115+
AlternativeFilename string `paramName:"alternative-filename"`
107116
}
108117

109118
type PushContainerfileResults struct {
@@ -207,7 +216,31 @@ func (c *PushContainerfile) Run() error {
207216
return fmt.Errorf("Error on getting absolute path of %s: %w", containerfilePath, err)
208217
}
209218

210-
os.Chdir(filepath.Dir(absContainerfilePath))
219+
var pushFilename string
220+
var workDir string
221+
222+
if c.Params.AlternativeFilename != "" {
223+
pushFilename = filepath.Base(c.Params.AlternativeFilename)
224+
workDir, err = os.MkdirTemp("", "push-containerfile-")
225+
if err != nil {
226+
return fmt.Errorf("Error on creating temporary directory: %w", err)
227+
}
228+
defer os.RemoveAll(workDir)
229+
content, err := os.ReadFile(absContainerfilePath)
230+
if err != nil {
231+
return fmt.Errorf("Error on reading file %s: %w", absContainerfilePath, err)
232+
}
233+
if err := os.WriteFile(filepath.Join(workDir, pushFilename), content, 0644); err != nil {
234+
return fmt.Errorf("Error on writing file: %w", err)
235+
}
236+
} else {
237+
pushFilename = filepath.Base(absContainerfilePath)
238+
workDir = filepath.Dir(absContainerfilePath)
239+
}
240+
241+
if err := os.Chdir(workDir); err != nil {
242+
return fmt.Errorf("Error on changing directory to %s: %w", workDir, err)
243+
}
211244
defer os.Chdir(curDir)
212245

213246
stdout, _, err := c.CliWrappers.OrasCli.Push(&cliwrappers.OrasPushArgs{
@@ -216,7 +249,7 @@ func (c *PushContainerfile) Run() error {
216249
Format: "go-template",
217250
Template: "{{.reference}}",
218251
DestinationImage: fmt.Sprintf("%s:%s", c.imageName, tag),
219-
FileName: filepath.Base(absContainerfilePath),
252+
FileName: pushFilename,
220253
})
221254
if err != nil {
222255
return fmt.Errorf("Error on pushing Containerfile %s: %w", containerfilePath, err)
@@ -262,6 +295,14 @@ func (c *PushContainerfile) validateParams() error {
262295
return fmt.Errorf("Tag suffix includes invalid characters or exceeds the max length of 57 characters.")
263296
}
264297

298+
altFilename := c.Params.AlternativeFilename
299+
if strings.Contains(altFilename, "/") {
300+
return fmt.Errorf("Path is included in alternative file name '%s'", altFilename)
301+
}
302+
if len(altFilename) > 100 {
303+
return fmt.Errorf("Alternative file name exceeds 100 characters.")
304+
}
305+
265306
return nil
266307
}
267308

@@ -276,4 +317,7 @@ func (c *PushContainerfile) logParams() {
276317
if c.Params.ResultPathImageRef != "" {
277318
l.Logger.Infof("[param] Image Reference result file: %s", c.Params.ResultPathImageRef)
278319
}
320+
if c.Params.AlternativeFilename != "" {
321+
l.Logger.Infof("[param] Alternative file name: %s", c.Params.AlternativeFilename)
322+
}
279323
}

pkg/commands/push_containerfile_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,64 @@ func TestRun(t *testing.T) {
175175

176176
})
177177

178+
t.Run("Successful push with an alternative container file name", func(t *testing.T) {
179+
artifactImageDigest := "sha256:a7c0071906a9c6b654760e44a1fc8226f8268c70848148f19c35b02788b272a5"
180+
181+
orasCli := &mockOrasCli{}
182+
orasCli.PushFunc = func(args *cliwrappers.OrasPushArgs) (string, string, error) {
183+
g.Expect(args.FileName).Should(Equal("Dockerfile"))
184+
185+
absFilename, err := filepath.Abs("Dockerfile")
186+
g.Expect(err).ShouldNot(HaveOccurred(), "Alternative file Dockerfile does not exist")
187+
g.Expect(filepath.Dir(absFilename)).ShouldNot(Equal(filepath.Join(workDir, "source")),
188+
"Directory was not changed for pushing with an alternative file name")
189+
190+
originalContainerfile := filepath.Join(workDir, "source", "Containerfile")
191+
originalContent, err := os.ReadFile(originalContainerfile)
192+
g.Expect(err).ShouldNot(HaveOccurred())
193+
194+
content, err := os.ReadFile(absFilename)
195+
g.Expect(err).ShouldNot(HaveOccurred())
196+
197+
g.Expect(string(content)).Should(Equal(string(originalContent)), "Container file content is mismatching")
198+
199+
return "localhost.reg.io/app@" + artifactImageDigest, "", nil
200+
}
201+
202+
testCases := []struct {
203+
alternativeFilename string
204+
shouldSucceed bool
205+
}{
206+
{alternativeFilename: "Dockerfile", shouldSucceed: true},
207+
{alternativeFilename: "path/to/Dockerfile", shouldSucceed: false},
208+
}
209+
210+
for _, tc := range testCases {
211+
t.Run("use alternative file name "+tc.alternativeFilename, func(t *testing.T) {
212+
cmd := &PushContainerfile{
213+
Params: &PushContainerfileParams{
214+
ImageUrl: "localhost.reg.io/app",
215+
ImageDigest: imageDigest,
216+
Source: "source",
217+
Containerfile: "Containerfile",
218+
Context: ".",
219+
TagSuffix: ".dockerfile",
220+
AlternativeFilename: tc.alternativeFilename,
221+
},
222+
ResultsWriter: &common.ResultsWriter{},
223+
CliWrappers: PushContainerfileCliWrappers{OrasCli: orasCli},
224+
}
225+
226+
err := cmd.Run()
227+
if tc.shouldSucceed {
228+
g.Expect(err).ShouldNot(HaveOccurred())
229+
} else {
230+
g.Expect(err).Should(HaveOccurred())
231+
}
232+
})
233+
}
234+
})
235+
178236
t.Run("should not push and exits as normal if specified Containerfile is not found", func(t *testing.T) {
179237
logFilename := filepath.Join(t.TempDir(), "logfile")
180238
logFile, _ := os.OpenFile(logFilename, os.O_CREATE|os.O_WRONLY, 0644)

0 commit comments

Comments
 (0)