image-builder: fix cross-arch uploading

This commit fixes the cross-arch uploading in the most simple
case by reading the `--arch` when `image-builder build --upload`
is used. Note that this is not a complete fix as it will not
take boot mode into account nor will it (by default) DTRT when
`image-builder upload` is used on a previously build images
for a different architecture.

Thanks to `FrostyX` for reporting the issue.
This commit is contained in:
Michael Vogt 2025-05-27 10:58:26 +02:00 committed by Achilleas Koutsou
parent f4f8b557a5
commit 2996bbc0d1
3 changed files with 52 additions and 31 deletions

View file

@ -477,6 +477,7 @@ operating systems like Fedora, CentOS and RHEL with easy customizations support.
uploadCmd.Flags().String("aws-ami-name", "", "name for the AMI in AWS (only for type=ami)")
uploadCmd.Flags().String("aws-bucket", "", "target S3 bucket name for intermediate storage when creating AMI (only for type=ami)")
uploadCmd.Flags().String("aws-region", "", "target region for AWS uploads (only for type=ami)")
uploadCmd.Flags().String("arch", "", "upload for the given architecture")
rootCmd.AddCommand(uploadCmd)
buildCmd := &cobra.Command{

View file

@ -84,6 +84,10 @@ func uploaderForCmdAWS(cmd *cobra.Command) (cloud.Uploader, error) {
if err != nil {
return nil, err
}
targetArch, err := cmd.Flags().GetString("arch")
if err != nil {
return nil, err
}
var missing []string
requiredArgs := []string{"aws-ami-name", "aws-bucket", "aws-region"}
@ -103,8 +107,11 @@ func uploaderForCmdAWS(cmd *cobra.Command) (cloud.Uploader, error) {
return nil, fmt.Errorf("%w: %q", ErrMissingUploadConfig, missing)
}
opts := &awscloud.UploaderOptions{
TargetArch: targetArch,
}
return awscloudNewUploader(region, bucketName, amiName, nil)
return awscloudNewUploader(region, bucketName, amiName, opts)
}
func cmdUpload(cmd *cobra.Command, args []string) error {

View file

@ -51,41 +51,54 @@ func TestUploadWithAWSMock(t *testing.T) {
assert.NoError(t, err)
var regionName, bucketName, amiName string
var fa fakeAwsUploader
restore := main.MockAwscloudNewUploader(func(region string, bucket string, ami string, opts *awscloud.UploaderOptions) (cloud.Uploader, error) {
regionName = region
bucketName = bucket
amiName = ami
return &fa, nil
})
defer restore()
var uploadOpts *awscloud.UploaderOptions
var fakeStdout bytes.Buffer
restore = main.MockOsStdout(&fakeStdout)
defer restore()
for _, tc := range []struct {
targetArchArg string
expectedUploadArch string
}{
{"", ""},
{"aarch64", "aarch64"},
} {
var fa fakeAwsUploader
restore := main.MockAwscloudNewUploader(func(region string, bucket string, ami string, opts *awscloud.UploaderOptions) (cloud.Uploader, error) {
regionName = region
bucketName = bucket
amiName = ami
uploadOpts = opts
return &fa, nil
})
defer restore()
restore = main.MockOsArgs([]string{
"upload",
"--to=aws",
"--aws-region=aws-region-1",
"--aws-bucket=aws-bucket-2",
"--aws-ami-name=aws-ami-3",
fakeImageFilePath,
})
defer restore()
var fakeStdout bytes.Buffer
restore = main.MockOsStdout(&fakeStdout)
defer restore()
err = main.Run()
require.NoError(t, err)
restore = main.MockOsArgs([]string{
"upload",
"--to=aws",
"--aws-region=aws-region-1",
"--aws-bucket=aws-bucket-2",
"--aws-ami-name=aws-ami-3",
"--arch=" + tc.targetArchArg,
fakeImageFilePath,
})
defer restore()
assert.Equal(t, regionName, "aws-region-1")
assert.Equal(t, bucketName, "aws-bucket-2")
assert.Equal(t, amiName, "aws-ami-3")
err = main.Run()
require.NoError(t, err)
assert.Equal(t, 0, fa.checkCalls)
assert.Equal(t, 1, fa.uploadAndRegisterCalls)
assert.Equal(t, fakeDiskContent, fa.uploadAndRegisterRead.String())
// progress was rendered
assert.Contains(t, fakeStdout.String(), "--] 100.00%")
assert.Equal(t, regionName, "aws-region-1")
assert.Equal(t, bucketName, "aws-bucket-2")
assert.Equal(t, amiName, "aws-ami-3")
assert.Equal(t, &awscloud.UploaderOptions{TargetArch: tc.expectedUploadArch}, uploadOpts)
assert.Equal(t, 0, fa.checkCalls)
assert.Equal(t, 1, fa.uploadAndRegisterCalls)
assert.Equal(t, fakeDiskContent, fa.uploadAndRegisterRead.String())
// progress was rendered
assert.Contains(t, fakeStdout.String(), "--] 100.00%")
}
}
func TestUploadCmdlineErrors(t *testing.T) {