Compare commits

...

4 Commits

Author SHA1 Message Date
Ettore Di Giacinto
4b2be221b3 Add kubesplit target 2022-11-03 23:46:36 +00:00
Ettore Di Giacinto
4f87e2329c Add logic to controller to build disks 2022-11-03 23:42:09 +00:00
Ettore Di Giacinto
dc6fb2c6be Set default menu 2022-11-04 00:22:44 +01:00
Ettore Di Giacinto
dc55928694 Add scripts to generate raw images
See: https://github.com/kairos-io/kairos/issues/377
2022-11-03 22:04:50 +00:00
7 changed files with 197 additions and 5 deletions

View File

@@ -276,4 +276,10 @@ unit-tests: test_deps
e2e-tests:
GINKGO=$(GINKGO) KUBE_VERSION=${KUBE_VERSION} $(ROOT_DIR)/script/test.sh
kind-e2e-tests: ginkgo kind-setup install undeploy-dev deploy-dev e2e-tests
kind-e2e-tests: ginkgo kind-setup install undeploy-dev deploy-dev e2e-tests
kubesplit: manifests kustomize
rm -rf helm-chart
mkdir helm-chart
$(KUSTOMIZE) build config/default | kubesplit -helm helm-chart

View File

@@ -30,7 +30,12 @@ type OSArtifactSpec struct {
// Foo is an example field of OSArtifact. Edit osartifact_types.go to remove/update
ImageName string `json:"imageName,omitempty"`
ISO bool `json:"iso,omitempty"`
// This needs to be revisited
ISO bool `json:"iso,omitempty"`
CloudImage bool `json:"cloudImage,omitempty"`
AzureImage bool `json:"azureImage,omitempty"`
GCEImage bool `json:"gceImage,omitempty"`
// TODO: treat cloudconfig as a secret, and take a secretRef where to store it (optionally)
CloudConfig string `json:"cloudConfig,omitempty"`
GRUBConfig string `json:"grubConfig,omitempty"`

View File

@@ -140,12 +140,19 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
})
}
cloudImgCmd := fmt.Sprintf(
"/raw-images.sh /rootfs /public/%s.raw",
artifact.Name,
)
if artifact.Spec.CloudConfig != "" {
volumeMounts = append(volumeMounts, v1.VolumeMount{
Name: "config",
MountPath: "/iso/iso-overlay/cloud_config.yaml",
SubPath: "config",
})
cloudImgCmd += " /iso/iso-overlay/cloud_config.yaml"
}
if artifact.Spec.CloudConfig != "" || artifact.Spec.GRUBConfig != "" {
@@ -167,6 +174,48 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
VolumeMounts: volumeMounts,
}
buildCloudImageContainer := v1.Container{
ImagePullPolicy: v1.PullAlways,
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
Name: "build-cloud-image",
Image: r.ToolImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
cloudImgCmd,
},
VolumeMounts: volumeMounts,
}
buildAzureCloudImageContainer := v1.Container{
ImagePullPolicy: v1.PullAlways,
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
Name: "build-azure-cloud-image",
Image: r.ToolImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"/azure.sh /public/%s.raw /public/%s-azure.raw",
artifact.Name,
),
},
VolumeMounts: volumeMounts,
}
buildGCECloudImageContainer := v1.Container{
ImagePullPolicy: v1.PullAlways,
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
Name: "build-gce-cloud-image",
Image: r.ToolImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"/gce.sh /public/%s.raw /public/%s-azure.raw",
artifact.Name,
),
},
VolumeMounts: volumeMounts,
}
servingContainer := v1.Container{
ImagePullPolicy: v1.PullAlways,
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
@@ -212,11 +261,24 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
}
pod.InitContainers = append(pod.InitContainers, buildIsoContainer)
if artifact.Spec.ISO {
pod.InitContainers = append(pod.InitContainers, buildIsoContainer)
}
if artifact.Spec.CloudImage || artifact.Spec.AzureImage || artifact.Spec.GCEImage {
pod.InitContainers = append(pod.InitContainers, buildCloudImageContainer)
}
if artifact.Spec.AzureImage {
pod.InitContainers = append(pod.InitContainers, buildAzureCloudImageContainer)
}
if artifact.Spec.GCEImage {
pod.InitContainers = append(pod.InitContainers, buildGCECloudImageContainer)
}
if pushImage {
pod.InitContainers = append(pod.InitContainers, createImageContainer(r.ToolImage, artifact.Spec.PushOptions))
}
pod.Containers = []v1.Container{servingContainer}

View File

@@ -28,7 +28,11 @@ FROM quay.io/kairos/packages-arm64:grub-efi-static-0.1 AS grub-efi
FROM quay.io/kairos/packages-arm64:grub-config-static-0.1 AS grub-config
FROM quay.io/kairos/packages-arm64:grub-artifacts-static-0.1 AS grub-artifacts
## RAW images
FROM quay.io/kairos/packages:grub-efi-static-0.1 AS grub-raw-efi
FROM quay.io/kairos/packages:grub-config-static-0.1 AS grub-raw-config
FROM quay.io/kairos/packages:grub-artifacts-static-0.1 AS grub-raw-artifacts
FROM opensuse/leap:$LEAP_VERSION
COPY --from=elemental /usr/bin/elemental /usr/bin/elemental
COPY --from=luet /usr/bin/luet /usr/bin/luet
@@ -37,6 +41,11 @@ COPY --from=luet /usr/bin/luet /usr/bin/luet
COPY --from=grub2 / /grub2
COPY --from=efi / /efi
# RAW images
COPY --from=grub-raw-efi / /raw/grub
COPY --from=grub-raw-config / /raw/grubconfig
COPY --from=grub-raw-artifacts / /raw/grubartifacts
# RPI64
COPY --from=rpi-u-boot / /rpi/u-boot
COPY --from=rpi-firmware / /rpi/rpi-firmware
@@ -71,6 +80,11 @@ COPY ./add-cloud-init.sh /add-cloud-init.sh
COPY ./build-arm-image.sh /build-arm-image.sh
COPY ./arm /arm
# RAW images helpers
COPY ./gce.sh /gce.sh
COPY ./raw-images.sh /raw-images.sh
COPY ./azure.sh /azure.sh
COPY defaults.yaml /defaults.yaml

