OS templates: technical details

From ISPWiki
Jump to: navigation, search

Hierarchy: VMmanager KVM -> OS templates section
VMmanager Cloud -> OS templates section

An OS template is the metainfo.xml file describing mechanisms that will be used during the installation process. VMmanager and DCImanager use single OS templates. You can view the pre-configured OS templates in our repository at http://master.download.ispsystem.com/OSTemplate/

List of parameters

  • <kernel>File name</kernel> - Linux kernel.
  • <initrd>File name</initrd> - initrd
  • <kernelcommand>Parameters</kernelcommand> - kernel boot parameters. Example- <kernelcommand>lang=en_US keymap=us ks=($OSINSTALLINFO_HTTP) method=http://mirror.yandex.ru/centos/6/os/x86_64/ initrd=initrd ip=($IP) netmask=($NETMASK) gateway=($GATEWAY) dns=($NAMESERVER)</kernelcommand>
  • <installdrive>File name</installdrive> - an additional virtual disk (this is a file up to 1 MB in size) can be connected to the virtual machine. You can use macros. This method can be used for FreeBSD 9 installation (for more details, see the FreeBSD installation guide). ("installdrive" is only used by VMmanager)
  • <installcfg>File name</installcfg> - the file that will be returned when following the url ($OSINSTALLINFO_HTTP). You can use macros.
  • <image>File name</image> - the ISO image that will be mounted as CDROM.
  • <tempipv4>yes</tempipv4> - an Ipv4-address is required for installation of OS with main IPv6 address.
  • <sharedir>Directory name</sharedir> - directory which files will be accessible through the http protocol. You can locate it in the OS template macros.
  • <support><elem version='5.1.0'>vmmgr</elem><elem>dcimgr</elem></support> - indicates software products that support thiss template. version - the minimum version of the control panel.
  • <rebootcount>1</rebootcount> - the number or reboots after which VMmanager considers the operating system to be installed.
  • <illegal_password_characters>Forbidden characters</illegal_password_characters> - characters that cannot be used in passwords.
  • <sshpublickey>yes</sshpublickey> - template supports public SSH-keys.
  • <up_mem_on_install>512</up_mem_on_install> - increase RAM up to this value during installation. When OS is installed, RAM will be reset to its previous value. The feature is supported only in VMmanager.
  • <virtionet>yes</virtionet> - templates supports virtio network. This feature is available only in VMmanager 5.4.0 and later.
  • <virtiodisk>yes</virtiodisk> - template supports virtio disks. This feature is available only in VMmanager 5.4.0 and later.
  • <chpasswd_method>mount.linux</chpasswd_method> - template supports password change. Currently the mount.linux method is used for linux-templates.
  • <loaderefi64>pxelinux.efi</loaderefi64> - template supports boot via UEFI (from version 5.127).
  • <ipxeconf>ipxe.conf</ipxeconf> - configuration file for boot via iPXE (from version 5.127).
  • <ipxeconf type="tftp"> - convert the filename record for iPXE in the dhcpd.conf configuration file to "tftp://10.10.10.10/.../ipxe.conf" (from version 5.128).

Limits

The limit node describes all template's limits. Note: you cannot create a virtual machine using that template if it does not meet its resource requirements. If the limits are not specified, the check won't be performed.

  • ipv4 - support IPv4 as the main IP address. yes/no
  • ipv6 - support IPv6 as the main IP address. yes/no
  • mem - the minimum amount of RAM in MiB.
  • disk - the minimum amount of disk space in MB.

For example:

 <limit>
 	<elem name="ipv4">yes</elem>
 	<elem name="ipv6">no</elem>
 	<elem name="mem">512</elem>
 	<elem name="disk">1500</elem>
 </limit>

How to create a template

Create a directory in [NFS storage]/image/YOUR_TEMPLATE_NAME. It must contain the metainfo.xml file with XML description of the template. The directory must also include all the files specified in the template parameters.

The template description should contain :

 <date>2013-04-14 15:37:21</date>
 <install_result>ok</install_result>

This check box indicates that the template is already installed. In our example the fields are not specified, because the description is given in the format that is used for templates from the repository.

Once completed, the newly created template will be added into the list of OS templates. You can add and manage it, all the changes made to the template file will be applied immediately.

How to add a repository

For more information, please refer to the article Creating custom OS templates repository.

Examples

kickstart (Centos, Fedora, RedHat)

For Centos we recommend using kickstart, as it provides flexible configuration and installation settings, and enables to make changes according to your needs.

metainfo.xml

 <?xml version="1.0"?>
 <doc>
   <osname>CentOS-6-amd64</osname>
   <support>
     <elem>VMmgr</elem>
     <elem>IFXmgr</elem>
   </support>
   <rebootcount>1</rebootcount>
   <kernel>vmlinuz</kernel>
   <initrd>initrd.img</initrd>
   <type>ostemplate</type>
   <loader>pxelinux.0</loader>
   <pxelinuxcfg>pxelinux.conf</pxelinuxcfg>
   <tempipv4>yes</tempipv4>
   <kernelcommand>lang=en_US keymap=us ks=($OSINSTALLINFO_HTTPv4) ksdevice=link method=http://mirror.yandex.ru/centos/6/os/x86_64/ ip=($IPv4) netmask=($NETMASKv4) gateway=($GATEWAYv4) dns=($NAMESERVERv4) proxy=($HTTPPROXYv4) text</kernelcommand>
   <installcfg>install.cfg</installcfg>
   <limit>
     <elem name="ipv4">yes</elem>
     <elem name="ipv6">yes</elem>
     <elem name="mem">512</elem>
     <elem name="disk">2000</elem>
   </limit>
 </doc>

