Skip to content

Commit 74af037

Browse files
authored
Add Ubuntu EMF template (#384)
* Add ubuntu24 EMF template Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> * Update ubuntu24 server cloud template for EMF - Update imagedisc.go to support FAT32 and FAT16 when specified Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> * Update ubuntu24-server-cloud-amd64.yml Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> --------- Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com>
1 parent 96cf523 commit 74af037

File tree

4 files changed

+192
-3
lines changed

4 files changed

+192
-3
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Image metadata describing template identity
2+
# this template attempt to create ubuntu cloud server in qcow2
3+
# based on https://cloud-images.ubuntu.com/server/releases/noble/release-20250429/ubuntu-24.04-server-cloudimg-amd64.img
4+
image:
5+
name: ubuntu-server-cloud-amd64
6+
version: "24.04"
7+
8+
# Target platform that the image builder should produce
9+
target:
10+
# Provider family
11+
os: ubuntu
12+
# Distribution release within provider family
13+
dist: ubuntu24
14+
# CPU architecture for artifacts
15+
arch: x86_64
16+
# Artifact format expected from build pipeline
17+
imageType: raw
18+
19+
# Disk layout and output artifact definition
20+
disk:
21+
# Human friendly name logged by builders
22+
name: ubuntu-server-cloud-raw
23+
artifacts:
24+
# Request conversion to qcow2
25+
- type: raw
26+
compression: gz
27+
size: 3500MiB
28+
# GPT partition table per installer spec
29+
partitionTableType: gpt
30+
partitions:
31+
# BIOS boot partition for GRUB compatibility - first partition
32+
- id: BIOSBOOT
33+
type: bios-boot
34+
# GPT type GUID for BIOS boot partition
35+
typeUUID: 21686148-6449-6e6f-744e-656564454649
36+
fsType: ext2
37+
start: 1MiB
38+
end: 5MiB
39+
flags:
40+
- bios_grub
41+
# EFI system partition for bootloaders - second partition
42+
- id: EFI
43+
type: esp
44+
# GPT type GUID for EFI system partition
45+
typeUUID: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
46+
fsType: fat32
47+
fsLabel: UEFI
48+
start: 5MiB
49+
end: 116MiB
50+
mountPoint: /boot/efi
51+
mountOptions: defaults
52+
flags:
53+
- boot
54+
- esp
55+
# Dedicated /boot to host kernels and bootloader assets - third partition
56+
- id: BOOT
57+
type: linux
58+
# GPT GUID for Linux /boot partition
59+
typeUUID: bc13c2ff-59e6-4262-a352-b275fd6f7172
60+
fsType: ext4
61+
fsLabel: BOOT
62+
start: 116MiB
63+
end: 1073MiB
64+
mountPoint: /boot
65+
mountOptions: defaults
66+
flags: []
67+
# Root filesystem - last partition for easy expansion
68+
- id: rootfs
69+
name: cloudimg-rootfs
70+
type: linux-root-amd64
71+
# Standard Linux root filesystem GUID for x86_64
72+
typeUUID: 4f68bce3-e8cd-4db1-96e7-fbcaf984b709
73+
fsType: ext4
74+
fsLabel: cloudimg-rootfs
75+
start: 1073MiB
76+
end: "0"
77+
mountPoint: /
78+
mountOptions: defaults
79+
flags: []
80+
81+
# Host OS configuration applied within the image
82+
systemConfig:
83+
# Name reused by logging and validation output
84+
name: ubuntu-server-cloud-amd64
85+
# High-level description surfaced in manifests
86+
description: server Ubuntu 24.04 cloud image for x86_64
87+
88+
immutability:
89+
enabled: false # default is true, overridden to false here
90+
91+
# Bootloader settings; grub following ubuntu defaults
92+
bootloader:
93+
bootType: efi
94+
provider: grub
95+
# Packages derived from ubuntu server cloud image
96+
packages:
97+
- base-files
98+
- bash
99+
- bsdutils
100+
- cloud-init
101+
- dash
102+
- diffutils
103+
- eatmydata
104+
- findutils
105+
- grep
106+
- grub-pc
107+
- gzip
108+
- hostname
109+
- init
110+
- libeatmydata1
111+
- libwrap0
112+
- linux-virtual
113+
- login
114+
- ncurses-base
115+
- ncurses-bin
116+
- ncurses-term
117+
- openssh-server
118+
- openssh-sftp-server
119+
- python-babel-localedata
120+
- python3-babel
121+
- python3-jinja2
122+
- python3-json-pointer
123+
- python3-jsonpatch
124+
- python3-jsonschema
125+
- python3-markupsafe
126+
- python3-pyrsistent
127+
- python3-serial
128+
- python3-tz
129+
- shim-signed
130+
- ssh-import-id
131+
- ubuntu-minimal
132+
- ubuntu-server
133+
- ubuntu-standard
134+
- util-linux
135+
136+
## other top level package
137+
- snapd
138+
- systemd-resolved
139+
140+
## Packages required by installer.sh (services that must pre-exist)
141+
- systemd-timesyncd
142+
- rsyslog
143+
- ufw
144+
- cron
145+
- logrotate
146+
- unattended-upgrades
147+
148+
# Kernel metadata used by builder to set cmdline and module hints
149+
kernel:
150+
version: "6.11"
151+
cmdline: "root=LABEL=cloudimg-rootfs ro console=tty1 console=ttyS0"
152+
packages:
153+
- linux-image-6.11.0-17-generic

internal/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ type PartitionInfo struct {
176176
Type string `yaml:"type"` // Type: partition type (e.g., "esp", "linux-root-amd64")
177177
TypeGUID string `yaml:"typeUUID"` // TypeGUID: GPT type GUID for the partition (e.g., "8300" for Linux filesystem)
178178
FsType string `yaml:"fsType"` // FsType: filesystem type (e.g., "ext4", "xfs", etc.);
179+
FsLabel string `yaml:"fsLabel"` // FsLabel: filesystem label (e.g., "cloudimg-rootfs")
179180
Start string `yaml:"start"` // Start: start offset of the partition; can be a absolute size (e.g., "512MiB")
180181
End string `yaml:"end"` // End: end offset of the partition; can be a absolute size (e.g., "2GiB") or "0" for the end of the disk
181182
MountPoint string `yaml:"mountPoint"` // MountPoint: optional mount point for the partition (e.g., "/boot", "/rootfs")

internal/config/schema/os-image-template.schema.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"type": { "type": "string", "description": "Partition type" },
117117
"typeUUID": { "type": "string", "description": "Partition type UUID" },
118118
"fsType": { "type": "string", "description": "Filesystem type" },
119+
"fsLabel": { "type": "string", "description": "Filesystem label" },
119120
"start": { "type": "string", "description": "Partition start offset" },
120121
"end": { "type": "string", "description": "Partition end offset (0 = rest of disk)" },
121122
"mountPoint": { "type": "string", "description": "Mount point path" },

internal/image/imagedisc/imagedisc.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,29 @@ func diskPartitionCreate(
574574
}
575575

576576
if partitionInfo.FsType == "fat32" || partitionInfo.FsType == "fat16" || partitionInfo.FsType == "vfat" {
577-
cmdStr = fmt.Sprintf("mkfs -t vfat %s", diskPartDev)
577+
var fatTypeFlag string
578+
switch partitionInfo.FsType {
579+
case "fat32":
580+
fatTypeFlag = "-F 32"
581+
case "fat16":
582+
fatTypeFlag = "-F 16"
583+
default: // "vfat"
584+
fatTypeFlag = "" // Let mkfs.vfat auto-decide
585+
}
586+
587+
if partitionInfo.FsLabel != "" {
588+
if fatTypeFlag != "" {
589+
cmdStr = fmt.Sprintf("mkfs -t vfat %s -n %s %s", fatTypeFlag, partitionInfo.FsLabel, diskPartDev)
590+
} else {
591+
cmdStr = fmt.Sprintf("mkfs -t vfat -n %s %s", partitionInfo.FsLabel, diskPartDev)
592+
}
593+
} else {
594+
if fatTypeFlag != "" {
595+
cmdStr = fmt.Sprintf("mkfs -t vfat %s %s", fatTypeFlag, diskPartDev)
596+
} else {
597+
cmdStr = fmt.Sprintf("mkfs -t vfat %s", diskPartDev)
598+
}
599+
}
578600
_, err := shell.ExecCmd(cmdStr, true, shell.HostPath, nil)
579601
if err != nil {
580602
log.Errorf("Failed to format partition %d with fs type %s: %v", partitionNum, partitionInfo.FsType, err)
@@ -590,8 +612,16 @@ func diskPartitionCreate(
590612
case "ext4":
591613
additionalFlags = "-b 4096 -O none,sparse_super,large_file,filetype,resize_inode,dir_index,ext_attr,has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize"
592614
}
593-
if additionalFlags != "" {
615+
var labelFlag string
616+
if partitionInfo.FsLabel != "" {
617+
labelFlag = fmt.Sprintf("-L %s", partitionInfo.FsLabel)
618+
}
619+
if additionalFlags != "" && labelFlag != "" {
620+
cmdStr = fmt.Sprintf("mkfs -t %s %s %s %s", partitionInfo.FsType, labelFlag, additionalFlags, diskPartDev)
621+
} else if additionalFlags != "" {
594622
cmdStr = fmt.Sprintf("mkfs -t %s %s %s", partitionInfo.FsType, additionalFlags, diskPartDev)
623+
} else if labelFlag != "" {
624+
cmdStr = fmt.Sprintf("mkfs -t %s %s %s", partitionInfo.FsType, labelFlag, diskPartDev)
595625
} else {
596626
cmdStr = fmt.Sprintf("mkfs -t %s %s", partitionInfo.FsType, diskPartDev)
597627
}
@@ -601,7 +631,11 @@ func diskPartitionCreate(
601631
return "", fmt.Errorf("failed to format partition %d with fs type %s: %w", partitionNum, partitionInfo.FsType, err)
602632
}
603633
} else if partitionInfo.FsType == "linux-swap" {
604-
cmdStr = fmt.Sprintf("mkswap %s", diskPartDev)
634+
if partitionInfo.FsLabel != "" {
635+
cmdStr = fmt.Sprintf("mkswap -L %s %s", partitionInfo.FsLabel, diskPartDev)
636+
} else {
637+
cmdStr = fmt.Sprintf("mkswap %s", diskPartDev)
638+
}
605639
_, err := shell.ExecCmd(cmdStr, true, shell.HostPath, nil)
606640
if err != nil {
607641
log.Errorf("Failed to format partition %d with fs type %s: %v", partitionNum, partitionInfo.FsType, err)

0 commit comments

Comments
 (0)