change script to allow specification of memory allocation
[leap_cloudadmin.git] / create-guest-with-cloudinit
1 #!/bin/bash 
2
3 # depends on following packages:
4 # apt-get install virtinst libvirt-bin dosfstools mtools kvm xmlstarlet
5
6 # For resizing the root partition we tried two ways: 
7
8 # sfdisk 
9 # ------
10 # For sfdisk we need util-linux >= 2.17.2-3 (debian wheezy, ubuntu oneiric), 
11 # because of the sfdisk-feature which lets us script the growing of the root partition.
12 # see https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/686124
13 # apt-get install -t wheezy util-linux
14
15 # parted
16 # ------
17 # seems to be more robust than sfdisk, so we use that approach
18 # unfortunatly, there's no way to resize a partition with parted >= 2.4
19 # deleting and recreating is the only way, which leaves us with an 
20 # dirty workaround, giving the beginning of the root partition in sectors
21 # with the variable $ROOT_PARTITION_BEGINNING
22
23
24 # defaults, configurable in config
25 VG='vg01'
26 ETC='/etc/libvirt/local/cloudinit'
27 CONFIG="$ETC/cloudinit.cfg"
28 VARDIR='/var/lib/libvirt/cloudinit'
29 SCRIPTDIR='/usr/local/bin/leap_cloudadmin'
30 KVM_URI='qemu:///system'
31 SEED='cloudinit_seed.img'
32
33 BASEIMAGE='leap-baseimage'
34 SWAPUUID='3a79d708-2a74-4344-a953-15e955dbdae7'
35
36 # Defaults for leap-baseimage, change if you 
37 # have a different disk layout 
38 ROOT_PARTITION_NR='2'
39 ROOT_PARTITION_BEGINNING='4096s'
40
41 # unconfigurable variables
42 MIN_ROOTSIZE=2
43 DEFAULT_SWAPSIZE=512
44 DEFAULT_MEM=512
45 rootsize=$MIN_ROOTSIZE
46 swapsize=$DEFAULT_SWAPSIZE
47 memsize=$DEFAULT_MEM
48
49
50 # overwrite defaults
51 [ -e $CONFIG ] && . $CONFIG
52
53 [ -z "$LC_ALL" ] && LC_ALL="en_US.UTF-8"
54
55
56 fail() { [ $# -eq 0 ] || echo "$@"; exit 1; }
57 bad_usage() { usage 1>&2; [ $# -eq 0 ] || fail "$@"; exit 1; }
58
59 usage() {
60        cat <<EOF
61
62 Usage: ${0##*/} -r <gb> -s <mb> -n guest_name
63
64   Creates a new guest VM using cloud-init to utilize nocloud.
65   Uses $ETC/<guest_name>.cfg as meta- und user-data file  
66
67   options:
68     -h             show usage
69     -r size        root size in GB. Defaults to minimal value of $MIN_ROOTSIZE GB.
70     -s size        swap size in MB. Defaults to $DEFAULT_SWAPSIZE MB.
71     -m size        memory size in kibibytes. Defaults to $DEFAULT_MEM KiB.
72     -n name        guestname
73 EOF
74 }
75
76
77 # Parse cmdline options
78
79 while getopts "hr:s:n:m:" OPTION
80 do
81   #echo $OPTION $OPTARG
82   case $OPTION in
83      h) usage
84         exit 0;;
85      r) rootsize=$OPTARG;; 
86      s) swapsize=$OPTARG;;
87      n) vmname=$OPTARG;; 
88      m) memsize=$OPTARG;; 
89    esac
90 done
91
92 [ -z $vmname  ] && bad_usage "must provide guest name"
93 [ $# -gt 8 ] && bad_usage "too many arguments"
94 [ $rootsize -lt $MIN_ROOTSIZE ] && bad_usage "Minimal root size is $MIN_ROOTSIZE GB !"
95
96
97 cfg="$ETC/$vmname.cfg"
98 rootdev="/dev/$VG/${vmname}-root"
99 swapdev="/dev/$VG/${vmname}-swap"
100
101 # requirements
102 echo "mtools_skip_check=1">~/.mtoolsrc
103 [ -e $VARDIR ] || ( mkdir $VARDIR ; chown libvirt-qemu $VARDIR )
104
105 [ -e $rootdev ] && fail "$rootdev exists - please delete it or choose another guest name"
106 [ -e $swapdev ] && fail "$swapdev exists - please delete it or choose another guest name"
107 [ -e $cfg ] ||  fail "please provide config file in $cfg"
108
109 echo
110 echo "Creating guest VM $vmname:"
111 echo "Root size: $rootsize GB, using $rootdev"
112 echo "Swap size: $swapsize MB, using $swapdev"
113 echo "Memory size: $memsize KiB"
114 echo ""
115 echo "using $cfg for cloud-init"
116 echo
117 echo "OK ? <Ctrl-C> to abort, <enter> to resume."
118 read enter
119
120 # is a VM with the same name defined ?
121 virsh dominfo $vmname > /dev/null 2>&1
122 if [ $? -eq 0 ]; then fail "Domain $vmname is defined in libvirt. Please undefine first."; fi
123
124 # create root and swap disk
125 lvcreate -L ${rootsize}g -n ${vmname}-root $VG
126 lvcreate -L ${swapsize}m -n ${vmname}-swap $VG
127 mkswap  -U $SWAPUUID $swapdev
128
129 sleep 4 
130 virt-clone --connect $KVM_URI -o $BASEIMAGE -n $vmname -f $rootdev  --force
131
132 # Set memory
133 tmpxml=`mktemp`
134 virsh dumpxml ${vmname} > $tmpxml
135 xmlstarlet edit -L -u "/domain[@type='kvm']/memory[@unit='KiB']" -v "${memsize}" $tmpxml
136 virsh define $tmpxml
137 rm -f $tmpxml
138
139 # resize root partition
140
141 # echo ",+," | sfdisk -q -N2  /dev/$VG/$vmname > /dev/null 2>&1
142 # sfdisk is unreliable for us and doesn't work on a new kvm host
143 parted $rootdev --script -- rm $ROOT_PARTITION_NR
144 parted $rootdev --script -- mkpart primary $ROOT_PARTITION_BEGINNING -1s
145
146 # create cloudinit seed disk 
147 csplit -q --prefix "$VARDIR/$vmname" $cfg '/#cloud-config/'
148 metadata="$VARDIR/${vmname}00"
149 userdata="$VARDIR/${vmname}01"
150 $SCRIPTDIR/libvirt-make-seed-disk $VARDIR/$vmname-$SEED $userdata $metadata
151
152
153 echo
154 echo "Cloudinit-seeddisk is at $VARDIR/$vmname-$SEED, attaching after booting"
155 echo
156 echo "Finished creating guest $vmname. Enjoy."
157 echo
158 echo "Press <return> to start the new guest."
159 read bogus
160
161 echo
162 echo 'Starting new guest, attaching to console. Exit with Ctrl+]'
163 echo
164
165 virsh start $vmname
166 sleep 2 
167
168 # create seed- and swapdisk definition and attach them
169 virsh attach-disk $vmname --source $swapdev --target vdb  --config
170 virsh attach-disk $vmname --source $VARDIR/$vmname-$SEED --target vdc --sourcetype file --type disk --driver qemu --subdriver raw --config
171 virsh setmem $vmname $memsize --live --config
172
173 virsh console $vmname 
174
175