Update Changelog and version for 0.12
[snf-image] / snf-image-host / snf-image-create-helper.in
1 #!/bin/bash
2
3 # Copyright (C) 2011 GRNET S.A.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19
20 set -e
21 set -o pipefail
22 set -o errtrace
23
24 . @osdir@/common.sh
25
26 usage() {
27     local rc="$1"
28
29     cat <<EOF
30
31 Usage: $0 [options]
32
33 This script runs multistrap and creates a small Debian image populated with
34 the snf-image-helper package. This image is needed for ganeti's \`snf-image'
35 guest OS type to work.
36
37 OPTIONS:
38     -d DIRECTORY
39         Use this directory to host the created files, instead of the default
40         [default: $HELPER_DIR]
41
42     -h  Print this message
43
44     -p PACKAGE
45         Install this deb package in the helper image, instead of the default
46
47     -y  Assume Yes to all queries and do not prompt
48
49 EOF
50
51     exit "$rc"
52 }
53
54 while getopts "d:hp:y" opt; do
55     case $opt in
56         d) HELPER_DIR="$OPTARG"
57             ;;
58         h) usage 0
59             ;;
60         p) HELPER_PKG="$OPTARG"
61             ;;
62         y) NO_PROMPT="yes"
63             ;;
64         ?) log_error "Use \`-h' for help"; exit 1
65             ;;
66     esac
67 done
68
69 echo
70 echo "This is the helper image creation script for snf-image."
71 echo "If you don't know what to do, use \`-h'."
72 echo
73
74 if [ ! -d "$HELPER_DIR" -o ! -w "$HELPER_DIR" ]; then
75     log_error "Helper directory \`$HELPER_DIR' does not exist or the script" \
76     "has no write permission on it."
77     exit 1
78 fi
79
80 if [ ! -e "$MULTISTRAP_CONFIG" ]; then
81     log_error "Multistrap configuration file: \`$MULTISTRAP_CONFIG' does not" \
82     "exist or is not readable by the script."
83     exit 1
84 fi
85
86 cat >&1 <<EOF
87 This program will overwrite the following files if present:
88   \`$HELPER_DIR/initrd'
89   \`$HELPER_DIR/kernel'
90   \`$HELPER_DIR/image'
91   \`$HELPER_DIR/packages'
92 EOF
93
94 while [[ 1 ]]; do
95     echo -n "Do you want to continue [y/N]? "
96     if [ "x$NO_PROMPT" = "xyes" ]; then
97         echo "y";
98         break;
99     fi
100
101     read answer
102     [ "$(echo -n "$answer" | tr [A-Z] [a-z])" = "y" ] && break
103     if [ -z "$answer" -o "$(echo -n "$answer" | tr [A-Z] [a-z])" = "n" ]; then
104         log_error "Abort."
105         exit 1
106     fi
107 done
108
109 rm -f "$HELPER_DIR/initrd" "$HELPER_DIR/kernel" "$HELPER_DIR/image"
110
111 echo -n "Allocating space for helper disk image..."
112 helper_img=$(mktemp "$HELPER_DIR/image.XXXXXX")
113 add_cleanup rm -f "$helper_img"
114 dd if=/dev/zero of="$helper_img" bs=1M count="$HELPER_SIZE" &> /dev/null
115 echo "done"
116
117 echo "Creating partitions..."
118 blockdev=$("$LOSETUP" -sf $helper_img)
119 add_cleanup "$LOSETUP" -d "$blockdev"
120
121 sleep 1 # sometimes losetup returns and the device is still busy..
122
123 format_disk0 "$blockdev" "extdump"  2>&1 | sed -e 's/^/CFDISK: /g'
124
125 root_dev=$(map_disk0 "$blockdev")-1
126 add_cleanup unmap_disk0 "$blockdev"
127
128 echo Creating and configuring filesystem...
129 mkfs.ext3 "$root_dev" 2>&1 | sed -e 's/^/MKFS.EXT3: /g'
130 # The helper vm should never do filesystem checks...
131 tune2fs -i 0 -c 0 "$root_dev" 2>&1 | sed -e 's/^/TUNE2FS: /g'
132
133 root_uuid=$(blkid -s UUID -o value "$root_dev")
134
135 target=$(mktemp -d)
136 add_cleanup rmdir "$target"
137
138 mount "$root_dev" "$target"
139 add_cleanup umount "$root_dev"
140
141 do_multistrap "$target"
142
143 # Save the package list
144 chroot "$target" dpkg-query -W  > "$HELPER_DIR/packages"
145
146 echo -n "Configuring the helper image..."
147 echo snf-image-helper > "$target/etc/hostname"
148
149 cat > "$target/etc/fstab" <<EOF
150 # /etc/fstab: static file system information.
151 #
152 # <file system>   <mount point>   <type>  <options>       <dump>  <pass>
153 UUID=$root_uuid         /               ext3    defaults        0       1
154 proc              /proc           proc    defaults        0       0
155 EOF
156
157 # We need this since we mount the helper VM ro
158 ln -sf /proc/mounts "$target/etc/mtab"
159
160 echo "done"
161
162 echo -n "Extracting kernel..."
163 if [ ! -L "$target/vmlinuz" -o ! -L "$target/vmlinuz" ]; then
164     echo -e "\033[1;31mfailed\033[0m"
165     log_error "vmlinuz or initrd.img link in root is missing."
166     log_error "I don't know how to find a usable kernel/initrd pair."
167     exit 1
168 fi
169 echo "done"
170
171 # Make sure extended globbing is enabled
172 shopt -s extglob
173
174 kernel=$(ls "$target"/boot/vmlinuz-+([0-9.])-+([a-z0-9])-amd64)
175 initrd=$(ls "$target"/boot/initrd.img-+([0-9.])-+([a-z0-9])-amd64)
176
177 echo "Moving $(basename "$kernel") and $(basename "$initrd") to \`$HELPER_DIR'"
178 cp "$kernel" "$initrd" "$HELPER_DIR"
179
180 kernel=$(basename "$kernel")
181 initrd=$(basename "$initrd")
182
183 (cd "$HELPER_DIR"; ln -fs "$kernel" kernel; ln -fs "$initrd" initrd)
184
185 pkg_installed=$(grep snf-image-helper "$HELPER_DIR/packages" > /dev/null && echo yes)
186
187 if [ -z "$HELPER_PKG" -a -z "$pkg_installed" ]; then
188     log_error "No helper package was specified and non was found by the apt."
189     exit 1
190 fi
191
192 if [ -r "$HELPER_PKG" ]; then
193     echo "Installing snf-image-helper pkg in the new image..."
194     cp "$HELPER_PKG" "$target/tmp/"
195     pkg_name=$(basename "$HELPER_PKG")
196     add_cleanup rm "$target/tmp/$pkg_name"
197     chroot "$target" dpkg -i "/tmp/$pkg_name" 2>&1 | sed -e 's/^/DPKG: /g'
198
199     # Recreate package list
200     chroot "$target" dpkg-query -W  > "$HELPER_DIR/packages"
201 else
202     echo "snf-image-helper pkg was installed from the apt repository."
203 fi
204
205 helper_version="$(grep ^snf-image-helper[[:space:]] "$HELPER_DIR/packages" | cut -f2)"
206 host_version="$(dpkg-query -W -f "\${Version}\n" snf-image)"
207
208 if [ "$VERSION_CHECK" == yes -a -z "$HELPER_PKG" ]; then
209     if [ "$host_version" != "$helper_version" ]; then
210         log_error "snf-image version (=$host_version) and " \
211             "snf-image-helper version (=$helper_version) don't match."
212         exit 1
213     fi
214 fi
215
216 mv "$helper_img" "$HELPER_DIR/image"
217
218 echo "$SNF_IMAGE_VERSION" > "$HELPER_DIR/version"
219
220 echo "Files in \`$HELPER_DIR' were updated successfully" >&2
221
222 exit 0
223
224 # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :