Updated Nov 12, 2017, 1:18 PM
==================================================================
Here's a very simple libvirt automatic Ubuntu system provisioning processes.
Requirements are simple, libvirt, qemu-kvm, virt-manager, apache web server, nbd module.
This process uses a backing store feature for the rootfs disk on the created instance.
The base rootfs (qcow2) image is /var/lib/libvirt/images/ubuntu-base
It is created using the "make-base" script below.
The script references an Ubuntu preseed.cfg file (see below), and
a postinstall file to be served up by your apache ( or any other webserver ),
You must update the /var/lib/libvirt/images/preseed.cfg file to reference the postinstall script, at the bottom of preseed.cfg.
You must copy the postinstall script (see below) to include your own root public key.
Create a node by calling the script "newnode", and pass the fqdn of the node-name to create.
You must ensure the node-name is fully defined in your /etc/hosts, or that a DNS query will return the ip-address.
Example: ./newnode ubuntu1.tsand.org
This will create a vda disk called ubuntu1.tsand.org, with a backing store of /var/lib/libvirt/images/ubuntu-base, with a static ip address.
Code:
>>>>> make-base
1 #! /bin/bash
2 # vi:set nu ai ap aw smd showmatch tabstop=4 shiftwidth=4:
3 RELEASE="xenial"
4 DISKSIZE="5"
5 virt-install \
6 --connect qemu:///system \
7 --name ubuntu-base \
8 --ram 1024 \
9 --vcpus 2 \
10 --disk pool=default,size=${DISKSIZE},bus=virtio,sparse=false \
11 --location 'http://archive.ubuntu.com/ubuntu/dists/${RELEASE}/main/installer-amd64/' \
12 --network bridge=br0,model=virtio \
13 --initrd-inject=/var/lib/libvirt/images/preseed.cfg \
14 --extra-args="locale=en_US.UTF-8 console-setup/ask_detect=false keyboard-configuration/layoutcode=us file=file:/preseed.cfg vga=788 quiet" \
15 --os-type=linux \
16 --os-variant=ubuntuprecise \
17 --virt-type kvm \
18 --video=vga \
19 --noreboot
>>>>> newnode
1 #! /bin/bash
2 # vi:set nu ai ap aw smd showmatch tabstop=4 shiftwidth=4:
3 #
4 TOP="/var/lib/libvirt/images"
5 IMG="ubuntu-base.qcow2"
6 SRC="${TOP}/${IMG}"
7 NAME="${1?Must specify target name}"
8 TARGET="${TOP}/${NAME}"
9 echo "Checking $TARGET"
10 if [ -f $TARGET ]
11 then
12 echo "TARGET $TARGET already exists"
13 exit 1
14 fi
15 echo "Checking $SRC"
16 if [ ! -f $SRC ]
17 then
18 echo "SOURCE $SRC not found in $TOP"
19 exit 1
20 fi
21 echo "Checking address for $NAME"
22 ADDRESS=$(host $NAME | grep has | awk '{print $4}')
23 if [ "$ADDRESS" == "" ]
24 then
25 echo "$NAME not found"
26 exit 1
27 fi
28 echo "Create $TARGET"
29 qemu-img create -f qcow2 -b $SRC $TARGET
30 echo "load nbd"
31 modprobe nbd max_part=8
32 echo "connect $TARGET"
33 qemu-nbd --connect=/dev/nbd0 $TARGET
34 echo "create /tmp/mnt"
35 mkdir -p /tmp/mnt
36 echo "partprobe /dev/nbd0"
37 partprobe /dev/nbd0
38 echo "mount /tmp/mnt"
39 mount /dev/nbd0p1 /tmp/mnt
40 # create the Ubuntu interfaces file
41 echo "update interfaces"
42 echo "
43 # This file describes the network interfaces available on your system
44 # and how to activate them. For more information, see interfaces(5).
45 source /etc/network/interfaces.d/*
46 # The loopback network interface
47 auto lo
48 iface lo inet loopback
49 # The primary network interface
50 auto ens3
51 iface ens3 inet static
52 address $ADDRESS
53 netmask 255.255.255.0
54 network 10.0.0.0
55 broadcast 10.0.0.255
56 gateway 10.0.0.1
57 # dns-* options are implemented by the resolvconf package, if installed
58 dns-nameservers 8.8.8.8
59 dns-search demo.local
60 " > /tmp/mnt/etc/network/interfaces
61 echo "update hostname"
62 echo $NAME > /tmp/mnt/etc/hostname
63 echo "release mount /tmp/mnt"
64 umount /tmp/mnt
65 echo "release /dev/nbd0"
66 qemu-nbd -d /dev/nbd0
67 echo "rmmod nbd"
68 rmmod nbd
69 # create the instance
70 virt-install --name $NAME --disk /var/lib/libvirt/images/$NAME --network bridge=br0 --memory 1024 --vcpu 1 --import --noautoconsole 2>/dev/null
71 exit 0
>>>>> postinstall
1 #! /bin/bash
2 mkdir /root/.ssh
3 chown -R root:root /root/.ssh
4 cd /root/.ssh
5 echo "
6 ssh-rsa ********************************* PUBLIC KEY **************************************************
7 " > authorized_keys
8 chmod -R 0700 .
9 cd
10 echo "root:password" | chpasswd
11 sed -i 's/^\(PermitRootLogin\).*$/\1 yes/g' /etc/ssh/sshd_config
12 echo "all done with post installation..."
13 exit 0
>>>>> preseed.cfg
1 # Set hostname
2 d-i netcfg/get_hostname string ubuntu
3 # Create new user
4 d-i passwd/user-fullname string Ubuntu User
5 d-i passwd/username string ubuntu
6 d-i passwd/user-password-crypted password $1$1AniiGAw$ZsUcBK840ZrkmoVIvTneP1
7 # Don't encrypt the home directory
8 d-i user-setup/encrypt-home boolean false
9 # Set timezone
10 d-i time/zone string America/New_York
11 # Partitioning
12 d-i partman-auto/disk string /dev/vda
13 d-i partman-auto/method string regular
14 d-i partman-auto/choose_recipe select atomic
15 d-i partman/confirm boolean true
16 d-i partman/confirm_nooverwrite boolean true
17 d-i partman-partitioning/confirm_write_new_label boolean true
18 d-i partman/choose_partition select finish
19 d-i partman/confirm boolean true
20 d-i partman/confirm_nooverwrite boolean true
21 # Mirror
22 d-i mirror/country string manual
23 d-i mirror/http/hostname string mirror.math.princeton.edu
24 d-i mirror/http/directory string /ubuntu
25 d-i mirror/http/proxy string
26 # Upgrade packages after debootstrap
27 d-i pkgsel/upgrade select full-upgrade
28 # Unattended security upgrades
29 d-i pkgsel/update-policy select unattended-upgrades
30 # Install OpenSSH server
31 tasksel tasksel/first multiselect openssh-server
32 # Install acpid ansible curl puppet ntp
33 d-i pkgsel/include string acpid ansible curl puppet ntp
34 # Install GRUB2
35 d-i grub-installer/only_debian boolean true
36 # Avoid that last message about the install being complete
37 d-i finish-install/reboot_in_progress note
38 d-i debian-installer/exit/poweroff boolean true
39
40 # Don't install kernel headers.
41 d-i base-installer/kernel/headers boolean false
42 # Don't even install the standard task.
43 tasksel tasksel/skip-tasks string standard
44 # Only install basic language packs. Let tasksel ask about tasks.
45 d-i pkgsel/language-pack-patterns string
46 # No language support packages.
47 d-i pkgsel/install-language-support boolean false
48 # Only ask the UTC question if there are other operating systems installed.
49 d-i clock-setup/utc-auto boolean true
50 # Verbose output and no boot splash screen.
51 d-i debian-installer/quiet boolean false
52 d-i debian-installer/splash boolean false
53 # Install the debconf oem-config frontend (if in OEM mode).
54 #d-i oem-config-udeb/frontend string debconf
55 # Wait for two seconds in grub
56 d-i grub-installer/timeout string 2
57 # Add the network and tasks oem-config steps by default.
58 # configure static network
59 # Static network configuration.
60 # IPv4 example
61 # disable auto network config
62 d-i netcfg/disable_autoconfig boolean true
63 d-i netcfg/get_ipaddress string 10.0.0.141
64 d-i netcfg/get_netmask string 255.255.255.0
65 d-i netcfg/get_gateway string 10.0.0.1
66 d-i netcfg/get_nameservers string 8.8.8.8
67 d-i netcfg/get_domain string tsand.org
68 d-i netcfg/confirm_static boolean true
69 netcfg netcfg/get_hostname string ubuntu1
70 netcfg netcfg/get_domain string demo.local
71 d-i netcfg/hostname string ubuntu1
72 #oem-config oem-config/steps multiselect language, timezone, keyboard, user, network, tasks
73 d-i base-installer/kernel/altmeta string lts-raring
74 d-i preseed/late_command string chroot /target sh -c "/usr/bin/curl -o /tmp/postinstall http://10.0.0.6/postinstall && /bin/sh -x /tmp/postinstall"