install.cfg

 %pre
 
 #!/bin/sh
 
 for disk in `ls -la /dev/sd?`; do
 	dd if=/dev/zero of=$disk bs=512 count=32
 done
 
 SWSIZE=$(grep MemTotal /proc/meminfo  | awk '{print int($2/1024)+1}')
 if [ ${SWSIZE} -gt 2048 ]; then
 	SWSIZE=2048
 fi
 
 if [ `cat /proc/scsi/scsi | grep -wc ATA` -eq 2 ]; then
  	set $(fdisk -l 2>/dev/null | grep -vi mapper | grep Disk | grep dev |  sed 's/://' | awk '{print $2}' | tr '\n' ' ')
  	HD1=$1
 	HD2=$2
 	if [ -b ${HD2} ]; then
 		SIZE1=$(fdisk -l "${HD1}"  2>/dev/null  | grep Disk | grep dev |  sed 's/://'|awk '{print $5}')
 		SIZE2=$(fdisk -l "${HD2}"  2>/dev/null  | grep Disk | grep dev |  sed 's/://'|awk '{print $5}')
 		if [ -n "${SIZE1}" ] && [ -n "${SIZE2}" ] && [ "${SIZE1}" = "${SIZE2}" ]; then
 			USE_MIRROR=yes
 		fi
 	fi
 fi
 
 if [ -n "${USE_MIRROR}" ]; then
 cat > /tmp/part-include << EOF
 part raid.11 --size=256 --asprimary --ondisk=sda
 part raid.12 --size=${SWSIZE} --asprimary --ondisk=sda 
 part raid.13 --size=1 --grow --asprimary --ondisk=sda 
 part raid.21 --size=256 --asprimary --ondisk=sdb
 part raid.22 --size=${SWSIZE} --asprimary --ondisk=sdb 
 part raid.23 --size=1 --grow --asprimary --ondisk=sdb
 raid /boot --fstype ext4 --device md0 --level=RAID1 raid.11 raid.21
 raid swap --fstype swap --device md1 --level=RAID1 raid.12 raid.22
 raid / --fstype ext4 --device md2 --level=RAID1 raid.13 raid.23
 EOF
 else
 cat > /tmp/part-include << EOF
 part /boot --fstype ext4 --size=256 --asprimary --ondisk=sda
 part swap --size=${SWSIZE} --asprimary --ondisk=sda
 part / --fstype ext4 --size=1 --grow --asprimary --ondisk=sda
 EOF
 fi
 
 %end
 auth --useshadow --enablemd5
 # Crete partition map
 bootloader --location=mbr
 zerombr
 clearpart --all --initlabel
 firstboot --disable
 # Disk partitioning information
 %include /tmp/part-include
 # System keyboard
 keyboard us
 # System language
 lang en_US.UTF-8
 # Installation logging level
 logging --level=info
 # Use NFS installation media
 url --url http://mirror.yandex.ru/centos/6/os/x86_64/
 #Root password
 rootpw ($PASS)
 # SELinux configuration
 selinux --disabled
 # Text installation
 text
 # System timezone
 timezone --utc Europe/Moscow
 
 # Network
 network --bootproto=static --ip=($IPv4) --netmask=($NETMASK)  --gateway=($GATEWAYv4) --nameserver=($NAMESERVERv4) --hostname=($HOSTNAME) --device=link
 
 # Install OS instead of upgrade
 install
 %packages
 @core
 %end
 
 %post
 # Настройка сети
 #echo "NETWORKING=yes" > /etc/sysconfig/network
 #echo "HOSTNAME=($HOSTNAME)"
 ETHDEV=$(ip route show | grep default | grep -Eo 'dev\ .+\ ' | awk '{print $2}')
 HWADDR=$(cat /etc/sysconfig/network-scripts/ifcfg-eth0 | awk -F= '/HWADDR/ {print $2}' | sed 's/"//g')
 UUID=$(cat /etc/sysconfig/network-scripts/ifcfg-eth0 | awk -F= '/UUID/ {print $2}' | sed 's/"//g')
 
 if [ -n "($IPv6)" ]; then
 cat > /etc/sysconfig/network << EOF
 NETWORKING=yes
 NETWORKING_IPV6=yes
 HOSTNAME=($HOSTNAME)
 IPV6_DEFAULTGW=($GATEWAY)
 EOF
 
 cat > /etc/sysconfig/network-scripts/ifcfg-${ETHDEV} << EOF
 DEVICE="${ETHDEV}"
 BOOTPROTO="static"
 DNS1="($NAMESERVER)"
 HWADDR="${HWADDR}"
 IPV6ADDR="($IPv6)/($NETMASKv6)"
 IPV6INIT="yes"
 IPV6_AUTOCONF="no"
 IPV6_DEFAULTGW="($GATEWAY)"
 NM_CONTROLLED="yes"
 ONBOOT="yes"
 TYPE="Ethernet"
 UUID="${UUID}"
 EOF
 
 fi
 %end
 
 %post --nochroot
 wget -O /dev/null --no-check-certificate "($FINISHv4)"
 # Reboot after installation
 %end
 
 reboot

FreeBSD 9

The installation is made using the modified image of the installation disk. bootonly.iso is used. After the OS is booted from the disk, the /etc/rc.local file will be uploaded and modified.

