summaryrefslogtreecommitdiffstats
path: root/recipes-extended/images/xen-image-minimal.bb
blob: 6da797d72cc467be035199d63a4fc8447ade41fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
DESCRIPTION = "A minimal xen image"

inherit features_check

REQUIRED_DISTRO_FEATURES ?= "xen systemd"

INITRD_IMAGE = "core-image-minimal-initramfs"

XEN_KERNEL_MODULES ?= "kernel-module-xen-blkback kernel-module-xen-gntalloc \
                       kernel-module-xen-gntdev kernel-module-xen-netback kernel-module-xen-wdt \
                       kernel-module-xt-comment kernel-module-xt-masquerade \
                       ${@bb.utils.contains('MACHINE_FEATURES', 'pci', "${XEN_PCIBACK_MODULE}", '', d)} \
                       ${@bb.utils.contains('MACHINE_FEATURES', 'acpi', '${XEN_ACPI_PROCESSOR_MODULE}', '', d)} \
                      "

IMAGE_INSTALL += " \
    packagegroup-core-boot \
    packagegroup-core-ssh-openssh \
    ${XEN_KERNEL_MODULES} \
    xen-tools \
    qemu \
    kernel-image \
    kernel-vmlinux \
    rsync \
    "

# The hypervisor may not be within the dom0 filesystem image but at least
# ensure that it is deployable:
do_build[depends] += "xen:do_deploy"

# Networking for HVM-mode guests (x86/64 only) requires the tun kernel module
IMAGE_INSTALL:append:x86    = " kernel-module-tun"
IMAGE_INSTALL:append:x86-64 = " kernel-module-tun"

# Linux kernel option CONFIG_XEN_PCIDEV_BACKEND depends on X86
XEN_PCIBACK_MODULE = ""
XEN_PCIBACK_MODULE:x86    = "kernel-module-xen-pciback"
XEN_PCIBACK_MODULE:x86-64 = "kernel-module-xen-pciback"
XEN_ACPI_PROCESSOR_MODULE = ""
XEN_ACPI_PROCESSOR_MODULE:x86    = "kernel-module-xen-acpi-processor"
XEN_ACPI_PROCESSOR_MODULE:x86-64 = "kernel-module-xen-acpi-processor"

LICENSE = "MIT"

QB_NETWORK_XEN_BRIDGE = "1"

inherit core-image
# Only inherit the qemuboot classes when building for a qemu machine
QB_QEMU_CLASSES = ""
QB_QEMU_CLASSES:qemuall = "qemuboot-xen-defaults qemuboot-xen-dtb qemuboot-testimage-network"
inherit ${QB_QEMU_CLASSES}

# note: this may be unused, see the wic plugin
syslinux_iso_populate:append() {
	install -m 0444 ${STAGING_DATADIR}/syslinux/libcom32.c32 ${ISODIR}${ISOLINUXDIR}
	install -m 0444 ${STAGING_DATADIR}/syslinux/mboot.c32 ${ISODIR}${ISOLINUXDIR}
}

# note: this may be unused, see the wic plugin
syslinux_hddimg_populate:append() {
	install -m 0444 ${STAGING_DATADIR}/syslinux/libcom32.c32 ${HDDDIR}${SYSLINUXDIR}
	install -m 0444 ${STAGING_DATADIR}/syslinux/mboot.c32 ${HDDDIR}${SYSLINUXDIR}
}

# note: this may be unused, see the wic plugin
grubefi_populate:append() {
	install -m 0644 ${DEPLOY_DIR_IMAGE}/xen-${MACHINE}.gz ${DEST}${EFIDIR}/xen.gz
}

# note: this may be unused, see the wic plugin
syslinux_populate:append() {
	install -m 0644 ${DEPLOY_DIR_IMAGE}/xen-${MACHINE}.gz ${DEST}/xen.gz
}

SYSLINUX_XEN_ARGS ?= "loglvl=all guest_loglvl=all console=com1,vga com1=115200,8n1"
SYSLINUX_KERNEL_ARGS ?= "ramdisk_size=32768 root=/dev/ram0 rw console=hvc0 earlyprintk=xen console=tty0 panic=10 LABEL=boot debugshell=5"