17
tools-image/azure.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# Transform a raw image disk to azure vhd
RAWIMAGE="$1"
VHDDISK="${2:-disk.vhd}"
cp -rf $RAWIMAGE $VHDDISK.work
MB=$((1024*1024))
size=$(qemu-img info -f raw --output json "$RAWIMAGE" | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}')
# shellcheck disable=SC2004
ROUNDED_SIZE=$(((($size+$MB-1)/$MB)*$MB))
echo "Resizing raw image to $ROUNDED_SIZE"
qemu-img resize -f raw "$VHDDISK.work" $ROUNDED_SIZE
echo "Converting $RAWIMAGE to $VHDDISK"
qemu-img convert -f raw -o subformat=fixed,force_size -O vpc "$VHDDISK.work" "$VHDDISK"
echo "Done"
rm -rf "$VHDDISK.work"

15
tools-image/gce.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Transform a raw image disk to gce compatible
RAWIMAGE="$1"
OUT="${2:-$RAWIMAGE.gce.raw}"
cp -rf $RAWIMAGE $OUT
GB=$((1024*1024*1024))
size=$(qemu-img info -f raw --output json "$OUT" | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}')
# shellcheck disable=SC2004
ROUNDED_SIZE=$(echo "$size/$GB+1"|bc)
echo "Resizing raw image from \"$size\"MB to \"$ROUNDED_SIZE\"GB"
qemu-img resize -f raw "$OUT" "$ROUNDED_SIZE"G
echo "Compressing raw image $OUT to $OUT.tar.gz"
tar -c -z --format=oldgnu -f "$OUT".tar.gz $OUT

73
tools-image/raw-images.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
# Generates EFI bootable images (statically)
# This is a re-adaptation of https://github.com/rancher/elemental-toolkit/blob/v0.8.10-1/images/img-builder.sh, which was dropped
# How to use:
# First extract the image which you want to create an image from:
### luet util unpack <image> rootfs
# Then convert it to a raw disk (EFI only):
### docker run -v $PWD:/output --entrypoint /raw-images.sh -ti --rm test-image /output/rootfs /output/foo.raw cloud-init.yaml
: "${OEM_LABEL:=COS_OEM}"
: "${RECOVERY_LABEL:=COS_RECOVERY}"
DIRECTORY=$1
OUT=${2:-disk.raw}
CONFIG=$3
echo "Output: $OUT"
set -e
mkdir -p /build/root/grub2
mkdir /build/root/cOS
mkdir /build/efi
cp -rf /raw/grub/* /build/efi
cp -rf /raw/grubconfig/* /build/root
cp -rf /raw/grubartifacts/* /build/root/grub2
echo "Generating squashfs from $DIRECTORY"
mksquashfs $DIRECTORY recovery.squashfs -b 1024k -comp xz -Xbcj x86
mv recovery.squashfs /build/root/cOS/recovery.squashfs
grub2-editenv /build/root/grub_oem_env set "default_menu_entry=Kairos"
# Create a 2GB filesystem for RECOVERY including the contents for root (grub config and squasfs container)
truncate -s $((2048*1024*1024)) rootfs.part
mkfs.ext2 -L "${RECOVERY_LABEL}" -d /build/root rootfs.part
# Create the EFI partition FAT16 and include the EFI image and a basic grub.cfg
truncate -s $((20*1024*1024)) efi.part
mkfs.fat -F16 -n COS_GRUB efi.part
mcopy -s -i efi.part /build/efi/EFI ::EFI
# Create the grubenv forcing first boot to be on recovery system
mkdir -p /build/oem
cp /build/root/etc/cos/grubenv_firstboot /build/oem/grubenv
if [ -n "$CONFIG" ]; then
echo "Copying config file ($CONFIG)"
cp $CONFIG /build/oem
fi
# Create a 64MB filesystem for OEM volume
truncate -s $((64*1024*1024)) oem.part
mkfs.ext2 -L "${OEM_LABEL}" -d /build/oem oem.part
echo "Generating image $OUT"
# Create disk image, add 3MB of initial free space to disk, 1MB is for proper alignement, 2MB are for the hybrid legacy boot.
truncate -s $((3*1024*1024)) $OUT
{
cat efi.part
cat oem.part
cat rootfs.part
} >> $OUT
# Add an extra MB at the end of the disk for the gpt headers, in fact 34 sectors would be enough, but adding some more does not hurt.
truncate -s "+$((1024*1024))" $OUT
# Create the partition table in $OUT (assumes sectors of 512 bytes)
sgdisk -n 1:2048:+2M -c 1:legacy -t 1:EF02 $OUT
sgdisk -n 2:0:+20M -c 2:UEFI -t 2:EF00 $OUT
sgdisk -n 3:0:+64M -c 3:oem -t 3:8300 $OUT
sgdisk -n 4:0:+2048M -c 4:root -t 4:8300 $OUT