To change settings of the newly installed system (its password, network, packets, etc) and allow your users not to modify the image thenaselves, complete the following steps. An additional disk (shell script of 1 MB in size) is connected to the virtual machine. Once the OS is booted from the disk, rc.local will start to read all of the data from the second hard drive, put them into /tmp/install.sh and start install.sh. Any actions can be described in install.sh.

The OS template includes the install.sh script. You can use macros, which VMmanager will change into corresponding values.

metainfo.xml

 <?xml version="1.0"?>
 <doc>
   <osname>FreeBSD-9-amd64</osname>
   <support>
     <elem>VMmgr</elem>
     <elem>IFXmgr</elem>
   </support>
   <image>freebsd.iso</image>
   <rebootcount>1</rebootcount>
   <type>ostemplate</type>
   <installdrive>freebsdinstall.sh</installdrive>
   <loader>pxelinux.0</loader>
   <pxelinuxcfg>pxelinux.conf</pxelinuxcfg>
   <installcfg>freebsdinstall.sh</installcfg>
   <initrd>freebsd.iso</initrd>
   <kernel>memdisk</kernel>
   <kernelcommand>iso raw</kernelcommand>
   <limit>
     <elem name="ipv4">yes</elem>
     <elem name="ipv6">yes</elem>
     <elem name="mem">512</elem>
     <elem name="disk">1500</elem>
   </limit>
 </doc>

