Skip to content

Commit 504361e

Browse files
committed
add tests
1 parent d5063fe commit 504361e

File tree

18 files changed

+678
-162
lines changed

18 files changed

+678
-162
lines changed

toolkit/tools/imagecreator/main.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ import (
1818
)
1919

2020
type ImageCreatorCmd struct {
21-
BuildDir string `name:"build-dir" help:"Directory to run build out of." required:""`
22-
ConfigFile string `name:"config-file" help:"Path of the image customization config file." required:""`
23-
RpmSources []string `name:"rpm-source" help:"Path to a RPM repo config file or a directory containing RPMs."`
24-
ToolsTar string `name:"tools-file" help:"Path to tdnf worker tarball"`
25-
OutputImageFile string `name:"output-image-file" help:"Path to write the customized image to."`
21+
BuildDir string `name:"build-dir" help:"Directory to run build out of." required:""`
22+
ConfigFile string `name:"config-file" help:"Path of the image customization config file." required:""`
23+
RpmSources []string `name:"rpm-source" help:"Path to a RPM repo config file or a directory containing RPMs."`
24+
ToolsTar string `name:"tools-file" help:"Path to tdnf worker tarball"`
25+
OutputImageFile string `name:"output-image-file" help:"Path to write the customized image to."`
26+
OutputImageFormat string `name:"output-image-format" placeholder:"(vhd|vhd-fixed|vhdx|qcow2|raw)" help:"Format of output image." enum:"${imageformat}" default:""`
2627
exekong.LogFlags
2728
}
2829

@@ -44,7 +45,7 @@ func main() {
4445

4546
logger.InitBestEffort(ptrutils.PtrTo(cli.LogFlags.AsLoggerFlags()))
4647

47-
err := imagecreatorlib.CreateImageWithConfigFile(cli.BuildDir, cli.ConfigFile, cli.RpmSources, cli.ToolsTar, cli.OutputImageFile)
48+
err := imagecreatorlib.CreateImageWithConfigFile(cli.BuildDir, cli.ConfigFile, cli.RpmSources, cli.ToolsTar, cli.OutputImageFile, cli.OutputImageFormat)
4849
if err != nil {
4950
log.Fatalf("image creation failed:\n%v", err)
5051
}

toolkit/tools/pkg/imagecustomizerlib/testdata/testrpms/download-test-rpms.sh renamed to toolkit/tools/internal/testutils/testrpms/download-test-rpms.sh

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,39 @@ CONTAINER_TAG="imagecustomizertestrpms:latest"
66
DOCKERFILE_DIR="$SCRIPT_DIR/downloader"
77

88
AZURELINUX_2_CONTAINER_IMAGE="mcr.microsoft.com/cbl-mariner/base/core:2.0"
9+
AZURELINUX_3_CONTAINER_IMAGE="mcr.microsoft.com/azurelinux/base/core:3.0"
910

1011
IMAGE_VERSION="2.0"
1112

12-
while getopts "t:" flag
13+
IMAGE_CREATOR="false"
14+
TOOLS_FILE="$SCRIPT_DIR/tools.tar.gz"
15+
16+
17+
while getopts "s:t:" flag
1318
do
1419
case "${flag}" in
20+
s) IMAGE_CREATOR="$OPTARG";;
1521
t) IMAGE_VERSION="$OPTARG";;
1622
h) ;;&
1723
?)
18-
echo "Usage: download-test-rpms.sh [-t IMAGE_VERSION]"
24+
echo "Usage: download-test-rpms.sh [-t IMAGE_VERSION] [-s IMAGE_CREATOR]"
1925
echo ""
2026
echo "Args:"
2127
echo " -t IMAGE_VERSION The Azure Image version to download the RPMs for."
28+
echo " -s IMAGE_CREATOR If set to true, the script will create a tar.gz file with the tools and download the rpms needed to test imagecreator."
2229
echo " -h Show help"
2330
exit 1;;
2431
esac
2532
done
2633

34+
2735
case "${IMAGE_VERSION}" in
36+
3.0)
37+
CONTAINER_IMAGE="$AZURELINUX_3_CONTAINER_IMAGE"
38+
;;
2839
2.0)
2940
CONTAINER_IMAGE="$AZURELINUX_2_CONTAINER_IMAGE"
30-
;;
41+
;;
3142
*)
3243
echo "error: unsupported Azure Linux version: $IMAGE_VERSION"
3344
exit 1;;
@@ -44,10 +55,19 @@ mkdir -p "$OUT_DIR"
4455

4556
# Build a container image that contains the RPMs.
4657
docker build \
47-
--build-arg "baseimage=$AZURELINUX_2_CONTAINER_IMAGE" \
58+
--build-arg "baseimage=$CONTAINER_IMAGE" \
59+
--build-arg "imagecreator=$IMAGE_CREATOR" \
4860
--tag "$CONTAINER_TAG" \
4961
"$DOCKERFILE_DIR"
5062

