diff options
-rw-r--r-- | classes/virt_networking.bbclass | 26 | ||||
-rw-r--r-- | recipes-extended/images/xen-guest-image-minimal.bb | 28 | ||||
-rw-r--r-- | recipes-extended/images/xen-image-minimal.bb | 181 | ||||
-rw-r--r-- | recipes-extended/xen/files/10-ether.network | 5 | ||||
-rw-r--r-- | recipes-extended/xen/files/10-xenbr0.netdev | 3 | ||||
-rw-r--r-- | recipes-extended/xen/files/10-xenbr0.network | 5 | ||||
-rw-r--r-- | recipes-extended/xen/xen-tools.inc | 10 |
7 files changed, 249 insertions, 9 deletions
diff --git a/classes/virt_networking.bbclass b/classes/virt_networking.bbclass new file mode 100644 index 00000000..e92e1de5 --- /dev/null +++ b/classes/virt_networking.bbclass | |||
@@ -0,0 +1,26 @@ | |||
1 | # Similarly to the cni_networking.bbclass this class should be | ||
2 | # inherted by recipes to produce a package that contains their | ||
3 | # desired networking configuration. | ||
4 | # | ||
5 | # Currently only systemd networking is supported, but this will | ||
6 | # be extended in the future | ||
7 | # | ||
8 | # By simply specifying the configuration / networking files, | ||
9 | # they will be package and then eventually installed to the | ||
10 | # correct target location. | ||
11 | # | ||
12 | PACKAGES:prepend = "${PN}-net-conf " | ||
13 | FILES:${PN}-net-conf = "${sysconfdir}/systemd/network/*" | ||
14 | |||
15 | do_install:append() { | ||
16 | if [ -z "${VIRT_NETWORKING_FILES}" ]; then | ||
17 | bbfatal "virt-networking was inherited, but no networking configuration was provided via VIRT_NETWORKING_FILES" | ||
18 | fi | ||
19 | |||
20 | # TODO: possibily make the systemd configuration conditional on the init manager | ||
21 | install -d "${D}/${sysconfdir}/systemd/network/" | ||
22 | for f in ${VIRT_NETWORKING_FILES}; do | ||
23 | conf_name="$(basename $f)" | ||
24 | install -D -m 0644 "$f" "${D}/${sysconfdir}/systemd/network/$conf_name" | ||
25 | done | ||
26 | } | ||
diff --git a/recipes-extended/images/xen-guest-image-minimal.bb b/recipes-extended/images/xen-guest-image-minimal.bb index fced7639..76f320e4 100644 --- a/recipes-extended/images/xen-guest-image-minimal.bb +++ b/recipes-extended/images/xen-guest-image-minimal.bb | |||
@@ -1,6 +1,7 @@ | |||
1 | DESCRIPTION = "A Xen guest image." | 1 | DESCRIPTION = "A Xen guest image." |
2 | 2 | ||
3 | inherit core-image features_check | 3 | inherit core-image features_check deploy |
4 | inherit kernel-artifact-names | ||
4 | 5 | ||
5 | IMAGE_INSTALL += " \ | 6 | IMAGE_INSTALL += " \ |
6 | packagegroup-core-boot \ | 7 | packagegroup-core-boot \ |
@@ -23,3 +24,28 @@ LICENSE = "MIT" | |||
23 | 24 | ||
24 | # Send console messages to xen console | 25 | # Send console messages to xen console |
25 | APPEND += "console=hvc0" | 26 | APPEND += "console=hvc0" |
27 | |||
28 | IMAGE_FSTYPES = "tar.bz2 ext4 ext4.qcow2" | ||
29 | |||
30 | XEN_GUEST_AUTO_BUNDLE ?= "" | ||
31 | |||
32 | # When a xen-guest-image-minimal is built with the | ||
33 | # XEN_GUEST_AUTO_BUNDLE varaible set to True, a configuration file for | ||
34 | # automatic guest bundling will be generated and the guest bundled | ||
35 | # automatically when a xen host image is built. | ||
36 | do_deploy() { | ||
37 | if [ -n "${XEN_GUEST_AUTO_BUNDLE}" ]; then | ||
38 | outname="xen-guest-bundle-${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}-${IMAGE_VERSION_SUFFIX}.cfg" | ||
39 | cat <<EOF >>${DEPLOYDIR}/$outname | ||
40 | name = "xen-guest" | ||
41 | memory = 512 | ||
42 | vcpus = 1 | ||
43 | disk = ['file:${IMAGE_LINK_NAME}.ext4,xvda,rw'] | ||
44 | vif = ['bridge=xenbr0'] | ||
45 | kernel = "${KERNEL_IMAGETYPE}" | ||
46 | extra = "root=/dev/xvda ro ip=dhcp" | ||
47 | EOF | ||
48 | fi | ||
49 | } | ||
50 | |||
51 | addtask deploy after do_compile | ||
diff --git a/recipes-extended/images/xen-image-minimal.bb b/recipes-extended/images/xen-image-minimal.bb index e6fa93ca..866212ed 100644 --- a/recipes-extended/images/xen-image-minimal.bb +++ b/recipes-extended/images/xen-image-minimal.bb | |||
@@ -1,9 +1,14 @@ | |||
1 | DESCRIPTION = "A minimal xen image" | 1 | DESCRIPTION = "A minimal xen image" |
2 | 2 | ||
3 | inherit features_check | ||
4 | |||
5 | REQUIRED_DISTRO_FEATURES ?= "xen systemd" | ||
6 | |||
3 | INITRD_IMAGE = "core-image-minimal-initramfs" | 7 | INITRD_IMAGE = "core-image-minimal-initramfs" |
4 | 8 | ||
5 | XEN_KERNEL_MODULES ?= "kernel-module-xen-blkback kernel-module-xen-gntalloc \ | 9 | XEN_KERNEL_MODULES ?= "kernel-module-xen-blkback kernel-module-xen-gntalloc \ |
6 | kernel-module-xen-gntdev kernel-module-xen-netback kernel-module-xen-wdt \ | 10 | kernel-module-xen-gntdev kernel-module-xen-netback kernel-module-xen-wdt \ |
11 | kernel-module-xt-comment kernel-module-xt-masquerade \ | ||
7 | ${@bb.utils.contains('MACHINE_FEATURES', 'pci', "${XEN_PCIBACK_MODULE}", '', d)} \ | 12 | ${@bb.utils.contains('MACHINE_FEATURES', 'pci', "${XEN_PCIBACK_MODULE}", '', d)} \ |
8 | ${@bb.utils.contains('MACHINE_FEATURES', 'acpi', '${XEN_ACPI_PROCESSOR_MODULE}', '', d)} \ | 13 | ${@bb.utils.contains('MACHINE_FEATURES', 'acpi', '${XEN_ACPI_PROCESSOR_MODULE}', '', d)} \ |
9 | " | 14 | " |
@@ -16,6 +21,7 @@ IMAGE_INSTALL += " \ | |||
16 | qemu \ | 21 | qemu \ |
17 | kernel-image \ | 22 | kernel-image \ |
18 | kernel-vmlinux \ | 23 | kernel-vmlinux \ |
24 | rsync \ | ||
19 | " | 25 | " |
20 | 26 | ||
21 | # The hypervisor may not be within the dom0 filesystem image but at least | 27 | # The hypervisor may not be within the dom0 filesystem image but at least |
@@ -44,14 +50,6 @@ QB_QEMU_CLASSES = "" | |||
44 | QB_QEMU_CLASSES:qemuall = "qemuboot-xen-defaults qemuboot-xen-dtb qemuboot-testimage-network" | 50 | QB_QEMU_CLASSES:qemuall = "qemuboot-xen-defaults qemuboot-xen-dtb qemuboot-testimage-network" |
45 | inherit ${QB_QEMU_CLASSES} | 51 | inherit ${QB_QEMU_CLASSES} |
46 | 52 | ||
47 | do_check_xen_state() { | ||
48 | if [ "${@bb.utils.contains('DISTRO_FEATURES', 'xen', ' yes', 'no', d)}" = "no" ]; then | ||
49 | die "DISTRO_FEATURES does not contain 'xen'" | ||
50 | fi | ||
51 | } | ||
52 | |||
53 | addtask check_xen_state before do_rootfs | ||
54 | |||
55 | # note: this may be unused, see the wic plugin | 53 | # note: this may be unused, see the wic plugin |
56 | syslinux_iso_populate:append() { | 54 | syslinux_iso_populate:append() { |
57 | install -m 0444 ${STAGING_DATADIR}/syslinux/libcom32.c32 ${ISODIR}${ISOLINUXDIR} | 55 | install -m 0444 ${STAGING_DATADIR}/syslinux/libcom32.c32 ${ISODIR}${ISOLINUXDIR} |
@@ -88,6 +86,168 @@ build_syslinux_cfg () { | |||
88 | echo " APPEND /xen.gz ${SYSLINUX_XEN_ARGS} --- /vmlinuz ${SYSLINUX_KERNEL_ARGS} --- /initrd" >> ${SYSLINUX_CFG} | 86 | echo " APPEND /xen.gz ${SYSLINUX_XEN_ARGS} --- /vmlinuz ${SYSLINUX_KERNEL_ARGS} --- /initrd" >> ${SYSLINUX_CFG} |
89 | } | 87 | } |
90 | 88 | ||
89 | # Function to parse the config file and get values for specific keys | ||
90 | get_config_value() { | ||
91 | config_file="$1" | ||
92 | key="$2" | ||
93 | line=$(grep -w "$key" $config_file) | ||
94 | value=$(echo "$line" | cut -d '=' -f 2-) | ||
95 | # Remove quotes, leading/trailing whitespace, and content after the first comma | ||
96 | echo "${value#*=}" | sed "s/'//g; s/^\s*|\s*$//g; s/\[//g;s/\"//g;s/^ *//g;" | cut -d ',' -f 1 | ||
97 | } | ||
98 | |||
99 | generate_guest_config() { | ||
100 | name=$1 | ||
101 | kernel=$2 | ||
102 | disk=$3 | ||
103 | outname=$name.cfg | ||
104 | |||
105 | cat <<EOF >${DEPLOY_DIR_IMAGE}/$outname | ||
106 | name = "$name" | ||
107 | memory = 512 | ||
108 | vcpus = 1 | ||
109 | disk = ['file:$disk,xvda,rw'] | ||
110 | vif = ['bridge=xenbr0'] | ||
111 | kernel = "$kernel" | ||
112 | extra = "root=/dev/xvda ro ip=dhcp" | ||
113 | EOF | ||
114 | } | ||
115 | |||
116 | # Guests can be bundled automatically through the following mechanisms: | ||
117 | # | ||
118 | # - via the variable XEN_BUNDLED_GUESTS | ||
119 | # - via a xen configuration file in the deploy directory of the format | ||
120 | # xen-guest-bundle-*.cfg | ||
121 | # | ||
122 | # The guests can be built via OE, or be 3rd party guests. They just | ||
123 | # must be in the deploy directory so they can be copied into the rootfs | ||
124 | # of the xen host image | ||
125 | # | ||
126 | # Type 1) XEN_BUNDLED_GUESTS | ||
127 | # | ||
128 | # If XEN_BUNDLED_GUESTS is used, it is simply a colon separated list of | ||
129 | # rootfs:kernels. Normal variable rules apply, so it can be set in a | ||
130 | # local.conf, or in a bbappend to the image recipe. | ||
131 | # | ||
132 | # An example would be: | ||
133 | # | ||
134 | # XEN_BUNDLED_GUESTS = "xen-guest-image-minimal-qemuarm64.rootfs.ext4:Image" | ||
135 | # | ||
136 | # These point at symlinks created in the image deploy directory, or they | ||
137 | # can be specific images/kernels without the symlink. | ||
138 | # | ||
139 | # Type 2) A Xen guest configuration file | ||
140 | # | ||
141 | # If xen guest configuration files are found in the deploy directories | ||
142 | # the kernel and disk information contained within them will be processed | ||
143 | # and modified for the xen host. The kernel and guest image will be | ||
144 | # copied to the appropriate location, and the config made to match. | ||
145 | # | ||
146 | # These files following the naming convention: xen-guest-bundle*.cfg | ||
147 | # | ||
148 | # Guests of type #1 generate a configuration file that is picked up as | ||
149 | # type #2. | ||
150 | # | ||
151 | # An example config file follows: | ||
152 | # | ||
153 | ## name = "xen-guest" | ||
154 | ## memory = 512 | ||
155 | ## vcpus = 1 | ||
156 | ## disk = ['file:xen-guest-image-minimal-qemuarm64.rootfs.ext4,xvda,rw'] | ||
157 | ## vif = ['bridge=xenbr0'] | ||
158 | ## kernel = "Image" | ||
159 | ## extra = "root=/dev/xvda ro console=hvc0 ip=dhcp" | ||
160 | # | ||
161 | # It should also be noted that when a xen-guest-image-minimal is built | ||
162 | # with the XEN_GUEST_AUTO_BUNDLE varaible set to True, a configuration | ||
163 | # file for type #2 will be generated and the guest bundled automatically | ||
164 | # when the host image is built. | ||
165 | # | ||
166 | # kernel and rootfs are copied to the target in /var/lib/xen/images/ | ||
167 | # | ||
168 | # configuration files are copied to: /etc/xen | ||
169 | # | ||
170 | # Guests can be launched after boot with: xl create -c /etc/xen/<config file> | ||
171 | # | ||
172 | bundle_xen_guests() { | ||
173 | set -e | ||
174 | |||
175 | if [ -n "${XEN_BUNDLED_GUESTS}" ]; then | ||
176 | echo "Processing Xen bundled guests variable: ${XEN_BUNDLED_GUESTS}" | ||
177 | # these are a colon separated list of rootfs:kernel | ||
178 | count=1 | ||
179 | for g in ${XEN_BUNDLED_GUESTS}; do | ||
180 | echo "Guest line: $g" | ||
181 | rootfs=$(echo "$g" | cut -d":" -f1) | ||
182 | kernel=$(echo "$g" | cut -d":" -f2) | ||
183 | name="xen-guest-bundle-$count" | ||
184 | |||
185 | if ! [ -e ${DEPLOY_DIR_IMAGE}/$rootfs ]; then | ||
186 | echo "rootfs '${DEPLOY_DIR_IMAGE}/$rootfs' not found, skipping ...." | ||
187 | continue | ||
188 | fi | ||
189 | if ! [ -e ${DEPLOY_DIR_IMAGE}/$kernel ]; then | ||
190 | echo "kernel '${DEPLOY_DIR_IMAGE}/$kernel' not found, skipping ...." | ||
191 | continue | ||
192 | fi | ||
193 | |||
194 | generate_guest_config $name $kernel $rootfs | ||
195 | |||
196 | count=$(expr $count + 1) | ||
197 | done | ||
198 | fi | ||
199 | |||
200 | echo ls ${DEPLOY_DIR_IMAGE}/xen-guest-bundle*.cfg | ||
201 | ls ${DEPLOY_DIR_IMAGE}/xen-guest-bundle*.cfg >/dev/null 2>/dev/null | ||
202 | if [ $? -eq 0 ]; then | ||
203 | for guest_cfg in $(ls ${DEPLOY_DIR_IMAGE}/xen-guest-bundle*.cfg); do | ||
204 | echo "Bundling guest: $guest_cfg" | ||
205 | |||
206 | CONFIG_FILE_BASE=$(basename $guest_cfg .cfg) | ||
207 | CONFIG_FILE="${DEPLOY_DIR_IMAGE}/$CONFIG_FILE_BASE.cfg" | ||
208 | DEST_DIR="${IMAGE_ROOTFS}/var/lib/xen/images" | ||
209 | MODIFIED_CONFIG_FILE="${DEPLOY_DIR_IMAGE}/$CONFIG_FILE_BASE-modified.cfg" | ||
210 | |||
211 | # Extract values from the configuration file | ||
212 | DISK_ORIG=$(get_config_value $CONFIG_FILE "disk" | sed 's/file://g') | ||
213 | DISK=$(readlink -f ${DEPLOY_DIR_IMAGE}/$DISK_ORIG) | ||
214 | DISK_NAME=$(basename $DISK) | ||
215 | KERNEL_ORIG=$(get_config_value $CONFIG_FILE "kernel") | ||
216 | KERNEL=$(readlink -f ${DEPLOY_DIR_IMAGE}/$KERNEL_ORIG) | ||
217 | KERNEL_NAME=$(basename $KERNEL) | ||
218 | |||
219 | if [ -z "$DISK" ]; then | ||
220 | echo "rootfs '$DISK' not found, skipping ...." | ||
221 | continue | ||
222 | fi | ||
223 | if [ -z "$KERNEL" ]; then | ||
224 | echo "kernel '$KERNEL' not found, skipping ...." | ||
225 | continue | ||
226 | fi | ||
227 | |||
228 | mkdir -p "$DEST_DIR" | ||
229 | # Copy the disk and kernel to the destination directory | ||
230 | echo "Copying disk and kernel files..." | ||
231 | echo cp "$DISK" "$DEST_DIR" | ||
232 | echo cp "$KERNEL" "$DEST_DIR" | ||
233 | cp "$DISK" "$DEST_DIR" | ||
234 | cp "$KERNEL" "$DEST_DIR" | ||
235 | |||
236 | # Create a modified config file with updated paths | ||
237 | sed -E \ | ||
238 | -e "s#^(disk = \[)[^,]+#\1'file:/var/lib/xen/images/$DISK_NAME#" \ | ||
239 | -e "s#^(kernel = )\"[^\"]+\"#\1\"/var/lib/xen/images/$KERNEL_NAME\"#" \ | ||
240 | "$CONFIG_FILE" > "$MODIFIED_CONFIG_FILE" | ||
241 | |||
242 | mkdir -p ${IMAGE_ROOTFS}/etc/xen | ||
243 | cp $MODIFIED_CONFIG_FILE ${IMAGE_ROOTFS}/etc/xen/$CONFIG_FILE_BASE.cfg | ||
244 | rm -f $MODIFIED_CONFIG_FILE | ||
245 | done | ||
246 | fi | ||
247 | # exit 1 | ||
248 | } | ||
249 | ROOTFS_POSTPROCESS_COMMAND += "bundle_xen_guests;" | ||
250 | |||
91 | # Enable runqemu. eg: runqemu xen-image-minimal nographic slirp | 251 | # Enable runqemu. eg: runqemu xen-image-minimal nographic slirp |
92 | WKS_FILE:x86-64 = "directdisk-xen.wks" | 252 | WKS_FILE:x86-64 = "directdisk-xen.wks" |
93 | WKS_FILE_DEPENDS_DEFAULT:x86-64 = "syslinux-native" | 253 | WKS_FILE_DEPENDS_DEFAULT:x86-64 = "syslinux-native" |
@@ -107,3 +267,8 @@ do_image_wic[depends] += "xen:do_deploy" | |||
107 | # and so does the emulated e1000 -- choose according to the network device | 267 | # and so does the emulated e1000 -- choose according to the network device |
108 | # drivers that are present in your dom0 Linux kernel. To switch to e1000: | 268 | # drivers that are present in your dom0 Linux kernel. To switch to e1000: |
109 | # QB_NETWORK_DEVICE = "-device e1000,netdev=net0,mac=@MAC@" | 269 | # QB_NETWORK_DEVICE = "-device e1000,netdev=net0,mac=@MAC@" |
270 | |||
271 | |||
272 | IMAGE_ROOTFS_SIZE = "8192" | ||
273 | # we always need extra space to install VMs, so add 2GB | ||
274 | IMAGE_ROOTFS_EXTRA_SPACE = "2000000" | ||
diff --git a/recipes-extended/xen/files/10-ether.network b/recipes-extended/xen/files/10-ether.network new file mode 100644 index 00000000..8d27ca92 --- /dev/null +++ b/recipes-extended/xen/files/10-ether.network | |||
@@ -0,0 +1,5 @@ | |||
1 | [Match] | ||
2 | Type=ether | ||
3 | |||
4 | [Network] | ||
5 | Bridge=xenbr0 | ||
diff --git a/recipes-extended/xen/files/10-xenbr0.netdev b/recipes-extended/xen/files/10-xenbr0.netdev new file mode 100644 index 00000000..ec45879f --- /dev/null +++ b/recipes-extended/xen/files/10-xenbr0.netdev | |||
@@ -0,0 +1,3 @@ | |||
1 | [NetDev] | ||
2 | Name=xenbr0 | ||
3 | Kind=bridge | ||
diff --git a/recipes-extended/xen/files/10-xenbr0.network b/recipes-extended/xen/files/10-xenbr0.network new file mode 100644 index 00000000..1e10c3eb --- /dev/null +++ b/recipes-extended/xen/files/10-xenbr0.network | |||
@@ -0,0 +1,5 @@ | |||
1 | [Match] | ||
2 | Name=xenbr0 | ||
3 | |||
4 | [Network] | ||
5 | DHCP=yes | ||
diff --git a/recipes-extended/xen/xen-tools.inc b/recipes-extended/xen/xen-tools.inc index 35dbb493..fba10b04 100644 --- a/recipes-extended/xen/xen-tools.inc +++ b/recipes-extended/xen/xen-tools.inc | |||
@@ -6,6 +6,15 @@ COMPATIBLE_HOST = 'i686-.*-linux|(x86_64.*).*-linux|aarch64.*-linux|arm-.*-linux | |||
6 | inherit setuptools3 update-rc.d systemd deploy | 6 | inherit setuptools3 update-rc.d systemd deploy |
7 | require xen-blktap.inc | 7 | require xen-blktap.inc |
8 | 8 | ||
9 | SRC_URI += "file://10-ether.network \ | ||
10 | file://10-xenbr0.netdev \ | ||
11 | file://10-xenbr0.network" | ||
12 | |||
13 | VIRT_NETWORKING_FILES = "${UNPACKDIR}/10-ether.network \ | ||
14 | ${UNPACKDIR}/10-xenbr0.netdev \ | ||
15 | ${UNPACKDIR}/10-xenbr0.network" | ||
16 | inherit virt_networking | ||
17 | |||
9 | QEMU_SYSTEM ?= "qemu-system-i386" | 18 | QEMU_SYSTEM ?= "qemu-system-i386" |
10 | QEMU_SYSTEM_RDEPENDS ?= "${QEMU_SYSTEM} qemu-firmware" | 19 | QEMU_SYSTEM_RDEPENDS ?= "${QEMU_SYSTEM} qemu-firmware" |
11 | 20 | ||
@@ -30,6 +39,7 @@ RDEPENDS:${PN} = "\ | |||
30 | virtual-xenstored \ | 39 | virtual-xenstored \ |
31 | ${PN}-xl \ | 40 | ${PN}-xl \ |
32 | ${QEMU_SYSTEM_RDEPENDS} \ | 41 | ${QEMU_SYSTEM_RDEPENDS} \ |
42 | ${PN}-net-conf \ | ||
33 | " | 43 | " |
34 | 44 | ||
35 | RDEPENDS:${PN}-dev = "" | 45 | RDEPENDS:${PN}-dev = "" |