freebsdinstall.sh

 #!/bin/sh
 
 WGET="fetch -o- -q "
 
 if [ "$START_BSD_INSTALL" != "yes" ]; then
 export START_BSD_INSTALL="yes"
 bsdinstall ../../../$0
 
 exit 0
 fi
 
 clear
 echo "Begin Installation at $(date)" | tee -a $BSDINSTALL_LOG
 
 2>>$BSDINSTALL_LOG
 
 error() {
 	${WGET} "($FAILURL)?error=$1"
 	exit 1
 } 
 
 rm -rf $BSDINSTALL_TMPETC
 mkdir $BSDINSTALL_TMPETC
 
 echo "Setting hostname..."
 HOSTNAME=($HOSTNAME)
 echo "hostname=\"$HOSTNAME\"" > $BSDINSTALL_TMPETC/rc.conf.hostname
 hostname -s "$HOSTNAME"
 
 echo "Configuring interfaces"
 echo "Detecting..."
 INTERFACES="${IFACE}"
 if [ -z "${INTERFACES}" ]; then
 	for IF in `ifconfig -l`; do
        test "$IF" = "lo0" && continue
        INTERFACES="$IF"
 	done
 fi
 if [ -z "$INTERFACES" ]; then
        dialog --backtitle 'FreeBSD Installer' \
            --title 'Network Configuration Error' \
            --msgbox 'No network interfaces present to configure.' 0 0
        exit 1
 fi
 
 if [ -n "($IPv6)" ]; then
 	echo "Configuring IPv6"
 	export http_proxy="($HTTPPROXYv6)"
 	export HTTP_PROXY="($HTTPPROXYv6)"
 	ifconfig $INTERFACES inet6 ($IPv6) prefixlen ($NETMASKv6)
 	route add -inet6 default ($GATEWAYv6)
 	echo "nameserver ($NAMESERVERv6)" >> /etc/resolv.conf
 
 	cat >> $BSDINSTALL_TMPETC/rc.conf.network << EOF
 ipv6_defaultrouter="($GATEWAYv6)"
 ifconfig_${INTERFACES}_ipv6="inet6 ($IPv6) prefixlen ($NETMASKv6)" 
 sshd_enable="YES"
 ipv6_all_interfaces="YES"
 EOF
 	echo "nameserver ($NAMESERVERv6)" >> $BSDINSTALL_TMPETC/resolv.conf
 elif [ -n "($IPv4)" ]; then
 	echo "Configuring IPv4"
 	export http_proxy="($HTTPPROXYv4)"
 	export HTTP_PROXY="($HTTPPROXYv4)"
 	ifconfig $INTERFACES inet ($IPv4) netmask ($NETMASKv4)
 	route add default ($GATEWAYv4)
 	echo "nameserver ($NAMESERVERv4)" >> /etc/resolv.conf
 	echo "name_servers=($NAMESERVERv4)" >> /etc/resolvconf.conf
 
 	cat >> $BSDINSTALL_TMPETC/rc.conf.network << EOF
 defaultrouter="($GATEWAYv4)"
 ifconfig_${INTERFACES}="inet ($IPv4) netmask ($NETMASKv4)" 
 sshd_enable="YES"
 EOF
 
 	echo "nameserver ($NAMESERVERv4)" >> $BSDINSTALL_TMPETC/resolv.conf
 fi
 sleep 5
 
 echo "Setting files for download"
 if [ "#$(uname -m)" = "#amd64" ]; then
        export DISTRIBUTIONS="base.txz kernel.txz lib32.txz"
 else
         export DISTRIBUTIONS="base.txz kernel.txz"
 fi
 
 FETCH_DISTRIBUTIONS=""
 for dist in $DISTRIBUTIONS; do
        if [ ! -f $BSDINSTALL_DISTDIR/$dist ]; then
                FETCH_DISTRIBUTIONS="$FETCH_DISTRIBUTIONS $dist"
        fi
 done
 FETCH_DISTRIBUTIONS=`echo $FETCH_DISTRIBUTIONS` # Trim white space
 
 MIRROR="http://mirror.yandex.ru/freebsd/snapshots"
 BSDVER="9.1-STABLE"
 
 BSDINSTALL_DISTSITE="$MIRROR/`uname -m`/`uname -p`/${BSDVER}"
 
 export BSDINSTALL_DISTSITE
 
 
 echo "Detecting disks"
 rm $PATH_FSTAB
 touch $PATH_FSTAB
 
 DISKS=`/sbin/sysctl -n kern.disks`
 if [ -n ${SKIP_HD} ]; then
 	DISKS=$(echo ${DISKS} | sed "s/${SKIP_HD}[ ]\{0,\}//")
 fi
 
 
 HD=${HD:-empty}
 if [ $HD = "empty" ]; then
  HD=`echo $DISKS | xargs -n1 echo | grep ar | sort -tr -k2 -n | head -1`
  if [ -z "$HD" ]; then
    HD=`echo $DISKS | xargs -n1 echo | grep ad | sort -td -k2 -n | head -1`
    if [ -z "$HD" ]; then
      HD=`echo $DISKS | xargs -n1 echo | grep da | sort -ta -k2 -n | head -1`
      if [ -z "$HD" ]; then
        HD=`echo $DISKS | /usr/bin/cut -d ' ' -f1`
        if [ -z "$HD" ]; then
          exit 1
        fi
      fi
    fi
  fi
 else
  if [ ! -b /dev/$HD ]; then
    # Hard disk device with this name not found
    # Terminate install with error
    error "disknodetect"
  fi
 fi
 
 DISK_TYPE=$(echo ${HD} | sed -e 's/[0-9]\{1,\}.*$//g')
 echo "Disk type: ${DISK_TYPE}"
 
 if [ $(echo ${DISKS} | grep -Eo "${DISK_TYPE}[0-9]" | wc -l) -eq 2 ]; then
 # Mirror
 	HDDS=$(echo ${DISKS} | grep -Eo "${DISK_TYPE}[0-9]")
 	echo "${HDDS}"
 	set ${HDDS}
 	HD1=$1
 	HD2=$2
 	echo "Disk1: ${HD1}"
 	echo "Disk2: ${HD2}"
 	SIZE1=$(grep -Eio "^${HD1}: [0-9]{1,}(mb|gb|tb|b) " /var/run/dmesg.boot | awk '{print $2}')
 	SIZE2=$(grep -Eio "^${HD2}: [0-9]{1,}(mb|gb|tb|b) " /var/run/dmesg.boot | awk '{print $2}')
 
 	grep -Eio "^${HD1}: [0-9]{1,}(mb|gb|tb|b) " /var/run/dmesg.boot
 	echo "Disk1 size: ${SIZE1}"
 	grep -Eio "^${HD2}: [0-9]{1,}(mb|gb|tb|b) " /var/run/dmesg.boot
 	echo "Disk2 size: ${SIZE2}"
 
 	if [ -n "${SIZE1}" ] && [ -n "${SIZE2}" ] && [ "${SIZE1}" = "${SIZE2}" ]; then
 		echo "This is miroor system"
 		GMIRROR=yes
 	else
 		echo "Disks size is differ"
 		echo "This is single system"
 		HDDS=${HD}
 	fi
 else
 # single
 	echo "This is single system"
 	HDDS=${HD}
 fi
 
 #exec 1>&2
 echo "Formatting disks"
 
 clear_disks() {
 	# $1 - disk
 	# $2 - disk-label-ending
         gpart delete -i 2 $1
         gpart delete -i 3 $1
         gpart delete -i 4 $1
         gpart delete -i 5 $1
         gpart delete -i 6 $1
         echo "destroy" | tee -a $BSDINSTALL_LOG
         gpart destroy -F $1
         echo "create GPT" | tee -a $BSDINSTALL_LOG
         gpart create -s GPT $1
         echo "add boot" | tee -a $BSDINSTALL_LOG
         gpart add -t freebsd-boot -l gpboot$2 -s 256K $1
         echo "set bootcode" | tee -a $BSDINSTALL_LOG
         gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 $1
         echo "add swap" >> $BSDINSTALL_LOG
         SWSIZE=$(sysctl -n hw.realmem | awk '{print int($1/1024/1024)+1}')
 		if [ ${SWSIZE} -gt 2048 ]; then
 			SWSIZE=2048
 		fi
         gpart add -t freebsd-swap -l swap$2 -s ${SWSIZE}M $1
         echo "add root" | tee -a $BSDINSTALL_LOG
 
         # calculating size (not neded now)
         #let "ROOT_PART = ($VOL_SIZE_M) - 1"
         #echo "$ROOT_PART"
         #gpart add -t freebsd-ufs -l rootfs -s "$ROOT_PART"M $HD
         gpart add -t freebsd-ufs -l rootfs$2 $1 
 
 }
 
 if [ -n "${GMIRROR}" ]; then
 	clear_disks ${HD1} ${HD1}
 	clear_disks ${HD2} ${HD2}
 else
 	clear_disks ${HD}
 fi
 
 if [ -n "${GMIRROR}" ]; then
 	echo "Creating mirror"
 	gmirror load
 	gmirror label -v rootfs /dev/gpt/rootfs${HD1} /dev/gpt/rootfs${HD2}
 	gmirror label -v swap /dev/gpt/swap${HD1} /dev/gpt/swap${HD2}
 
 	echo "newfs root" | tee -a $BSDINSTALL_LOG
 	newfs -U /dev/mirror/rootfs
 
 	echo "mount" | tee -a $BSDINSTALL_LOG
 	mount /dev/mirror/rootfs $BSDINSTALL_CHROOT
 
 	echo "# Device                Mountpoint      FStype  Options         Dump    Pass#" > $PATH_FSTAB
 	echo "/dev/mirror/swap        none    swap    sw      0       0"    >> $PATH_FSTAB
 	echo "/dev/mirror/rootfs       /               ufs     rw      1       1" >> $PATH_FSTAB
 else
 
 	echo "newfs root" | tee -a $BSDINSTALL_LOG
 	newfs -U /dev/gpt/rootfs
 
 	echo "mount" | tee -a $BSDINSTALL_LOG
 	mount /dev/gpt/rootfs $BSDINSTALL_CHROOT
 
 	echo "# Device                Mountpoint      FStype  Options         Dump    Pass#" > $PATH_FSTAB
 	echo "/dev/gpt/swap        none    swap    sw      0       0"    >> $PATH_FSTAB
 	echo "/dev/gpt/rootfs       /               ufs     rw      1       1" >> $PATH_FSTAB
 fi
 
 if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
        ALL_DISTRIBUTIONS="$DISTRIBUTIONS"
 
        # Download to a directory in the new system as scratch space
        BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
        mkdir -p "$BSDINSTALL_FETCHDEST" || error
 
        export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
        # Try to use any existing distfiles
        if [ -d $BSDINSTALL_DISTDIR ]; then
                DISTDIR_IS_UNIONFS=1
                mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR"
        else
                export DISTRIBUTIONS="MANIFEST $ALL_DISTRIBUTIONS"
                export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST"
        fi
 
        export FTP_PASSIVE_MODE=YES
        bsdinstall distfetch || error fetch
        export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
         clear
 fi
 
 bsdinstall checksum || error checksummincorrect
 bsdinstall distextract || error distextractfail
 clear
 
 echo "Setting password"
 PASSWORD="($PASS)"
 
 echo $PASSWORD | pw -V "$BSDINSTALL_CHROOT/etc" usermod root -h0
 
 echo "Configuring services"
 echo "PermitRootLogin yes" >> "$BSDINSTALL_CHROOT/etc/ssh/sshd_config"
 
 #echo sshd_enable=\"YES\" >> $BSDINSTALL_TMPETC/rc.conf.services
 echo dumpdev=\"AUTO\" >> $BSDINSTALL_TMPETC/rc.conf.services
 
 if [ -n "${GMIRROR}" ]; then
 	echo geom_mirror_load="YES" >> $BSDINSTALL_CHROOT/boot/loader.conf
 fi
 
 echo "Installing configs"
 bsdinstall config  || error
 
 echo "Installing vim"
 chroot $BSDINSTALL_CHROOT pkg_add -r vim-lite
 sed -i "" -E 's/EDITOR(.*)vi/EDITOR\1vim/g' $BSDINSTALL_CHROOT/root/.cshrc
 cat >> $BSDINSTALL_CHROOT/root/.vimrc << EOF
 set nocompatible
 set encoding=utf8
 syntax on
 EOF
 
 cp $BSDINSTALL_LOG $BSDINSTALL_CHROOT/root/
 dmesg > $BSDINSTALL_CHROOT/root/dmesg
 if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
        [ "$BSDINSTALL_FETCHDEST" != "$BSDINSTALL_DISTDIR" ] && \
            umount "$BSDINSTALL_DISTDIR"
        rm -rf "$BSDINSTALL_FETCHDEST"
 fi
 
 echo "Installation complete"
 $WGET "($FINISH)"
 
 echo "Installation Completed at $(date)" | tee -a $BSDINSTALL_LOG
 cp $BSDINSTALL_LOG $BSDINSTALL_CHROOT/root

