compressed a bit so things do not get trimmed
[pkg-exppsy/neurodebian.git] / vm / tools / nd_createappliance
1 #!/bin/bash
2 #emacs: -*- mode: shell-script; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil -*- 
3 #ex: set sts=4 ts=4 sw=4 noet:
4
5 # fail early
6 set -eu
7
8 build_dir=$PWD/build
9 dist_dir=$PWD/dist
10 vendor="NeuroDebian"
11 vm_version="7.4.20140423"
12 vm_ostype=Debian
13 vendor_url="http://neuro.debian.net"
14 product_url="${vendor_url}/vm.html"
15 di_port=10100                   # port to start webserver on
16
17 # Generic definitions
18 eula="This virtual appliance contains Free and Open Source Software (FOSS) released under licenses compliant with the Debian Free Software Guidelines (DFSG, see http://www.debian.org/social_contract), such as, GPL, BSD, MIT, etc.  Such software is free to be used or customized for any purpose.
19
20 However, by default this virtual machine is also enabled to install additional software from Debian and NeuroDebian repositories that is distributed under more restrictive licenses (e.g. closed-source, non-commercial, research-only). It is the user's responsibility to adhere to the terms and conditions of any particular software that is installed and used in this virtual machine. Copyright and license details for any installed PACKAGE are available in /usr/share/doc/PACKAGE/copyright inside the virtual machine."
21
22 # The defaults to be modified from cmdline
23 di_cd=
24 # look here for more details about the default IP of the host:
25 # # http://www.virtualbox.org/manual/ch09.html#changenat
26 mirror_host=10.0.0.1:9999
27 di_tz='US/Eastern'
28 di_preseed_in=
29
30 function usage {
31 echo "Usage: $0 [OPTIONS]
32
33 Create ND VirtualBox appliance.
34
35 Options:
36   -p PRESEED_IN path to preesed.cfg.in file for d-i
37   -i ISO        path to debian installation iso file
38   -m MIRROR     debian mirror to use for installation
39   -t TIME_ZONE  time zone of virtual machine
40   -h            Show this help and exit
41 "
42 }
43
44 # Process cmdline
45 while getopts "p:i:" OPTION
46 do
47   case $OPTION in
48       "p") di_preseed_in="$OPTARG";;
49       "i") di_cd="$OPTARG";;
50       "m") mirror_host="$OPTARG";;
51       "t") di_tz="$OPTARG";;
52       "h") exit 1;;
53   esac
54 done
55
56 if [ -z "$di_cd" ] ; then
57     echo "You must specify the iso image (-i)" >&2
58     exit 1
59 fi
60
61 if [ -z "$di_preseed_in" ]; then
62     # deduce release and use corresponding directory here
63     release=$(basename "$di_cd" | cut -d- -f2)
64     di_preseed_in=$(dirname $0)/../d-i/$release/preseed.cfg.in
65     if [ ! -e "$di_preseed_in" ]; then
66         echo "$di_preseed_in is not found. Specify one with -p" >&2
67         exit 2
68     fi
69 fi
70
71 # Figure out our IP address for VM to reach webserver
72 eth=`route | awk '/default/{print $8;}'`
73 di_host=`ip addr show dev $eth | sed -ne '/inet /s, *inet \([0-9.]*\)/.*,\1,gp'`
74
75 # Generate preseed file
76 # yoh could not escape Python here
77 di_preseed=${di_preseed_in%.in}
78 python -c "open('$di_preseed', 'w').write(open('$di_preseed_in').read() % {'DI_HTTP_HOSTNAME': '$di_host:$di_port', 'MIRROR_HTTP_HOSTNAME': '$mirror_host', 'TIME_ZONE': '$di_tz'})"
79
80 # By default 32bit unless installer image has amd64
81 # TODO: might need to make more robust?
82 vm_arch=i386
83 vm_arch_name=" (32bit)"
84 if file $di_cd | grep -q ' amd64 '; then
85     vm_arch=amd64
86     vm_ostype+="_64"
87     vm_arch_name=" (64bit)"
88 fi
89
90 vm_fprefix="${vendor}_${vm_version}_${vm_arch}" # common prefix for files
91 #vm_disk="$build_dir/nd-${vm_version}_${vm_arch}.vdi"
92 vm_disk="$build_dir/${vm_fprefix}.vdi"
93 vm_name="${vendor} ${vm_version} ${vm_arch_name}"
94 # Let's use OVA since 4.x
95 # vm_ovf="${dist_dir}/${vm_fprefix}.ovf"
96 vm_ova="${dist_dir}/${vm_fprefix}.ova"
97 product_name="${vendor} VirtualMachine (${vm_arch})"
98
99 _info() {
100     echo "I: $*"
101 }
102
103 clean_buildvm() {
104 # TODO: remove whenever done
105 VBoxManage storagectl "${vm_name}" \
106     --name "SATA Controller" --remove || :
107 VBoxManage storagectl "${vm_name}" \
108     --name "IDE Controller" --remove || :
109
110 VBoxManage closemedium disk "${vm_disk}" || :
111 VBoxManage unregistervm "${vm_name}" --delete || :
112 rm -f ${vm_disk}
113 }
114
115 clean_buildvm >&/dev/null                   # clean things up
116
117 #exit
118 # Check that no previous VM was left (can happen if previous failures
119 # were "valid")
120 if VBoxManage list vms | grep -q "^\"${vm_name}\".*"; then
121     echo "VM $vm_name still exists -- something is wrong, Can't continue" >&2
122     exit 1
123 fi
124
125 _info Assure build directory
126 mkdir -p $build_dir
127
128 _info Create HardDisk for the VM
129 VBoxManage createhd --filename $vm_disk \
130     --size 40960 --format VDI
131   # documented but not implemented:
132   #  --comment "Drive for NeuroDebian VM installer"
133
134 _info Create VM
135 VBoxManage createvm --name "${vm_name}" --register \
136     --ostype "${vm_ostype}" --basefolder $build_dir
137
138 _info Tune VM
139 VBoxManage modifyvm "${vm_name}" \
140     --audio alsa \
141     --audiocontroller  ac97 \
142     --boot1 disk \
143     --boot2 dvd \
144     --cpus 1 \
145     --ioapic  on \
146     --memory 1048 \
147     --mouse usbtablet \
148     --nic1 nat \
149     --rtcuseutc on \
150     --usb on \
151     --vram 32
152
153 # Add HD controllers
154 VBoxManage storagectl "${vm_name}" \
155     --name "IDE Controller" \
156     --add ide \
157     --controller "PIIX4"
158 VBoxManage storageattach "${vm_name}" \
159     --storagectl "IDE Controller" \
160     --port 0 \
161     --device 0 \
162     --type dvddrive \
163     --medium  $di_cd
164
165 VBoxManage storagectl "${vm_name}" \
166     --name "SATA Controller" \
167     --add sata \
168     --controller "IntelAHCI"
169
170 VBoxManage storageattach  "${vm_name}" \
171     --storagectl "SATA Controller" \
172     --port 0 \
173     --device 0 \
174     --type hdd \
175     --medium "${vm_disk}"
176
177 VBoxManage showvminfo  "${vm_name}"
178
179 _info "Run Debian Installer"
180 # When boot menu appears you will have to
181 # press Esc
182 # type  auto url=$di_host
183 # press Enter"
184
185 # start local web server to serve preseed file
186 builtin cd $(dirname ${di_preseed})
187 python -m SimpleHTTPServer ${di_port} >&/dev/null &
188 di_pid=$!
189 builtin cd -
190
191
192
193 VBoxManage startvm "${vm_name}"
194
195 # TODO: see if we could just use virtinst (virt-install tool) to run d-i
196 #       with pre-seeding without this hackery.  See
197 #       http://honk.sigxcpu.org/con/Preseeding_Debian_virtual_machines_with_virt_install.html
198 #       for an example
199 sleep 5                         # give some time to make sure we get to menu
200 # Send our sequence -- cruel way
201 #VBoxManage controlvm "${vm_name}" keyboardputscancode \
202 #    01 81 \
203 #    1e 9e 16 96 14 94 18 98 39 b9 16 96 13 93 26 a6 0d 8d 23 a3 15 95 20 a0 13 93 1e 9e \
204 #    1c 9c # ESCAPE, auto url=hydra, ENTER
205 echo "typeGuest \"${vm_name}\" \"&ESC;Wauto url=${di_host}|;${di_port}/$(basename ${di_preseed})&ENTER;\"" | /usr/lib/virtualbox/vboxshell.py
206
207 # wait for it to finish! -- found no cleaner way :-/
208 sleep 10
209 while VBoxManage showvminfo "${vm_name}" | grep -q running; do
210     sleep 5
211 done
212
213 # kill the web server
214 kill ${di_pid} || echo "Could not kill the webserver"
215
216 _info Compacting VDI
217 sudo ./nd_compactvdi "${vm_disk}"
218
219 _info Exporting the appliance
220 if [ -e "$vm_ova" ]; then
221     vm_ova_old=$vm_ova.`date +"20%y%m%d%H%M"`
222     _info Previous OVA image exists, renaming it to $vm_ova_old
223     mv "$vm_ova" "$vm_ova_old"
224 fi
225 VBoxManage export "${vm_name}" -o "$vm_ova" \
226         --vsys 0 \
227         --product "${product_name}" \
228         --producturl "${product_url}" \
229         --vendor "${vendor}" \
230         --vendorurl "http://neuro.debian.net" \
231         --version "$vm_version" \
232         --eula "$eula"
233
234 _info Cleaning after ourselves
235 clean_buildvm
236
237 _info Testing import of the appliance
238 VBoxManage import "$vm_ova" --vsys 0 --eula accept
239
240 _info Starting imported machine
241 VBoxManage startvm "${vm_name}"