# note: this may be unused, see the wic plugin
build_syslinux_cfg () {
	echo "ALLOWOPTIONS 1" > ${SYSLINUX_CFG}
	echo "DEFAULT boot" >> ${SYSLINUX_CFG}
	echo "TIMEOUT 10" >> ${SYSLINUX_CFG}
	echo "PROMPT 1" >> ${SYSLINUX_CFG}
	echo "LABEL boot" >> ${SYSLINUX_CFG}
	echo "  KERNEL mboot.c32" >> ${SYSLINUX_CFG}
	echo "  APPEND /xen.gz ${SYSLINUX_XEN_ARGS} --- /vmlinuz ${SYSLINUX_KERNEL_ARGS} --- /initrd" >> ${SYSLINUX_CFG}
}

# Function to parse the config file and get values for specific keys
get_config_value() {
    config_file="$1"
    key="$2"
    line=$(grep -w "$key" $config_file)
    value=$(echo "$line" | cut -d '=' -f 2-)
    # Remove quotes, leading/trailing whitespace, and content after the first comma
    echo "${value#*=}" | sed "s/'//g; s/^\s*|\s*$//g; s/\[//g;s/\"//g;s/^ *//g;" | cut -d ',' -f 1
}

generate_guest_config() {
    name=$1
    kernel=$2
    disk=$3
    outname=$name.cfg

    cat <<EOF >${DEPLOY_DIR_IMAGE}/$outname
name = "$name"
memory = 512
vcpus = 1
disk = ['file:$disk,xvda,rw']
vif = ['bridge=xenbr0']
kernel = "$kernel"
extra = "root=/dev/xvda ro ip=dhcp"
EOF
}

# Guests can be bundled automatically through the following mechanisms:
#
#   - via the variable XEN_BUNDLED_GUESTS
#   - via a xen configuration file in the deploy directory of the format
#     xen-guest-bundle-*.cfg
#
# The guests can be built via OE, or be 3rd party guests. They just
# must be in the deploy directory so they can be copied into the rootfs
# of the xen host image
#
# Type 1) XEN_BUNDLED_GUESTS
#
# If XEN_BUNDLED_GUESTS is used, it is simply a colon separated list of
# rootfs:kernels. Normal variable rules apply, so it can be set in a
# local.conf, or in a bbappend to the image recipe.
#
# An example would be:
#
#  XEN_BUNDLED_GUESTS = "xen-guest-image-minimal-qemuarm64.rootfs.ext4:Image"
#
# These point at symlinks created in the image deploy directory, or they
# can be specific images/kernels without the symlink.
#
# Type 2) A Xen guest configuration file
#
# If xen guest configuration files are found in the deploy directories
# the kernel and disk information contained within them will be processed
# and modified for the xen host. The kernel and guest image will be
# copied to the appropriate location, and the config made to match.
#
# These files following the naming convention: xen-guest-bundle*.cfg
#
# Guests of type #1 generate a configuration file that is picked up as
# type #2.
#
# An example config file follows:
#
## name = "xen-guest"
## memory = 512
## vcpus = 1
## disk = ['file:xen-guest-image-minimal-qemuarm64.rootfs.ext4,xvda,rw']
## vif = ['bridge=xenbr0']
## kernel = "Image"
## extra = "root=/dev/xvda ro console=hvc0 ip=dhcp"
#
# It should also be noted that when a xen-guest-image-minimal is built
# with the XEN_GUEST_AUTO_BUNDLE varaible set to True, a configuration
# file for type #2 will be generated and the guest bundled automatically
# when the host image is built.
#
# kernel and rootfs are copied to the target in /var/lib/xen/images/
#
# configuration files are copied to: /etc/xen
#
# Guests can be launched after boot with: xl create -c /etc/xen/<config file>
#
bundle_xen_guests() {
    set +e

    if [ -n "${XEN_BUNDLED_GUESTS}" ]; then
	echo "Processing Xen bundled guests variable: ${XEN_BUNDLED_GUESTS}"
	# these are a colon separated list of rootfs:kernel
	count=1
	for g in ${XEN_BUNDLED_GUESTS}; do
	    echo "Guest line: $g"
	    rootfs=$(echo "$g" | cut -d":" -f1)
	    kernel=$(echo "$g" | cut -d":" -f2)
	    name="xen-guest-bundle-$count"

	    if ! [ -e ${DEPLOY_DIR_IMAGE}/$rootfs ]; then
		echo "rootfs '${DEPLOY_DIR_IMAGE}/$rootfs' not found, skipping ...."
		continue
	    fi
	    if ! [ -e ${DEPLOY_DIR_IMAGE}/$kernel ]; then
		echo "kernel '${DEPLOY_DIR_IMAGE}/$kernel' not found, skipping ...."
		continue
	    fi

	    generate_guest_config $name $kernel $rootfs

	    count=$(expr $count + 1)
	done
    fi

    echo ls ${DEPLOY_DIR_IMAGE}/xen-guest-bundle*.cfg
    ls ${DEPLOY_DIR_IMAGE}/xen-guest-bundle*.cfg >/dev/null 2>/dev/null
    if [ $? -eq 0 ]; then
	for guest_cfg in $(ls ${DEPLOY_DIR_IMAGE}/xen-guest-bundle*.cfg); do
	    echo "Bundling guest: $guest_cfg"

	    CONFIG_FILE_BASE=$(basename $guest_cfg .cfg)
	    CONFIG_FILE="${DEPLOY_DIR_IMAGE}/$CONFIG_FILE_BASE.cfg"
	    DEST_DIR="${IMAGE_ROOTFS}/var/lib/xen/images"
	    MODIFIED_CONFIG_FILE="${DEPLOY_DIR_IMAGE}/$CONFIG_FILE_BASE-modified.cfg"

	    # Extract values from the configuration file
	    DISK_ORIG=$(get_config_value $CONFIG_FILE "disk" | sed 's/file://g')
	    DISK=$(readlink -f ${DEPLOY_DIR_IMAGE}/$DISK_ORIG)
	    DISK_NAME=$(basename $DISK)
	    KERNEL_ORIG=$(get_config_value $CONFIG_FILE "kernel")
	    KERNEL=$(readlink -f ${DEPLOY_DIR_IMAGE}/$KERNEL_ORIG)
	    KERNEL_NAME=$(basename $KERNEL)

	    if [ -z "$DISK" ]; then
		echo "rootfs '$DISK' not found, skipping ...."
		continue
	    fi
	    if [ -z "$KERNEL" ]; then
		echo "kernel '$KERNEL' not found, skipping ...."
		continue
	    fi

	    mkdir -p "$DEST_DIR"
	    # Copy the disk and kernel to the destination directory
	    echo "Copying disk and kernel files..."
	    echo cp "$DISK" "$DEST_DIR"
	    echo cp "$KERNEL" "$DEST_DIR"
	    cp "$DISK" "$DEST_DIR"
	    cp "$KERNEL" "$DEST_DIR"

	    # Create a modified config file with updated paths
	    sed -E \
		-e "s#^(disk = \[)[^,]+#\1'file:/var/lib/xen/images/$DISK_NAME#" \
		-e "s#^(kernel = )\"[^\"]+\"#\1\"/var/lib/xen/images/$KERNEL_NAME\"#" \
		"$CONFIG_FILE" > "$MODIFIED_CONFIG_FILE"

	    mkdir -p ${IMAGE_ROOTFS}/etc/xen
	    cp $MODIFIED_CONFIG_FILE ${IMAGE_ROOTFS}/etc/xen/$CONFIG_FILE_BASE.cfg
	    rm -f $MODIFIED_CONFIG_FILE
	done
    fi
    # exit 1
}
ROOTFS_POSTPROCESS_COMMAND += "bundle_xen_guests;"