preseed (Debian, Ubuntu)

This mechanism is similar to kickstart.

metainfo.xml

 <?xml version="1.0"?>
 <doc>
   <osname>Debian-7-amd64</osname>
   <support>
     <elem>IFXmgr</elem>
     <elem>VMmgr</elem>
   </support>
   <rebootcount>1</rebootcount>
   <kernel>linux</kernel>
   <initrd>initrd.gz</initrd>
   <type>ostemplate</type>
   <loader>pxelinux.0</loader>
   <pxelinuxcfg>pxelinux.conf</pxelinuxcfg>
   <tempipv4>yes</tempipv4>
   <kernelcommand>url=($OSINSTALLINFO_HTTPv4) language=en debian-installer/country=RU locale=en_US keyboard-configuration/xkb-keymap=us console-keymaps-at/keymap=us interface=auto netcfg/disable_dhcp=true netcfg/get_ipaddress=($IPv4) netcfg/get_netmask=($NETMASKv4) netcfg/get_gateway=($GATEWAYv4) netcfg/get_nameservers=($NAMESERVERv4) hostname=($HOSTNAME) domain=($HOSTNAME)</kernelcommand>
   <installcfg>install.cfg</installcfg>
   <limit>
     <elem name="ipv4">yes</elem>
     <elem name="ipv6">yes</elem>
     <elem name="mem">512</elem>
     <elem name="disk">1000</elem>
   </limit>
 </doc>

