summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlibexec/container/build7
-rwxr-xr-xshare/build-scripts/debconf170
-rwxr-xr-xshare/build-scripts/debconf.d/0003-debconf209
-rw-r--r--share/build-scripts/debconf.d/0003-debconf.templates82
-rw-r--r--share/config/container.conf.in14
-rw-r--r--share/doc/vms.txt16
6 files changed, 491 insertions, 7 deletions
diff --git a/libexec/container/build b/libexec/container/build
index 2c29730..efb42f3 100755
--- a/libexec/container/build
+++ b/libexec/container/build
@@ -32,7 +32,7 @@ CONFIG_TEMPLATE="/usr/share/${SOFTWARE}/config/container.conf.in"
Parameters ()
{
- GETOPT_LONGOPTIONS="name:,cnt.auto:,cnt.container-server:,cnt.overlay:,cnt.overlay-options:,cnt.start:,bind:,bind-ro:,capability:,drop-capability:,script:,verbose,"
+ GETOPT_LONGOPTIONS="name:,cnt.auto:,cnt.container-server:,cnt.overlay:,cnt.overlay-options:,cnt.start:,bind:,bind-ro:,capability:,drop-capability:,script:,boot-method:,verbose,"
GETOPT_OPTIONS="n:,b:,c:,d:,s:,v,"
PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${COMMAND} --options ${GETOPT_OPTIONS} --shell sh -- ${@})"
@@ -108,6 +108,11 @@ Parameters ()
shift 1
;;
+ --boot-method)
+ BOOT_METHOD="${2}"
+ shift 2
+ ;;
+
--)
shift 1
break
diff --git a/share/build-scripts/debconf b/share/build-scripts/debconf
index 900242d..8307695 100755
--- a/share/build-scripts/debconf
+++ b/share/build-scripts/debconf
@@ -31,11 +31,12 @@ CACHE="/var/cache/${PROGRAM}/build-$(basename ${SCRIPT})"
CONFIG="/etc/${SOFTWARE}/config"
HOOKS="/etc/${SOFTWARE}/hooks"
MACHINES="/var/lib/machines"
+VMS="/srv/container/vms"
Parameters ()
{
- GETOPT_LONGOPTIONS="bind:,bind-ro:,script:,name:,preseed-file:"
- GETOPT_OPTIONS="b:,s:,n:,p:"
+ GETOPT_LONGOPTIONS="bind:,bind-ro:,boot-method:,script:,name:,preseed-file:,vm"
+ GETOPT_OPTIONS="b:,s:,n:,p:,v:"
PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${SCRIPT} --options ${GETOPT_OPTIONS} --shell sh -- ${@})"
@@ -60,6 +61,11 @@ Parameters ()
shift 2
;;
+ --boot-method)
+ BOOT_METHOD="${2}"
+ shift 2
+ ;;
+
--cnt.auto)
# ignore
shift 2
@@ -85,6 +91,11 @@ Parameters ()
shift 2
;;
+ --vm)
+ VM="TRUE"
+ shift 1
+ ;;
+
--)
shift 1
break
@@ -100,7 +111,7 @@ Parameters ()
Usage ()
{
- echo "Usage: container build -n|--name NAME -s|--script ${SCRIPT} -- [-p|--preseed-file FILE]" >&2
+ echo "Usage: container build -n|--name NAME -s|--script ${SCRIPT} [--boot-method systemd-nswawn|qemu] -- [-p|--preseed-file FILE]" >&2
exit 1
}
@@ -251,9 +262,20 @@ Umount ()
fi
# Unmounting pseudo-filesystems
+ # FIXME this should not be necessary
+ umount -f "${DIRECTORY}/dev" > /dev/null 2>&1 || true
umount -f "${DIRECTORY}/dev/pts" > /dev/null 2>&1 || true
umount -f "${DIRECTORY}/proc" > /dev/null 2>&1 || true
umount -f "${DIRECTORY}/sys" > /dev/null 2>&1 || true
+
+ # Unmounting disk images
+ if [ "${BOOT_METHOD}" = "qemu" ]
+ then
+ umount -f "${DIRECTORY}/boot/efi" > /dev/null 2>&1 || true
+ umount -f "${DIRECTORY}" > /dev/null 2>&1 || true
+ rmdir "${MACHINES}/${NAME}"
+ kpartx -d "${VMS}/${NAME}/root.img"
+ fi
}
Chroot ()
@@ -368,7 +390,8 @@ Bootstrap ()
DIRECTORY="${1}"
EXCLUDE="ifupdown"
- INCLUDE="dbus"
+ #FIXME amd64 hardcoded
+ INCLUDE="dbus,linux-image-amd64,grub-efi-amd64"
# apt repositories
INCLUDE="${INCLUDE},gnupg"
@@ -1101,6 +1124,60 @@ EOF
done
}
+Configure_vm ()
+{
+ DIRECTORY="${1}"
+
+ # FIXME duplicate definition
+ EFI_PARTITION="p1"
+ SYSTEM_PARTITION="p2"
+ EFI_UUID="$(lsblk --output UUID --noheadings /dev/mapper/loop0${EFI_PARTITION})"
+ ROOT_UUID="$(lsblk --output UUID --noheadings /dev/mapper/loop0${SYSTEM_PARTITION})"
+ echo "UUID=${ROOT_UUID} / ext4 discard,noatime,errors=remount-ro 0 1" >> ${DIRECTORY}/etc/fstab
+ echo "UUID=${EFI_UUID} /boot/efi vfat umask=0077 0 1" >> ${DIRECTORY}/etc/fstab
+
+ mkdir -p ${DIRECTORY}/boot/efi/EFI/progress-linux
+ cp ${DIRECTORY}/usr/lib/grub/x86_64-efi/monolithic/grubx64.efi ${DIRECTORY}/boot/efi/EFI/progress-linux/
+
+cat > ${DIRECTORY}/boot/efi/EFI/progress-linux/grub.cfg << EOF
+search.fs_uuid ${ROOT_UUID} root
+set prefix=(\$root)'/boot/grub'
+configfile \$prefix/grub.cfg
+EOF
+
+cat >> ${DIRECTORY}/etc/initramfs-tools/modules << EOF
+
+# enable virtio
+virtio_pci
+virtio_blk
+virtio_net
+EOF
+
+ Chroot ${DIRECTORY} update-initramfs -u
+
+ mount -o bind /dev ${DIRECTORY}/dev
+ Chroot ${DIRECTORY} update-grub
+
+ # FIXME workaround for grub not being installed as EFI/boot/bootx86.efi
+ mkdir "${DIRECTORY}/boot/efi/EFI/boot"
+ echo 'fs0:\EFI\progress-linux\grubx64.efi' > "${DIRECTORY}/boot/efi/EFI/boot/startup.nsh"
+
+ sed -i \
+ -e "s|@BOOT_METHOD@|${BOOT_METHOD}|g" \
+ -e "s|@CPU@|${CPU}|g" \
+ -e "s|@MEMORY@|${MEMORY}|g" \
+ -e "s|@DISPLAY@|${DISPLAY}|g" \
+ -e "s|@SERIAL@|${SERIAL}|g" \
+ -e "s|@MONITOR@|${MONITOR}|g" \
+ -e "s|@FIRMWARE@|${FIRMWARE}|g" \
+ -e "s|@DRIVE@|${DRIVE}|g" \
+ -e "s|@NETDEV@|${NETDEV}|g" \
+ -e "s|@QEMU_RAW@|${QEMU_RAW}|g" \
+ "${CONFIG}/${NAME}.conf"
+
+}
+
+
Commands ()
{
DIRECTORY="${1}"
@@ -1117,6 +1194,7 @@ Commands ()
-e "s|^bind=.*|bind=${BIND}|g" \
-e "s|^bind-ro=.*|bind-ro=${BIND_RO}|g" \
-e "s|^network-veth-extra=.*|network-veth-extra=${HOST_INTERFACE_NAME}:eno1|g" \
+ -e "s|@PRIMARY_TAP@|${HOST_INTERFACE_NAME}|g" \
"${CONFIG}/${NAME}.conf"
if [ "${NETWORK_NUMBER}" -ge 2 ]
@@ -1179,6 +1257,67 @@ Commands ()
esac
}
+Create_vm_disk ()
+{
+ mkdir -p "${VMS}/${NAME}"
+
+ # FIXME drive-image file size as arg or preseed
+ DRIVE_SIZE=12000
+
+ # FIXME image name
+ dd if=/dev/zero of="${VMS}/${NAME}/root.img" bs=1024k count=0 seek="${DRIVE_SIZE}"
+ parted "${VMS}/${NAME}/root.img" mklabel gpt
+
+
+ # FIXME only for root image
+ case "${FIRMWARE}" in
+ legacy)
+ # FIXME number partitions and size scrip and everything
+ parted -a optimal "${VMS}/${NAME}/root.img" mkpart BIOS-BOOT 1MB 2MB
+ parted "${VMS}/${NAME}/root.img" set 1 bios_grub on
+ parted -a optimal "${VMS}/${NAME}/root.img" mkpart SYSTEM 2MB 100%
+ SYSTEM_PARTITION="p2"
+ ;;
+
+ efi)
+ parted -a optimal "${VMS}/${NAME}/root.img" mkpart EFI fat32 1M 1000M
+ parted "${VMS}/${NAME}/root.img" set 1 esp on
+ parted -a optimal "${VMS}/${NAME}/root.img" mkpart SYSTEM 1000MB 100%
+ EFI_PARTITION="p1"
+ SYSTEM_PARTITION="p2"
+
+ # efi bios
+ cp /usr/share/qemu/OVMF.fd "${VMS}/${NAME}/firmware.fd"
+ ;;
+
+ *)
+ echo "Error, unrecognized firware." >&2
+ exit 1
+ esac
+
+ kpartx -av "${VMS}/${NAME}/root.img"
+ # FIXME loop number hardcoded
+ mkfs.ext4 "/dev/mapper/loop0${SYSTEM_PARTITION}"
+
+ if [ ! -z "${EFI_PARTITION}" ]
+ then
+ mkfs.vfat -F 32 "/dev/mapper/loop0${EFI_PARTITION}"
+ fi
+
+ # FIXME swap, more discs
+}
+
+Mount_vm_disk ()
+{
+ # FIXME probably not necessary
+ mkdir -p "${MACHINES}/${NAME}"
+
+ # FIXME partition number hardcoded
+ mount "/dev/mapper/loop0${SYSTEM_PARTITION}" "${MACHINES}/${NAME}"
+ mkdir -p "${MACHINES}/${NAME}/boot/efi"
+ mount "/dev/mapper/loop0${EFI_PARTITION}" "${MACHINES}/${NAME}/boot/efi"
+}
+
# Trap function
trap 'Umount' EXIT HUP INT QUIT TERM
@@ -1218,6 +1357,13 @@ else
INSTALLER="image"
fi
+case "${BOOT_METHOD}" in
+ qemu)
+ Create_vm_disk
+ Mount_vm_disk
+ ;;
+esac
+
case "${INSTALLER}" in
bootstrap)
## Dependencies
@@ -1246,8 +1392,11 @@ case "${INSTALLER}" in
Cleanup_system "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}"
## Specific parts
- mkdir -p "${MACHINES}"
- cp -a "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}" "${MACHINES}/${NAME}"
+
+ # FIXME is there a better way to do this?
+ mkdir -p "${MACHINES}/${NAME}"
+ cp -a "${CACHE}/${DISTRIBUTION}_${ARCHITECTURE}/"* "${MACHINES}/${NAME}/"
+
;;
image)
@@ -1300,6 +1449,15 @@ Mount
Configure_system "${MACHINES}/${NAME}"
Configure_network "${MACHINES}/${NAME}"
Configure_systemd_networkd "${MACHINES}/${NAME}"
+
+case "${BOOT_METHOD}" in
+ qemu)
+ echo DEBUG: Configure_vm start
+ Configure_vm "${MACHINES}/${NAME}"
+ echo DEBUG: Configure_vm end
+ ;;
+esac
+
Cleanup_system "${MACHINES}/${NAME}"
Commands "${MACHINES}/${NAME}"
diff --git a/share/build-scripts/debconf.d/0003-debconf b/share/build-scripts/debconf.d/0003-debconf
index e12e25e..76da4c2 100755
--- a/share/build-scripts/debconf.d/0003-debconf
+++ b/share/build-scripts/debconf.d/0003-debconf
@@ -1340,6 +1340,195 @@ Internal_options ()
echo "CNT_OVERLAY_OPTIONS=\"${CNT_OVERLAY_OPTIONS}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
}
+Cpu ()
+{
+ db_get container/cpu
+ CPU="${RET}" # select
+
+ if [ -z "${CPU}" ]
+ then
+ CPU="${RET}" # string (w/o empty)
+
+ case "${CPU}" in
+ debconf)
+ CPU="host"
+ ;;
+ esac
+ fi
+
+ echo "CPU=\"${CPU}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export CPU
+}
+
+Memory ()
+{
+ db_get container/memory
+ MEMORY="${RET}" # select
+
+ if [ -z "${MEMORY}" ]
+ then
+ MEMORY="${RET}" # string (w/o empty)
+
+ case "${MEMORY}" in
+ debconf)
+ MEMORY="2G"
+ ;;
+ esac
+ fi
+
+ echo "MEMORY=\"${MEMORY}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export MEMORY
+}
+
+Display ()
+{
+ db_get container/display
+ DISPLAY="${RET}" # select
+
+ if [ -z "${DISPLAY}" ]
+ then
+ DISPLAY="${RET}" # string (w/o empty)
+
+ case "${DISPLAY}" in
+ debconf)
+ DISPLAY="2G"
+ ;;
+ esac
+ fi
+
+ echo "DISPLAY=\"${DISPLAY}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export DISPLAY
+}
+
+Serial ()
+{
+ db_get container/serial
+ SERIAL="${RET}" # select
+
+ if [ -z "${SERIAL}" ]
+ then
+ SERIAL="${RET}" # string (w/o empty)
+
+ case "${SERIAL}" in
+ debconf)
+ SERIAL="host"
+ ;;
+ esac
+ fi
+
+ echo "SERIAL=\"${SERIAL}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export SERIAL
+}
+
+Monitor ()
+{
+ db_get container/monitor
+ MONITOR="${RET}" # select
+
+ if [ -z "${MONITOR}" ]
+ then
+ MONITOR="${RET}" # string (w/o empty)
+
+ case "${MONITOR}" in
+ debconf)
+ MONITOR="host"
+ ;;
+ esac
+ fi
+
+ echo "MONITOR=\"${MONITOR}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export MONITOR
+}
+
+Firmware ()
+{
+ db_get container/firmware
+ FIRMWARE="${RET}" # select
+
+ if [ -z "${FIRMWARE}" ]
+ then
+ FIRMWARE="${RET}" # string (w/o empty)
+
+ case "${FIRMWARE}" in
+ debconf)
+ FIRMWARE="host"
+ ;;
+ esac
+ fi
+
+ echo "FIRMWARE=\"${FIRMWARE}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export FIRMWARE
+}
+
+Drive ()
+{
+ db_get container/drive
+ DRIVE="${RET}" # select
+
+ if [ -z "${DRIVE}" ]
+ then
+ DRIVE="${RET}" # string (w/o empty)
+
+ case "${DRIVE}" in
+ debconf)
+ DRIVE="host"
+ ;;
+ esac
+ fi
+
+ echo "DRIVE=\"${DRIVE}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export DRIVE
+}
+
+Netdev ()
+{
+ db_get container/netdev
+ NETDEV="${RET}" # string (w/ empty)
+
+ echo "NETDEV=\"${NETDEV}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export NETDEV
+}
+
+Qemu_raw ()
+{
+ db_get container/qemu-raw
+ QEMU_RAW="${RET}" # select
+
+ if [ -z "${QEMU_RAW}" ]
+ then
+ QEMU_RAW="${RET}" # string (w/o empty)
+
+ case "${QEMU_RAW}" in
+ debconf)
+ QEMU_RAW="host"
+ ;;
+ esac
+ fi
+
+ echo "QEMU_RAW=\"${QEMU_RAW}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export QEMU_RAW
+}
+
+Boot_method ()
+{
+ db_get container/boot-method
+ BOOT_METHOD="${RET}" # select
+
+ if [ -z "${BOOT_METHOD}" ]
+ then
+ BOOT_METHOD="${RET}" # string (w/o empty)
+
+ case "${BOOT_METHOD}" in
+ debconf)
+ BOOT_METHOD="systemd-nspawn"
+ ;;
+ esac
+ fi
+
+ echo "BOOT_METHOD=\"${BOOT_METHOD}\"" >> "${DEBCONF_TMPDIR}/debconf.default"
+ export BOOT_METHOD
+}
+
Mode
Images
@@ -1368,4 +1557,24 @@ Root_password
Internal_options
+Cpu
+
+Memory
+
+Display
+
+Serial
+
+Monitor
+
+Firmware
+
+Drive
+
+Netdev
+
+Qemu_raw
+
+Boot_method
+
db_stop
diff --git a/share/build-scripts/debconf.d/0003-debconf.templates b/share/build-scripts/debconf.d/0003-debconf.templates
index 551033a..5d83df3 100644
--- a/share/build-scripts/debconf.d/0003-debconf.templates
+++ b/share/build-scripts/debconf.d/0003-debconf.templates
@@ -274,3 +274,85 @@ Description: Nameserver Resolver Options?
See resolv.conf(5) for more information about the 'options' option.
.
This defaults to empty.
+
+Template: container/cpu
+Type: string
+Default:
+Description: Cpu
+ VM CPU should be emulated.
+ .
+ Use 'host' for kvm.
+ .
+ This defaults to empty.
+
+Template: container/memory
+Type: string
+Default:
+Description: Memory
+ Memory options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/display
+Type: string
+Default:
+Description: Display
+ Display options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/serial
+Type: string
+Default:
+Description: Serial
+ Serial options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/monitor
+Type: string
+Default:
+Description: Monitor
+ Monitor options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/firmware
+Type: string
+Default:
+Description: Firmware
+ Firmware options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/drive
+Type: string
+Default:
+Description: Drive
+ Drive options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/netdev
+Type: string
+Default:
+Description: Netdev
+ Netdev options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/qemu-raw
+Type: string
+Default:
+Description: Qemu-raw
+ Raw options for the VM.
+ .
+ This defaults to empty.
+
+Template: container/boot-method
+Type: string
+Default:
+Description: Boot-method
+ Either 'efi' or 'legacy'.
+ .
+ This defaults to empty.
diff --git a/share/config/container.conf.in b/share/config/container.conf.in
index d3f9a48..9a0c9b2 100644
--- a/share/config/container.conf.in
+++ b/share/config/container.conf.in
@@ -10,6 +10,7 @@ cnt.start=@CNT_START@
bind=@BIND@
bind-ro=@BIND_RO@
boot=@BOOT@
+boot-method=@BOOT_METHOD@
capability=@CAPABILITY@
directory=@DIRECTORY@
drop-capability=@DROP_CAPABILITY@
@@ -28,3 +29,16 @@ CPUQuota=
CPUShares=
MemoryLimit=
TasksMax=
+
+[vm]
+vm.memory=@MEMORY@
+vm.cpu=@CPU@
+vm.display=@DISPLAY@
+vm.serial=@SERIAL@
+vm.mon=@MONITOR@
+vm.firmware=@FIRMWARE@
+
+vm.drive=@DRIVE@
+vm.netdev=@NETDEV@
+
+vm.raw=@QEMU_RAW@
diff --git a/share/doc/vms.txt b/share/doc/vms.txt
new file mode 100644
index 0000000..453ce23
--- /dev/null
+++ b/share/doc/vms.txt
@@ -0,0 +1,16 @@
+Manage Virtual Machines (VMs)
+=============================
+
+Status:
+
+- only debconf is supported
+
+HOWTO:
+
+to generate a vm image, provide the --vm option:
+
+ cnt build -n test --vm
+
+dependencies:
+
+ apt install qemu-system ovmf