# Enable runqemu. eg: runqemu xen-image-minimal nographic slirp
WKS_FILE:x86-64 = "directdisk-xen.wks"
WKS_FILE_DEPENDS_DEFAULT:x86-64 = "syslinux-native"
WKS_FILE:qemux86-64 = "qemuboot-xen-x86-64.wks"
WKS_FILE_DEPENDS_DEFAULT:qemux86-64 = "syslinux-native"
QB_MEM ?= "-m 400"
QB_DEFAULT_KERNEL ?= "none"
QB_DEFAULT_FSTYPE ?= "wic"
QB_DEFAULT_FSTYPE:qemux86-64 = "wic"
QB_FSINFO ?= "wic:kernel-in-fs"
QB_SERIAL_OPT = "-serial mon:stdio"
# qemux86-64 machine does not include 'wic' in IMAGE_FSTYPES, which is needed
# to boot this image, so add it here:
IMAGE_FSTYPES:qemux86-64 += "wic"
do_image_wic[depends] += "xen:do_deploy"
# Networking: the qemuboot.bbclass default virtio network device works ok
# and so does the emulated e1000 -- choose according to the network device
# drivers that are present in your dom0 Linux kernel. To switch to e1000:
# QB_NETWORK_DEVICE = "-device e1000,netdev=net0,mac=@MAC@"


IMAGE_ROOTFS_SIZE = "8192"
# we always need extra space to install VMs, so add 2GB
IMAGE_ROOTFS_EXTRA_SPACE = "2000000"