install.cfg

 d-i keyboard-configuration/xkb-keymap select us
 
 # Mirrors
 #d-i mirror/protocol string ftp
 #d-i mirror/country string manual
 #d-i mirror/ftp/hostname string ftp.ru.debian.org
 #d-i mirror/ftp/directory string /debian
 #d-i mirror/ftp/proxy string
 d-i mirror/country string manual
 d-i mirror/http/hostname string mirror.yandex.ru
 d-i mirror/http/directory string /debian
 d-i mirror/http/proxy string ($HTTPPROXYv4)
 
 d-i passwd/make-user boolean false
 
 d-i passwd/root-password password ($PASS)
 d-i passwd/root-password-again password ($PASS)
 
 d-i clock-setup/utc boolean true
 
 d-i time/zone string Europe/Moscow
 
 d-i preseed/early_command string \
 	anna-install parted-udeb 
 
 # Partitioning
 d-i partman/early_command string \
 for DISK in $(list-devices disk); do \
     dd if=/dev/zero of=${DISK} bs=512 count=1; \
     parted -s ${DISK} mklabel gpt; \
 done; \
 set $(list-devices disk); \
 let numb=$#/2; \
 DISKA=$1; \
 DISKB=$2; \
 if [ -b "${DISKB}" ]; then \
     SIZE1=$(fdisk -l "${DISKA}" 2>/dev/null|grep Disk|grep dev|cut -d' ' -f5); \
     SIZE2=$(fdisk -l "${DISKB}" 2>/dev/null|grep Disk|grep dev|cut -d' ' -f5); \
 	if [ -n ${SIZE1} ] && [ -n ${SIZE2} ] && [ "${SIZE1}" = "${SIZE2}" ]; then \
 	    USE_MIRROR=yes; \
 	else \
 	    USE_MIRROR=no; \
 	fi; \
 fi; \
 if [ "#${USE_MIRROR}" = "#yes" ]; then \
 	debconf-set partman-auto/disk "$DISKA $DISKB";\
 	debconf-set partman-auto/method "raid";\
 	debconf-set partman-auto/expert_recipe "multiraid :: \
 		100 50 100 raid $primary{ } method{ raid } . \
 		128 512 100% raid method{ raid } . \
 		1024 10000 1000000000 raid method{ raid } . ";\
 	debconf-set partman-auto-raid/recipe "1 2 0 ext2 /boot ${DISKA}1#${DISKB}1 . \
 		1 2 0 swap - ${DISKA}5#${DISKB}5 . \
 		1 2 0 ext4 / ${DISKA}6#${DISKB}6 . ";\
 	debconf-set grub-installer/bootdev "$DISKA $DISKB";\
 else \
 	debconf-set partman-auto/disk "$DISKA";\
 	debconf-set partman-auto/method "regular";\
 	debconf-set partman-auto/expert_recipe "boot-root :: \
 		100 50 100 ext2 $primary{ } $bootable{ } method{ format } format{ } use_filesystem{ } filesystem{ ext2 } mountpoint{ /boot } . \
 		128 512 100% linux-swap method{ swap } format{ } . \
 		1024 10000 1000000000 ext4 method{ format } format{ } use_filesystem{ } filesystem{ ext4 } mountpoint{ / } . ";\
 	debconf-set grub-installer/bootdev "$DISKA";\
 fi 
 
 
 #d-i partman-auto/method string regular
 
 #d-i partman-auto/expert_recipe string                         \
 #      boot-root ::                                            \
 #              40 50 100 ext2                                  \
 #                      $primary{ } $bootable{ }                \
 #                      method{ format } format{ }              \
 #                      use_filesystem{ } filesystem{ ext2 }    \
 #                      mountpoint{ /boot }                     \
 #              .                                               \
 #              500 10000 1000000000 ext4                       \
 #                      method{ format } format{ }              \
 #                      use_filesystem{ } filesystem{ ext4 }    \
 #                      mountpoint{ / }                         \
 #              .                                               \
 #              64 512 300% linux-swap                          \
 #                      method{ swap } format{ }                \
 #		.
 
 # Force overwrite partitions
 
 d-i partman-partitioning/choose_label       select gpt
 d-i partman-partitioning/confirm_new_label  boolean true
 d-i partman-partitioning/unknown_label  boolean true
 d-i partman/exception_handler   select  Yes
 partman-partitioning    partman-partitioning/choose_label       select gpt
 partman-partitioning    partman-partitioning/confirm_new_label  boolean true
 partman-partitioning    partman-partitioning/unknown_label  boolean true
 partman-base    partman/exception_handler   select  Yes
 
 d-i partman-auto/purge_lvm_from_device boolean true
 d-i partman-lvm/device_remove_lvm boolean true 
 d-i partman-md/device_remove_md boolean true
 d-i partman-md/confirm boolean true
 d-i partman-md/confirm_nooverwrite boolean true
 d-i partman-partitioning/confirm_write_new_label boolean true
 d-i partman/choose_partition select finish
 d-i partman/confirm boolean true
 d-i partman/confirm_nooverwrite boolean true
 
 d-i partman/mount_style select traditional
 
 # Apt
 
 #d-i base-installer/install-recommends boolean true
 
 #d-i base-installer/kernel/linux/initramfs-generators string initramfs-tools
 #d-i base-installer/kernel/image string linux-image-amd64
 
 d-i apt-setup/contrib boolean true
 #d-i apt-setup/use_mirror boolean true
 
 # Packages
 d-i apt-setup/services-select multiselect security, volatile
 tasksel tasksel/first multiselect standard
 d-i pkgsel/include string openssh-server vim wget
 
 popularity-contest popularity-contest/participate boolean false
 
 # Grub
 d-i grub-installer/only_debian boolean true
 d-i grub-installer/with_other_os boolean true
 
 d-i finish-install/keep-consoles boolean true
 
 d-i preseed/late_command string \
 	in-target rm -f /etc/apt/apt.conf ;\
 	ETHDEV=$(ip route show | grep default | grep -Eo 'dev\ .+\ ' | cut -d' ' -f2) ;\
 	if [ -n "($IPv6)" ]; then \
 		echo "# The loopback network interface" > /target/etc/network/interfaces ;\
 		echo "auto lo" >> /target/etc/network/interfaces ;\
 		echo "iface lo inet loopback" >> /target/etc/network/interfaces ;\
 		echo "" >> /target/etc/network/interfaces ;\
 		echo "# The primary network interface" >> /target/etc/network/interfaces ;\
 		echo "allow-hotplug ${ETHDEV}" >> /target/etc/network/interfaces ;\
 		echo "iface ${ETHDEV} inet6 static" >> /target/etc/network/interfaces ;\
 		echo -e "\taddress ($IPv6)" >> /target/etc/network/interfaces ;\
 		echo -e "\tnetmask ($NETMASKv6)" >> /target/etc/network/interfaces ;\
 		echo -e "\tgateway ($GATEWAYv6)" >> /target/etc/network/interfaces ;\
 		echo -e "\tdns-nameservers ($NAMESERVERv6)" >> /target/etc/network/interfaces ;\
 		echo "nameserver ($NAMESERVERv6)" > /target/etc/resolv.conf ;\
 		sed -i "s/($IPv4)/($IPv6)/" /etc/hosts ;\
 		sed -i "s/($IPv4)/($IPv6)/" /target/etc/hosts ;\
 		echo "# The loopback network interface" > /etc/network/interfaces ;\
 		echo "auto lo" >> /etc/network/interfaces ;\
 		echo "iface lo inet loopback" >> /etc/network/interfaces ;\
 		echo "" >> /etc/network/interfaces ;\
 		echo "# The primary network interface" >> /etc/network/interfaces ;\
 		echo "allow-hotplug ${ETHDEV}" >> /etc/network/interfaces ;\
 		echo "iface ${ETHDEV} inet6 static" >> /etc/network/interfaces ;\
 		echo -e "\taddress ($IPv6)" >> /etc/network/interfaces ;\
 		echo -e "\tnetmask ($NETMASKv6)" >> /etc/network/interfaces ;\
 		echo -e "\tgateway ($GATEWAYv6)" >> /etc/network/interfaces ;\
 		echo -e "\tdns-nameservers ($NAMESERVERv6)" >> /etc/network/interfaces ;\
 		echo "nameserver ($NAMESERVERv6)" > /etc/resolv.conf ;\
 	fi ;\
 	in-target wget --no-check-certificate "($FINISHv4)"
 
 d-i finish-install/reboot_in_progress note