63+
64+
# if IMAGE_CREATOR is set to true, create a tar.gz file with the tools.
65+
if [ "$IMAGE_CREATOR" = "true" ]; then
66+
docker create --name temp-container ${CONTAINER_TAG}
67+
docker export temp-container | gzip > "$TOOLS_FILE"
68+
docker rm temp-container
69+
fi
70+
5171
# Extract the RPM files.
5272
docker run \
5373
--rm \
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
ARG baseimage
2+
FROM ${baseimage}
3+
4+
ARG imagecreator
5+
6+
7+
8+
RUN tdnf update -y && \
9+
tdnf install -y dnf dnf-plugins-core createrepo_c
10+
11+
RUN dnf download -y --resolve --alldeps --destdir /downloadedrpms \
12+
jq golang
13+
14+
RUN if [ "${imagecreator}" = "true" ]; then \
15+
16+
dnf download -y --resolve --alldeps --destdir /downloadedrpms \
17+
azurelinux-release \
18+
azurelinux-repos azurelinux-rpm-macros bash dbus dracut-hostonly e2fsprogs filesystem \
19+
grub2 grub2-efi-binary iana-etc iproute iputils irqbalance \
20+
ncurses-libs openssl rpm rpm-libs shadow-utils shim sudo \
21+
systemd systemd-networkd systemd-resolved systemd-udev tdnf \
22+
tdnf-plugin-repogpgcheck util-linux zlib kernel initramfs ; \
23+
24+
fi
25+
26+
# Add repo metadata, so that the directory can be used in a .repo file.
27+
RUN createrepo --compatibility --update /downloadedrpms
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package testutils
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"fmt"
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
11+
"github.com/microsoft/azurelinux/toolkit/tools/internal/file"
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func GetImageFileType(filePath string) (string, error) {
16+
file, err := os.OpenFile(filePath, os.O_RDONLY, 0)
17+
if err != nil {
18+
return "", err
19+
}
20+
defer file.Close()
21+
22+
stat, err := file.Stat()
23+
if err != nil {
24+
return "", err
25+
}
26+
27+
firstBytes := make([]byte, 512)
28+
firstBytesCount, err := file.Read(firstBytes)
29+
if err != nil {
30+
return "", err
31+
}
32+
33+
lastBytes := make([]byte, 512)
34+
lastBytesCount, err := file.ReadAt(lastBytes, max(0, stat.Size()-512))
35+
if err != nil {
36+
return "", err
37+
}
38+
39+
switch {
40+
case firstBytesCount >= 8 && bytes.Equal(firstBytes[:8], []byte("conectix")):
41+
return "vhd", nil
42+
43+
case firstBytesCount >= 8 && bytes.Equal(firstBytes[:8], []byte("vhdxfile")):
44+
return "vhdx", nil
45+
46+
case isZstFile(firstBytes):
47+
return "zst", nil
48+
49+
// Check for the MBR signature (which exists even on GPT formatted drives).
50+
case firstBytesCount >= 512 && bytes.Equal(firstBytes[510:512], []byte{0x55, 0xAA}):
51+
switch {
52+
case lastBytesCount >= 512 && bytes.Equal(lastBytes[:8], []byte("conectix")):
53+
return "vhd-fixed", nil
54+
55+
default:
56+
return "raw", nil
57+
}
58+
59+
default:
60+
return "", fmt.Errorf("unknown file type: %s", filePath)
61+
}
62+
}
63+
64+
func isZstFile(firstBytes []byte) bool {
65+
if len(firstBytes) < 4 {
66+
return false
67+
}
68+
69+
magicNumber := binary.LittleEndian.Uint32(firstBytes[:4])
70+
71+
// 0xFD2FB528 is a zst frame.
72+
// 0x184D2A50-0x184D2A5F are skippable ztd frames.
73+
return magicNumber == 0xFD2FB528 || (magicNumber >= 0x184D2A50 && magicNumber <= 0x184D2A5F)
74+
}
75+
76+
func GetDownloadedRpmsDir(t *testing.T, testutilsDir string, azureLinuxVersion string, imagecreator bool) string {
77+
downloadedRpmsDir := filepath.Join(testutilsDir, "testrpms/downloadedrpms", azureLinuxVersion)
78+
dirExists, err := file.DirExists(downloadedRpmsDir)
79+
if !assert.NoErrorf(t, err, "cannot access downloaded RPMs dir (%s)", downloadedRpmsDir) {
80+
t.FailNow()
81+
}
82+
if !assert.True(t, dirExists) {
83+
// log the downloadedRpmsDir
84+
t.Logf("downloadedRpmsDir: %s", downloadedRpmsDir)
85+
t.Logf("test requires offline RPMs")
86+
t.Logf("please run toolkit/tools/internal/testutils/testrpms/download-test-rpms.sh -t %s -s %t",
87+
azureLinuxVersion, imagecreator)
88+
t.FailNow()
89+
}
90+
91+
return downloadedRpmsDir
92+
}
93+
94+
func GetDownloadedToolsFile(t *testing.T, testutilsDir string, azureLinuxVersion string, imagecreator bool) string {
95+
GetDownloadedToolsFile := filepath.Join(testutilsDir, "testrpms/tools.tar.gz")
96+
if !assert.FileExists(t, GetDownloadedToolsFile) {
97+
t.Logf("test requires downloaded tools file")
98+
t.Logf("please run toolkit/tools/internal/testutils/testrpms/download-test-rpms.sh -t %s -s %t",
99+
azureLinuxVersion, imagecreator)
100+
t.FailNow()
101+
}
102+
return GetDownloadedToolsFile
103+
}
104+
105+
func GetDownloadedRpmsRepoFile(t *testing.T, testutilsDir string, azureLinuxVersion string, withGpgKey bool, imagecreator bool) string {
106+
dir := GetDownloadedRpmsDir(t, testutilsDir, azureLinuxVersion, imagecreator)
107+
108+
suffix := "nokey"
109+
if withGpgKey {
110+
suffix = "withkey"
111+
}
112+
113+
repoFile := filepath.Join(dir, "../", fmt.Sprintf("rpms-%s-%s.repo", azureLinuxVersion, suffix))
114+
return repoFile
115+
}

0 commit comments

Comments
 (0)