Skip to content

Commit dd13153

Browse files
mvo5achilleas-k
authored andcommitted
upload: try to auto-detect the upload arch from the filename
This is another convenience feature for the `image-builder upload` command: when we do not know the target architecture try to guess it from the filename. This is not perfect but it will help a lot of users and should be fine until the day we go and inspect the image.
1 parent 03613a3 commit dd13153

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

cmd/image-builder/upload.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"io"
88
"os"
9+
"path/filepath"
10+
"strings"
911

1012
"github.com/cheggaaa/pb/v3"
1113
"github.com/spf13/cobra"
@@ -123,6 +125,26 @@ func uploaderForCmdAWS(cmd *cobra.Command, targetArch string, bootMode *platform
123125
return awscloudNewUploader(region, bucketName, amiName, opts)
124126
}
125127

128+
func detectArchFromImagePath(imagePath string) string {
129+
// This detection is currently rather naive, we just look for
130+
// the file name and try to infer from that. We could extend
131+
// this to smartz like inspect the image via libguestfs or
132+
// add extra metadata to the image. But for now this is what
133+
// we got.
134+
135+
// imagePath by default looks like
136+
// /path/to/<disro>-<imgtype>-<arch>.img.xz
137+
// so try to infer the arch
138+
baseName := filepath.Base(imagePath)
139+
nameNoEx := strings.SplitN(baseName, ".", -1)[0]
140+
frags := strings.Split(nameNoEx, "-")
141+
maybeArch := frags[len(frags)-1]
142+
if a, err := arch.FromString(maybeArch); err == nil {
143+
return a.String()
144+
}
145+
return ""
146+
}
147+
126148
func cmdUpload(cmd *cobra.Command, args []string) error {
127149
imagePath := args[0]
128150

@@ -139,10 +161,14 @@ func cmdUpload(cmd *cobra.Command, args []string) error {
139161
return err
140162
}
141163
if targetArch == "" {
142-
// we could try to inspect the image here and get a
143-
// better guess
144-
targetArch = arch.Current().String()
145-
fmt.Fprintf(osStderr, "WARNING: no upload architecture specified, using %q (use --arch to override)\n", targetArch)
164+
targetArch = detectArchFromImagePath(imagePath)
165+
if targetArch != "" {
166+
fmt.Fprintf(osStderr, "Note: using architecture %q based on image filename (use --arch to override)\n", targetArch)
167+
}
168+
if targetArch == "" {
169+
targetArch = arch.Current().String()
170+
fmt.Fprintf(osStderr, "WARNING: no upload architecture specified, using %q (use --arch to override)\n", targetArch)
171+
}
146172
}
147173

148174
uploader, err := uploaderFor(cmd, uploadTo, targetArch, nil)

cmd/image-builder/upload_test.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,26 @@ func (fa *fakeAwsUploader) UploadAndRegister(r io.Reader, status io.Writer) erro
4848
func TestUploadWithAWSMock(t *testing.T) {
4949
fakeDiskContent := "fake-raw-img"
5050

51-
fakeImageFilePath := filepath.Join(t.TempDir(), "disk.raw")
52-
err := os.WriteFile(fakeImageFilePath, []byte(fakeDiskContent), 0644)
53-
assert.NoError(t, err)
54-
5551
var regionName, bucketName, amiName string
5652
var uploadOpts *awscloud.UploaderOptions
5753

5854
for _, tc := range []struct {
55+
fakeDiskName string
5956
targetArchArg string
6057
expectedUploadArch string
58+
expectedWarning string
6159
}{
62-
{"", "x86_64"},
63-
{"aarch64", "aarch64"},
60+
// simple case: explicit target arch, no warning
61+
{"fake-disk.img", "aarch64", "aarch64", ""},
62+
// no target arch, detectable from filename: add note
63+
{"centos-9-ami-aarch64.img", "", "aarch64", `Note: using architecture "aarch64" based on image filename (use --arch to override)` + "\n"},
64+
// no target arch, not detectable form filename: we warn and expect host arch
65+
{"fake-disk.img", "", arch.Current().String(), fmt.Sprintf("WARNING: no upload architecture specified, using %q (use --arch to override)\n", arch.Current().String())},
6466
} {
67+
fakeImageFilePath := filepath.Join(t.TempDir(), tc.fakeDiskName)
68+
err := os.WriteFile(fakeImageFilePath, []byte(fakeDiskContent), 0644)
69+
assert.NoError(t, err)
70+
6571
var fa fakeAwsUploader
6672
restore := main.MockAwscloudNewUploader(func(region string, bucket string, ami string, opts *awscloud.UploaderOptions) (cloud.Uploader, error) {
6773
regionName = region
@@ -105,9 +111,8 @@ func TestUploadWithAWSMock(t *testing.T) {
105111
assert.Contains(t, fakeStdout.String(), "--] 100.00%")
106112

107113
// warning was passed
108-
if tc.targetArchArg == "" {
109-
assert.Equal(t, fakeStderr.String(), `WARNING: no upload architecture specified, using "x86_64" (use --arch to override)`+"\n")
110-
}
114+
assert.Equal(t, fakeStderr.String(), tc.expectedWarning)
115+
111116
}
112117
}
113118

0 commit comments

Comments
 (0)