Windows

Only VMmanager currently supports this method. The system installs a ready-to-use image of the operating system. The C:\vmmgr\firstrun.cmd script boots automatically. The script uses dd to read the data from 1MB virtual disk containing the script from VMmanager. We recommend that you use Task Scheduler for auto-reboot.

Autoboot script

Locate the scripts in C:\vmmgr\

firstrun.cmd
@echo off
powershell.exe C:\vmmgr\firstrun.ps1 >NUL
firstrun.ps1
 $ddout = C:\vmmgr\ddwrap.cmd
 $ddout
 $list = $ddout | select-string "size is 1048576 bytes" -Context 3,0
 $list
 $context = $list.Context.PreContext | select-string Part
 $str = $context.Line
 $str
 C:\vmmgr\dd.exe if=$str of=C:\vmmgr\vmmgr.cmd bs=512 count=2048
 C:\vmmgr\vmmgr.cmd
ddwrap.cmd
c:\vmmgr\dd.exe --list 2>&1


When using our boot scripts, you should allow unsigned scripts in PowerShell. In PowerShell and execute the command:

Set-ExecutionPolicy RemoteSigned

Locate dd utility into C:\vmmgr\

Template files

metainfo.xml
 <?xml version="1.0"?>
 <doc>
   <osname>Windows-Server-2012</osname>
   <limit>
     <elem name="ipv4">yes</elem>
     <elem name="ipv6">no</elem>
     <elem name="mem">1024</elem>
     <elem name="disk">10000</elem>
   </limit>
   <support>
     <elem>VMmgr</elem>
   </support>
   <hddimage>win_ser_2012_str.hddimage</hddimage>
   <rebootcount>1</rebootcount>
   <type>ostemplate</type>
   <installdrive>win_ser_2012_str.cmd</installdrive>
 </doc>

win_ser_2012_str.cmd

In the installation script comment out the lines for Windows activation and specify your key.

 @echo off
 set logfile=C:\setup.log 
 echo ------Set static IP-------------------------------------[%DATE%-%TIME%]      > %logfile%
 echo --- IP/NM=($IP)/($NETMASK)  GW=($GATEWAY)      >> %logfile%
 echo --- NS1=($NAMESERVER)                                                   >> %logfile%
 netsh interface ip set address    "Ethernet" static ($IP) ($NETMASK) ($GATEWAY)  >> %logfile%
 netsh interface ip add dnsservers "Ethernet" ($NAMESERVER)          >> %logfile%
 echo --- set Administartor password >> %logfile%
 net user Administrator ($PASS)  >> %logfile%
 set extendfile=C:\vmmgr\extend.txt
 echo --- resize disk >> %logfile%
 echo select volume 1 > %extendfile%
 echo extend noerr >> %extendfile%
 diskpart.exe /s %extendfile% >> %logfile%
 
 #Uncomment the following 3 lines and enter your activation key.
 #echo activate windows >> %logfile%
 #cscript %windir%\system32\slmgr.vbs -ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXX
 #cscript %windir%\system32\slmgr.vbs -ato
 
 echo remove task vmmgr_firstrun >> %logfile%
 schtasks /Delete /TN "vmmgr_firstrun" /F  >> %logfile%
 echo restart OS >> %logfile%
 echo ------END--------------------------------------------------[%DATE%-%TIME%]     >> %logfile%
 
 echo RMDIR /s /Q  C:\vmmgr >> c:\del.cmd
 echo shutdown /r >> c:\del.cmd
 cmd /c c:\del.cmd

