#!/bin/bash ORIGINAL_ARGS=("$@") # Includes . $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; } # Configurable stuff MOUNTPOINT_ROOTDIR=/var/lib/libvirt/mountpoints MIRROR=http://deb.debian.org/debian # Other globals MODROOT=$(cd $(dirname $(readlink -f $0))/.. && pwd) main() { local MY_ARGS local PROGNAME # Defaults for options REMOTE_HOST= MEM_SIZE=1 DISK_TUPLES=() NIC_TUPLES=() CNT_NAME= CPU_COUNT=1 RELEASE= UID_GID_OFFSET= FLUSH_CACHE_FLAG=false UNDEFINE_FLAG=false # Process options special_opts_handler() { case $1 in --name=*) CNT_NAME=${1#*=} ;; --os=*) miniade_warning "'--os=' has been replaced by '--release='" RELEASE=${1#*=} ;; --release=*) RELEASE=${1#*=} ;; --remote=*) REMOTE_HOST=${1#*=} ;; --mem=*) MEM_SIZE=${1#*=} ;; --nic=*) NIC_TUPLES=( "${NIC_TUPLES[@]}" ${1#*=} ) ;; --cpus=*) CPU_COUNT=${1#*=} ;; --disk=*) DISK_TUPLES=( "${DISK_TUPLES[@]}" ${1#*=} ) ;; --offset=*) UID_GID_OFFSET=${1#*=} ;; --flush-cache|-F) FLUSH_CACHE_FLAG=true ;; --undefine) UNDEFINE_FLAG=true ;; *) return 1 ;; esac } miniade_process_options --help-handler=help --special-opts-handler=special_opts_handler MY_ARGS "$@" && set -- "${MY_ARGS[@]}" # Process arguments [ $# = 0 ] || miniade_bad_usage # Sanity checks and derivations miniade_get_progname PROGNAME CACHE_ROOTDIR=/var/local/$PROGNAME HISTFILE=$HOME/.${PROGNAME}_history for VAR in REMOTE_HOST; do eval "[ \"X\$$VAR\" != Xunset ] || $VAR=" done for VAR in CNT_NAME UID_GID_OFFSET RELEASE; do eval "[ \"X\$$VAR\" != X ]" || miniade_bad_usage done export LIBVIRT_DEFAULT_URI=lxc:///system [ ${#DISK_TUPLES[*]} -ge 1 ] || miniade_bad_usage [ "X$REMOTE_HOST" = X ] || miniade_check_ssh_ok $REMOTE_HOST || miniade_error "$REMOTE_HOST: no unfettered ssh access" if $UNDEFINE_FLAG; then miniade_debug 2 "main: skipping already-defined checks!" elif ! virsh dominfo $CNT_NAME > /dev/null 2>&1; then miniade_error "$CNT_NAME: container defined locally already (hint: use '--undefine' or run 'LIBVIRT_DEFAULT_URI=lxc:///system virsh undefine $CNT_NAME'?)" elif [ -d /var/lib/lxc/$CNT_NAME ]; then miniade_error "$CNT_NAME: container defined locally already (hint: use '--undefine' or run 'rm -fr /var/lib/lxc/$CNT_NAME'?)" elif [ "X$REMOTE_HOST" = X ]; then : elif { ! ssh -n $REMOTE_HOST "export LIBVIRT_DEFAULT_URI=$LIBVIRT_DEFAULT_URI; virsh dominfo $CNT_NAME" > /dev/null 2>&1; }; then miniade_error "$CNT_NAME: container defined remotely already (hint: use '--undefine' or run 'ssh -n $REMOTE_HOST \"LIBVIRT_DEFAULT_URI=$LIBVIRT_DEFAULT_URI virsh undefine $CNT_NAME\"'?)" elif ! ssh -n $REMOTE_HOST "[ ! -d /var/lib/lxc/$CNT_NAME ]"; then miniade_error "$CNT_NAME: container defined remotely already (hint: use '--undefine' run 'ssh -n $REMOTE_HOST \"rm -fr /var/lib/lxc/$CNT_NAME\"'?)" fi # Disk checks miniade_debug 10 "main: disk checks ..." for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_error "${DISK_TUPLES[$I]}: failed to parse (hint: should be {file|block|dir}:[:])" DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} STAT_OUTPUT=$(stat -L -c %F $DISK_IMG_OR_DEV_OR_DIR 2>&1) || true miniade_debug 10 "main: DISK_TYPE=$DISK_TYPE, DISK_IMG_OR_DEV_OR_DIR=$DISK_IMG_OR_DEV_OR_DIR, INTRA_VM_MNTPNT=$INTRA_VM_MNTPNT, STAT_OUTPUT=[$STAT_OUTPUT]" if [ $DISK_TYPE = file ] && [ "$STAT_OUTPUT" != "regular file" ]; then miniade_error "$DISK_IMG_OR_DEV_OR_DIR: not a file" elif [ $DISK_TYPE = block ] && [ "$STAT_OUTPUT" != "block special file" ]; then miniade_error "$DISK_IMG_OR_DEV_OR_DIR: not a block device" elif [ $DISK_TYPE = dir ] && [ "$STAT_OUTPUT" != "directory" ]; then miniade_error "$DISK_IMG_OR_DEV_OR_DIR: not a directory" fi { ! [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/drbd.* ]]; } || [ "X$(drbdadm status ${DISK_IMG_OR_DEV_OR_DIR#/dev/} | sed -n '1s/.*://p')" = XPrimary ] || miniade_error "$DISK_IMG_OR_DEV_OR_DIR: appears to be a DRBD device but not in primary mode" if [[ $DISK_TYPE =~ ^(file|block)$ ]]; then cut -d' ' -f1 /proc/mounts | { ! fgrep -xq $(readlink -f $DISK_IMG_OR_DEV_OR_DIR); } || miniade_error "$DISK_IMG_OR_DEV_OR_DIR: already mounted!" elif [ $DISK_TYPE = dir ]; then LS_OUTPUT=$(ls $DISK_IMG_OR_DEV_OR_DIR) || miniade_error "$DISK_IMG_OR_DEV_OR_DIR: not ls-able" [ "X$LS_OUTPUT" = X ] || miniade_error "$DISK_IMG_OR_DEV_OR_DIR: not empty" fi if [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^.*/${CNT_NAME}\.img$ ]]; then MOUNTPOINT_SUBDIR=root [[ $INTRA_VM_MNTPNT =~ ^(/|)$ ]] || miniade_error "root OS image must have intra-VM mountpoint either '/' or left unspecified (this check should really be done earlier (1)" elif [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^.*/${CNT_NAME}_(.*)\.img$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^/dev/.*${CNT_NAME}$ ]]; then MOUNTPOINT_SUBDIR=root [[ $INTRA_VM_MNTPNT =~ ^(/|)$ ]] || miniade_error "root OS image must have intra-VM mountpoint either '/' or left unspecified (this check should really be done earlier (2)" elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^/dev/.*${CNT_NAME}_(.*)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = dir ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^$MOUNTPOINT_ROOTDIR/$CNT_NAME/([^/]+)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} # not actually used but check is important [[ $INTRA_VM_MNTPNT =~ ^(/|)$ ]] || miniade_error "root OS image must have intra-VM mountpoint either '/' or left unspecified (this check should really be done earlier (2)" else miniade_error "$DISK_IMG_OR_DEV_OR_DIR: bad path" fi if [[ $DISK_TYPE =~ ^(file|block)$ ]]; then cut -d' ' -f2 /proc/mounts | { ! fgrep -xq $MOUNTPOINT_ROOTDIR/$CNT_NAME/$MOUNTPOINT_SUBDIR; } || miniade_error "$DISK_IMG_OR_DEV_OR_DIR: mountpoint already in use! (hint: run 'umount $MOUNTPOINT_ROOTDIR/$CNT_NAME/$MOUNTPOINT_SUBDIR'?)" fi done DISK_LETTER_MAP=( {a..z} ) # NIC checks miniade_debug 10 "main: NIC checks ..." for ((I=0; I<${#NIC_TUPLES[*]}; I++)); do [[ ${NIC_TUPLES[$I]} =~ ^(bridge|network):(.+) ]] || miniade_error "${NIC_TUPLES[$I]}: failed to parse (hint: should be {bridge|network}:)" NIC_TYPE=${BASH_REMATCH[1]} NIC_BRIDGE_OR_NETWORK=${BASH_REMATCH[2]} done # Memory checks miniade_debug 10 "main: memory checks ..." if [[ $MEM_SIZE =~ ^([1-9][0-9]*)([GMK]?)$ ]]; then MEM_SIZE=${BASH_REMATCH[1]} MEM_SIZE_UNIT=${BASH_REMATCH[2]:-G} else miniade_error "$MEM_SIZE: invalid memory size (hint: format is [unit])" fi # Release checks miniade_debug 10 "main: release checks ..." case $RELEASE in bullseye) : ;; debian11) RELEASE=bullseye ;; bookworm) : ;; debian12) RELEASE=bookworm ;; trixie) : ;; debian13) RELEASE=trixie ;; stable|unstable|testing|sid) miniade_error "$RELEASE: moving-target release name (hint: use a less ambiguous release name (e.g. 'debian11' or 'bullseye')" ;; *) miniade_internal "$RELEASE: invalid release" ;; esac # Misc miniade_debug 10 "main: misc checks ..." UUID=$(uuidgen) { $FLUSH_CACHE_FLAG && LXC_CREATE_FLUSH_CACHE_OPT="--flush-cache"; } || LXC_CREATE_FLUSH_CACHE_OPT= # Guts echo "$(date --iso=seconds): $0" "${ORIGINAL_ARGS[@]}" >> $HISTFILE if $UNDEFINE_FLAG; then miniade_evaler "virsh undefine $CNT_NAME > /dev/null" miniade_evaler "rm -fr /var/lib/lxc/$CNT_NAME" [ "X$REMOTE_HOST" = X ] || miniade_evaler "ssh -n $REMOTE_HOST \"LIBVIRT_DEFAULT_URI=$LIBVIRT_DEFAULT_URI virsh undefine $CNT_NAME\"" [ "X$REMOTE_HOST" = X ] || miniade_evaler "ssh -n $REMOTE_HOST \"rm -fr /var/lib/lxc/$CNT_NAME\"" fi make_container_filesystems mount_container_filesystems populate_container_root_file_system run_fixes_from_alexis shift_container_filesystems umount_container_filesystems write_xml > /tmp/$PROGNAME.$$.xml define_container /tmp/$PROGNAME.$$.xml } help() { local PROGNAME miniade_get_progname PROGNAME echo "Usage: $PROGNAME [ ] [ --undefine ] [ --flush-cache | -F ] [ --remote= ] --name= [ --mem=[MGT] ] [ --cpus= ] --disk={block|file|dir}:[:] [ ... ] --nic={bridge|network}: [ ... ] --release= --offset=" exit 0 } make_container_filesystems() { local GAVE_INFO_MSG_FLAG miniade_debug 10 "make_container_filesystems: sof" # Make file system on all disks. GAVE_INFO_MSG_FLAG=false for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_internal "this should have been detected in code above (1)" DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} if [ $DISK_TYPE = dir ]; then continue fi if ! $GAVE_INFO_MSG_FLAG; then miniade_info "making filesystems ..." GAVE_INFO_MSG_FLAG=true fi # I can't see any way to avoid 'contains a ext4 file system ... Proceed anyway?' # except blanking the signature. 'conv=notrunc' is needed when the rootfs device # is actually a file image else this dd shrinks the file to 10M. miniade_evaler "dd if=/dev/zero of=$DISK_IMG_OR_DEV_OR_DIR bs=1M count=10 conv=notrunc 2>/dev/null" miniade_evaler "mkfs -q -t ext4 $DISK_IMG_OR_DEV_OR_DIR" done } mount_container_filesystems() { local GAVE_INFO_MSG_FLAG miniade_debug 10 "mount_container_filesystems: sof" # Make file system on all disks. ## The root disk is the first disk listed. #[[ ${DISK_TUPLES[0]} =~ ^(file|block):(/.*) ]] || internal "this should have been detected in code above" #DISK_TYPE=${BASH_REMATCH[1]} #DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} GAVE_INFO_MSG_FLAG=false for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_internal "this should have been detected in code above (2)" DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} if [ $DISK_TYPE = dir ]; then continue fi if ! $GAVE_INFO_MSG_FLAG; then miniade_info "mounting filesystems ..." GAVE_INFO_MSG_FLAG=true fi if [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}\.img$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}_(.*)\.img$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}_(.*)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} else miniade_internal "this should have been detected in code above (3)" fi miniade_evaler "mkdir -p $MOUNTPOINT_ROOTDIR/$CNT_NAME/$MOUNTPOINT_SUBDIR" miniade_evaler "mount $DISK_IMG_OR_DEV_OR_DIR $MOUNTPOINT_ROOTDIR/$CNT_NAME/$MOUNTPOINT_SUBDIR" done } populate_container_root_file_system() { miniade_debug 10 "populate_container_root_file_system: sof" populate_container_root_file_system_$RELEASE "$@" } populate_container_root_file_system_bullseye() { miniade_debug 10 "populate_container_root_file_system: sof" populate_container_root_file_system_using_my_templates "$@" } populate_container_root_file_system_bookworm() { miniade_debug 10 "populate_container_root_file_system: sof" populate_container_root_file_system_using_my_templates "$@" } populate_container_root_file_system_trixie() { miniade_debug 10 "populate_container_root_file_system: sof" #populate_container_root_file_system_using_my_templates "$@" populate_container_root_file_system_using_os_templates "$@" } populate_container_root_file_system_using_os_templates() { miniade_debug 10 "populate_container_root_file_system_using_os_templates: sof" miniade_info "calling lxc-create with OS-provided template ..." # 'lxc-create --quiet' discards stdout and stderr, but without # '--quiet' it's ugly. We create an alias for stderr and tell # lxc-create to tell lxc-debian to use that instead of stderr. exec 4>&2 LXCCREATE_CMDLINE="lxc-create --quiet --bdev=dir --dir=$MOUNTPOINT_ROOTDIR/$CNT_NAME/root --name=$CNT_NAME --template=debian -- --mirror=$MIRROR --release=$RELEASE $LXC_CREATE_FLUSH_CACHE_OPT" miniade_evaler "$LXCCREATE_CMDLINE --stderr=4" || miniade_error "lxc-create failed (hint: try manually invoking: ${LXCCREATE_CMDLINE/--quiet /})" exec 4>&- miniade_evaler "rm -fr /var/lib/lxc/$CNT_NAME" } populate_container_root_file_system_using_my_templates() { local VERBOSELEVEL miniade_debug 10 "populate_container_root_file_system_using_my_templates: sof" miniade_info "calling lxc-create with my template ..." # 'lxc-create --quiet' discards stdout and stderr, but without # '--quiet' it's ugly. We create an alias for stderr and tell # lxc-create to tell lxc-debian to use that instead of stderr. exec 4>&2 miniade_get_verboselevel VERBOSELEVEL LXCCREATE_CMDLINE="lxc-create --quiet --bdev=dir --dir=$MOUNTPOINT_ROOTDIR/$CNT_NAME/root --name=$CNT_NAME --template=$MODROOT/share/lxc/templates/lxc-debian -- --mirror=$MIRROR --release=$RELEASE --debug=$VERBOSELEVEL $LXC_CREATE_FLUSH_CACHE_OPT" miniade_evaler "$LXCCREATE_CMDLINE --stderr=4" || miniade_error "lxc-create failed (hint: try manually invoking: ${LXCCREATE_CMDLINE/--quiet /})" exec 4>&- miniade_evaler "rm -fr /var/lib/lxc/$CNT_NAME" } run_fixes_from_alexis() { miniade_debug 10 "run_fixes_from_alexis: sof" miniade_info "copying root password from host ..." miniade_evaler "sed -i '/^root:/d' $MOUNTPOINT_ROOTDIR/$CNT_NAME/root/etc/shadow; grep '^root:' /etc/shadow >> $MOUNTPOINT_ROOTDIR/$CNT_NAME/root/etc/shadow" } shift_container_filesystems() { miniade_debug 10 "shift_container_filesystems: sof" local GAVE_INFO_MSG_FLAG GAVE_INFO_MSG_FLAG=false for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_internal "this should have been detected in code above (6)" DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} #if [ $DISK_TYPE = dir ]; then # continue #fi if ! $GAVE_INFO_MSG_FLAG; then miniade_info "shifting UIDs and GIDs in filesystems ..." GAVE_INFO_MSG_FLAG=true fi if [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}\.img$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}_(.*)\.img$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}_(.*)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = dir ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^$MOUNTPOINT_ROOTDIR/$CNT_NAME/([^/]+)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} else miniade_internal "this should have been detected in code above (7)" fi miniade_evaler "$MODROOT/bin/shift-uid-gid $MOUNTPOINT_ROOTDIR/$CNT_NAME/$MOUNTPOINT_SUBDIR $UID_GID_OFFSET $UID_GID_OFFSET" done } umount_container_filesystems() { local GAVE_INFO_MSG_FLAG miniade_debug 10 "umount_container_filesystems: sof" GAVE_INFO_MSG_FLAG=false for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_internal "this should have been detected in code above (4)" DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} if [ $DISK_TYPE = dir ]; then continue fi if ! $GAVE_INFO_MSG_FLAG; then miniade_info "unmounting filesystems ..." GAVE_INFO_MSG_FLAG=true fi if [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}\.img$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}_(.*)\.img$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}_(.*)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} else miniade_internal "this should have been detected in code above (5)" fi miniade_evaler "umount $MOUNTPOINT_ROOTDIR/$CNT_NAME/$MOUNTPOINT_SUBDIR" done } write_xml() { local ROOTFS_TYPE_LOCAL THING miniade_debug 10 "write_xml: sof" miniade_info "generating XML ..." echo "" echo " $CNT_NAME" echo " $UUID" echo " " miniade_debug 10 "write_xml: writing mounthook stuff ..." echo " " echo " " for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_internal "this should have been detected in code above (12)" DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} if [ $DISK_TYPE = dir ]; then continue fi if [ $DISK_TYPE = file ]; then DISK_TYPE_LOCAL=loop THING=file else DISK_TYPE_LOCAL=block THING=device fi if [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}\.img$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}_(.*)\.img$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}$ ]]; then MOUNTPOINT_SUBDIR=root elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}_(.*)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} else miniade_internal "this should have been detected in code above (8)" fi echo " " done echo " " echo " " miniade_debug 10 "write_xml: writing libosinfo stuff ..." echo " " miniade_debug 10 "write_xml: writing memory stuff ..." case $MEM_SIZE_UNIT in G) MEM_SIZE_KB=$((MEM_SIZE*1024*1024)) ;; M) MEM_SIZE_KB=$((MEM_SIZE*1024)) ;; K) MEM_SIZE_KB=$MEM_SIZE ;; esac echo " $MEM_SIZE_KB" echo " $MEM_SIZE_KB" miniade_debug 10 "write_xml: writing cpu stuff ..." echo " $CPU_COUNT" miniade_debug 10 "write_xml: writing cgroups stuff ..." echo " " echo " /machine" echo " " miniade_debug 10 "write_xml: writing OS stuff ..." echo " " echo " exe" echo " /sbin/init" echo " " miniade_debug 10 "write_xml: writing UID/GID remapping stuff ..." echo " " echo " " echo " " echo " " miniade_debug 10 "write_xml: writing features stuff ..." echo " " echo " " echo " " miniade_debug 10 "write_xml: writing clock stuff ..." echo " " miniade_debug 10 "write_xml: writing switch-related stuff ..." echo " destroy" echo " restart" echo " destroy" echo " " miniade_debug 10 "write_xml: writing hypervisor stuff ..." echo " /usr/lib/libvirt/libvirt_lxc" miniade_debug 10 "write_xml: writing video stuff ..." miniade_debug 10 "write_xml: writing controller stuff ..." miniade_debug 10 "write_xml: writing CDROM stuff ..." miniade_debug 10 "write_xml: writing memballoon stuff ..." miniade_debug 10 "write_xml: writing RNG stuff ..." miniade_debug 10 "write_xml: writing disk stuff ..." for ((I=0; I<${#DISK_TUPLES[*]}; I++)); do [[ ${DISK_TUPLES[$I]} =~ ^(file|block|dir):(/[^:]+)(:(/[^:]*))?$ ]] || miniade_internal "this should have been detected in code above (10)" echo " " DISK_TYPE=${BASH_REMATCH[1]} DISK_IMG_OR_DEV_OR_DIR=${BASH_REMATCH[2]} INTRA_VM_MNTPNT=${BASH_REMATCH[4]} if [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}\.img$ ]]; then MOUNTPOINT_SUBDIR=root TARGET_DIR=/ elif [ $DISK_TYPE = file ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ .*/${CNT_NAME}_(.*)\.img$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} if [ "X$INTRA_VM_MNTPNT" != X ]; then TARGET_DIR=$INTRA_VM_MNTPNT else TARGET_DIR=/srv/$MOUNTPOINT_SUBDIR fi elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}$ ]]; then MOUNTPOINT_SUBDIR=root TARGET_DIR=/ elif [ $DISK_TYPE = block ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ /dev/.*${CNT_NAME}_(.*)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} if [ "X$INTRA_VM_MNTPNT" != X ]; then TARGET_DIR=$INTRA_VM_MNTPNT else TARGET_DIR=/srv/$MOUNTPOINT_SUBDIR fi elif [ $DISK_TYPE = dir ] && [ $DISK_IMG_OR_DEV_OR_DIR = $MOUNTPOINT_ROOTDIR/$CNT_NAME/root ]; then MOUNTPOINT_SUBDIR=root TARGET_DIR=/ elif [ $DISK_TYPE = dir ] && [[ $DISK_IMG_OR_DEV_OR_DIR =~ ^$MOUNTPOINT_ROOTDIR/$CNT_NAME/([^/]+)$ ]]; then MOUNTPOINT_SUBDIR=${BASH_REMATCH[1]} if [ "X$INTRA_VM_MNTPNT" != X ]; then TARGET_DIR=$INTRA_VM_MNTPNT else TARGET_DIR=/srv/$MOUNTPOINT_SUBDIR fi else miniade_internal "this should have been detected in code above (11)" fi # Note mountpoint is hardcoded to .../root. So we don't support # multiple disks ... yet. echo " " echo " " echo " " done miniade_debug 10 "write_xml: writing nic stuff ..." for ((I=0; I<${#NIC_TUPLES[*]}; I++)); do [[ ${NIC_TUPLES[$I]} =~ ^(bridge|network):(.+) ]] NIC_TYPE=${BASH_REMATCH[1]} NIC_BRIDGE_OR_NETWORK=${BASH_REMATCH[2]} MACADDR=$(perl -e 'printf("%02x:%02x:%02x:%02x:%02x:%02x", 0x52, 0x54, 0x00, map { int(rand(256)) } 1..3);') echo " " echo " " echo " " echo " " done miniade_debug 10 "write_xml: writing console stuff ..." echo " " echo " " echo " " miniade_debug 10 "write_xml: writing audio stuff ..." miniade_debug 10 "write_xml: writing USB redirector stuff ..." echo " " echo "" } define_container() { local XML_FILE miniade_debug 10 "define_container: sof" [ $# = 1 ] || miniade_internal "define_vm: bad arg count ($#)" XML_FILE=$1 miniade_info "importing XML ..." miniade_evaler "virsh --quiet define $XML_FILE" if [ "X$REMOTE_HOST" != X ]; then miniade_info "importing XML on remote host ..." miniade_evaler "ssh -T $REMOTE_HOST \"export LIBVIRT_DEFAULT_URI=$LIBVIRT_DEFAULT_URI; virsh --quiet define <(cat)\" < $XML_FILE" miniade_evaler "rm $XML_FILE" else miniade_warning "$XML_FILE: use this file to define the container on the other node" fi } main "$@"