CentOS. Extraction of OS template from file

You can create a Linux template that will be extracted from a predefined disk image. Before you start, make sure that OS file system supports "resizing on the fly" on a mounted file system (e.g. ext4).

This method can be used only for VMmanager

We'll take an example on CentOS.

Creating a disk image

In order to create an image, you need to create a virtual machine running CentOS with a small disk size (2GB)

You can install and required software applications Disk partition:

/dev/vda1 - /boot
/dev/vda2 - swap
/dev/vda3 - / 

In /etc/rc.local add a command to run the installation script that will be connected with the installdrive option.

echo "sh /dev/sda" >> /etc/rc.local

NOTE If you run Debian, the /etc/rc.local file ends with exit 0, and you need to add before "exit" rather than at the end of the file.

If virtio is not supported, the setup disk will be /dev/sdb

Make a "disk dump" into the file of the template directory:

LVM:

dd if=/dev/MyLvm/VMNAME of=centos_hdd.image

RAW:

dd if=PATHE_TO_FILE of=centos_hdd.image

Installation script

Following is the example for CentOS. If you run Debian, the script will differ. A file name is specified in the installdrive parameter

#!/bin/sh
 
clean_files() {
        rm -f /etc/ssh/*key*
        sed -r -i '/sh \/dev\/sda/d' /etc/rc.local
}
 
 
disk_format() {
        fdisk /dev/vda <<EOF
c
d
3
n
p
3
 
 
w
EOF
}
 
resize_fs() {
        cat >> /etc/init.d/resize_fs << EOF
#!/bin/bash
#
# Resize fs
#
### BEGIN INIT INFO
# Default-Start:        1 2 3 4 5
# Default-Stop:         0 6
# Required-Start:
# Required-Stop?
# Short-Description:    Resize root filesystem
# Description:          Resize root filesystem
# Provides:             resize_fs
### END INIT INFO
 
. /etc/init.d/functions
 
case "\$1" in
        start|reload)
                resize2fs /dev/root
                chkconfig --del resize_fs
                rm -f /etc/init.d/resize_fs
                exit 0
                ;;
        *)
                echo "service resize_fs start"
                exit 2
esac
 
EOF
chmod +x /etc/init.d/resize_fs
chkconfig --add resize_fs
}
 
network_configure() {
        IPv4=($IPv4)
        NETMASK=($NETMASKv4)
        GATEWAYv4=($GATEWAYv4)
        IPv6=($IPv6)
        PREFIX=($NETMASKv6)
        GATEWAYv6=($GATEWAYv6)
        HOSTNAME=($HOSTNAME)
 
        if [ -n "${GATEWAYv4}" ]; then
                GATEWAY=${GATEWAYv4}
        else
                GATEWAY=${GATEWAYv6}
        fi
 
        # Removing udev rules
        rm -f /etc/udev/rules.d/70-persistent-net.rules
 
 
        # Configuring network
        sed -r -i '/HOSTNAME=.+/d; /GATEWAY=.+/d' /etc/sysconfig/network
cat >> /etc/sysconfig/network << EOF
HOSTNAME=${HOSTNAME}
GATEWAY=${GATEWAY}
EOF
 
        ip link set eth1 name eth0
        HWADDR=$(ip link show eth0 | awk '/link\/ether/ {print $2}' | tr [:lower:] [:upper:])
 
        cat > /etc/sysconfig/network-scripts/ifcfg-eth0 << EOF
DEVICE="eth0"
BOOTPROTO="static"
DNS1="($NAMESERVER)"
HWADDR="${HWADDR}"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
EOF
 
        if [ -n "${IPv4}" ]; then
                cat >> /etc/sysconfig/network-scripts/ifcfg-eth0 << EOF
GATEWAY="${GATEWAYv4}"
IPADDR="${IPv4}"
NETMASK="${NETMASK}"
EOF
 
        else
                cat >> /etc/sysconfig/network-scripts/ifcfg-eth0 << EOF
IPV6INIT="yes"
IPV6ADDR="${IPv6}/${PREFIX}"
IPV6_DEFAULTGW="${GATEWAYv6}"
EOF
 
        fi
 
        ifup eth0
}
 
clean_files
disk_format
resize_fs
echo "($PASS)" | passwd --stdin root
network_configure
wget -q -O /dev/null --no-check-certificate "($FINISH)"
reboot

This script will:

  • resize the partition
  • set a password
  • enable file system resize after next start. It cannot be done after you apply the changes, as the OS kernel will get information about the changes you have made only after reboot.
  • delete the command for its start from /etc/rc.local


metainfo.xml

<?xml version="1.0"?>
<doc>
  <osname>CentOS-6-amd64-fromdisk</osname>
  <limit>
    <elem name="ipv4">yes</elem>
    <elem name="ipv6">yes</elem>
    <elem name="mem">512</elem>
    <elem name="disk">2000</elem>
  </limit>
  <support>
    <elem version="5.4.0">VMmgr</elem>
  </support>
  <hddimage>centos_hdd.image</hddimage>
  <rebootcount>1</rebootcount>
  <type>ostemplate</type>
  <installdrive>install.sh</installdrive>
  <virtiodisk>yes</virtiodisk>
  <virtionet>yes</virtionet>
  <date>2013-09-20 12:59:19</date>
  <install_result>ok</install_result>
</doc>