Revision d51a95a8

b/host/snf-image-update-helper.in
1
#!/bin/bash
2

  
3
set -e
4
set -x
5

  
6
. @osdir@/common.sh
7

  
8
CACHE_FILE="$HELPER_DIR/cache.tar"
9
ARCH=amd64
10
EXTRA_PKGS="linux-image-amd64,e2fsprogs,ntfs-3g,xmlstarlet"
11

  
12
helper_img=$(mktemp $HELPER_DIR/image.XXXXXXXX)
13

  
14
dd if=/dev/zero of=$helper_img bs=1k count=400000
15
blockdev=$(losetup -sf $helper_img)
16
CLEANUP+=("losetup -d $blockdev")
17

  
18
format_disk0 $blockdev "extdump"
19

  
20
root_dev=$(map_disk0 $blockdev)-1
21
CLEANUP+=("unmap_disk0 $blockdev")
22

  
23
mkfs.ext3 $root_dev
24

  
25
TMPDIR=$(mktemp -d)
26
CLEANUP+=("rmdir $TMPDIR")
27

  
28
mount $root_dev $TMPDIR
29
CLEANUP+=("umount $root_dev")
30

  
31
if [  -f "$CACHE_FILE" ]; then
32
    tar xf "$CACHE_FILE" -C $TMPDIR
33
else
34
    debootstrap --arch "$ARCH" --include $EXTRA_PKGS --variant=minbase \
35
	    squeeze $TMPDIR
36

  
37
    # remove the downloaded debs, as they are no longer needed
38
    find "$TMPDIR/var/cache/apt/archives" -type f -name '*.deb' -print0 | \
39
        xargs -r0 rm -f
40

  
41
    TMP_CACHE=$(mktemp "${CACHE_FILE}.XXXXXX")
42
    tar cf "$TMP_CACHE" -C $TMPDIR .
43
    mv -f "$TMP_CACHE" "$CACHE_FILE"
44
fi
45

  
46
echo helper > $TMPDIR/etc/hostname
47

  
48
cat > $TMPDIR/etc/fstab <<EOF
49
# /etc/fstab: static file system information.
50
#
51
# <file system>   <mount point>   <type>  <options>       <dump>  <pass>
52
/dev/sda1         /               ext3    defaults        0       1
53
proc              /proc           proc    defaults        0       0
54
EOF
55

  
56
if [ ! -L "$TMPDIR/vmlinuz" -o ! -L "$TMPDIR/vmlinuz" ]; then
57

  
58
	log_error "vmlinuz or initrd.img link in root is missing."
59
	log_error "I don't know how to find a usable kernel/initrd pair."
60
	exit 1
61
fi
62

  
63
kernel=$(readlink -en $TMPDIR/vmlinuz)
64
initrd=$(readlink -en $TMPDIR/initrd.img)
65

  
66
echo "Moving $(basename $kernel) and $(basename $initrd) to $HELPER_DIR"
67
mv $kernel $initrd $HELPER_DIR
68

  
69
kernel=$(basename $kernel)
70
initrd=$(basename $initrd)
71

  
72
(cd $HELPER_DIR; ln -fs $kernel kernel; ln -fs $initrd initrd)
73

  
74
rm $TMPDIR/vmlinuz $TMPDIR/initrd.img
75

  
76
cleanup
77

  
78
mv $helper_img $HELPER_DIR/image
79

  
80
trap - EXIT
81

  
82
exit 0
83

  
84
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
b/snf-image-host/Makefile.am
15 15
dist_os_DATA = ${srcdir}/ganeti_api_version ${srcdir}/parameters.list \
16 16
               ${srcdir}/variants.list
17 17

  
18
dist_bin_SCRIPTS = snf-image-update-helper
19

  
18 20
os_DATA = common.sh
19 21

  
20 22
edit = sed \
......
23 25
	   -e 's|@osdir[@]|$(osdir)|g' \
24 26
	   -e 's|@osname[@]|$(osname)|g' \
25 27
	   -e 's|@defaultdir[@]|$(defaultdir)|g' \
26
	   -e 's|@HELPER[@]|$(HELPER)|g' \
28
	   -e 's|@HELPER_DIR[@]|$(HELPER_DIR)|g' \
29
	   -e 's|@HELPER_IMG[@]|$(HELPER_IMG)|g' \
27 30
	   -e 's|@HELPER_KERNEL[@]|$(HELPER_KERNEL)|g' \
28 31
	   -e 's|@HELPER_INITRD[@]|$(HELPER_INITRD)|g' \
32
	   -e 's|@HELPER_PKG[@]|$(HELPER_PKG)|g' \
29 33
	   -e 's|@AWK[@]|$(AWK)|g' \
30 34
	   -e 's|@MKDIR_P[@]|$(MKDIR_P)|g' \
31 35
	   -e 's|@LOSETUP[@]|$(LOSETUP)|g' \
......
35 39
	   -e 's|@progress_monitor_support[@]|$(progress_monitor_support)|g' \
36 40
	   -e 's|@PROGRESS_MONITOR[@]|$(PROGRESS_MONITOR)|g'
37 41

  
38
common.sh: Makefile
42
%:%.in Makefile
39 43
	rm -f $@ $@.tmp
40 44
	srcdir=''; \
41 45
		   test -f ./$@.in || srcdir=$(srcdir)/; \
......
48 52
	touch "$(DESTDIR)$(variantsdir)/default.conf"
49 53
	
50 54

  
51
CLEANFILES = $(os_DATA)
55
CLEANFILES = $(os_DATA) $(dist_bin_SCRIPTS)
b/snf-image-host/common.sh.in
183 183
    umount $target
184 184
}
185 185

  
186
# this one is only to be called by create
187
ganeti_os_main() {
188
    if [ -z "$OS_API_VERSION" -o "$OS_API_VERSION" = "5" ]; then
189
        OS_API_VERSION=5
190
        GETOPT_RESULT=`getopt -o o:n:i:b:s: -n '$0' -- "$@"`
191
        if [ $? != 0 ] ; then log_error "Terminating..."; exit 1 ; fi
192
        get_api5_arguments $GETOPT_RESULT
193
    elif [ "$OS_API_VERSION" = "10" -o "$OS_API_VERSION" = "15" ]; then
194
        get_api10_arguments
195
    elif [ "$OS_API_VERSION" = "20" ]; then
196
        get_api20_arguments
197
        IMAGE_NAME=$IMG_ID
198
        IMAGE_TYPE=$IMG_FORMAT
199
    else
200
        log_error "Unknown OS API VERSION $OS_API_VERSION"
201
        exit 1
202
    fi
203
    
204
    if [ -n "$OS_VARIANT" ]; then
205
        if [ ! -d "$VARIANTS_DIR" ]; then
206
            log_error "OS Variants directory $VARIANTS_DIR doesn't exist"
207
            exit 1
208
        fi
209
        VARIANT_CONFIG="$VARIANTS_DIR/$OS_VARIANT.conf"
210
        if [ -f "$VARIANT_CONFIG" ]; then
211
            . "$VARIANT_CONFIG"
212
        else
213
            if grep -qxF "$OS_VARIANT" variants.list; then
214
                log_error "ERROR: instance-image configuration error"
215
                log_error "  Published variant $OS_VARIANT is missing its config" \
216
                          "file"
217
                log_error "  Please create $VARIANT_CONFIG or unpublish the variant"
218
                log_error "  (by removing $OS_VARIANT from variants.list)"
219
            else
220
                log_error "Unofficial variant $OS_VARIANT is unsupported"
221
                log_error "Most probably this is a user error, forcing a wrong name"
222
                log_error "To support this variant please create file" \
223
                            "$VARIANT_CONFIG"
224
            fi
225
            exit 1
226
        fi
227
    fi
228

  
229
}
230

  
186 231
cleanup() {
232
# if something fails here, it souldn't call cleanup again...
233
    trap - EXIT
187 234
    if [ ${#CLEANUP[*]} -gt 0 ]; then
188 235
        LAST_ELEMENT=$((${#CLEANUP[*]}-1))
189 236
        REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
190 237
        for i in $REVERSE_INDEXES; do
191
            ${CLEANUP[$i]}
238
            # If something fails here, it's better to retry it for a few times
239
            # before we give up with an error. This is needed for kpartx when
240
            # dealing with ntfs partitions mounted through fuse. umount is not
241
            # synchronous and may return while the partition is still busy. A
242
            # premature attempt to delete partition mappings through kpartx on a
243
            # device that hosts previously mounted ntfs partition may fail with
244
            # an  `device-mapper: remove ioctl failed: Device or resource busy'
245
            # error. A sensible workaround for this is to wait for a while and
246
            # then try again.
247
            local cmd=${CLEANUP[$i]}
248
            $cmd || for interval in 0.25 0.5 1 2 4; do
249
            echo "Command $cmd failed!"
250
            echo "I'll wait for $interval secs and will retry..."
251
            sleep $interval
252
            $cmd && break
192 253
        done
193
    fi
254
        test $? -eq 1 && { echo "Giving Up..."; exit 1; }
255
    done
256
  fi
194 257
}
195 258

  
196 259
trap cleanup EXIT
......
203 266
: ${ARCH:="x86_64"}
204 267
: ${VARIANTS_DIR:="@sysconfdir@/ganeti/snf-image/variants"}
205 268
: ${IMAGE_DIR:="@localstatedir@/lib/snf-image"}
206
: ${HELPER:="@HELPER@"}
269
: ${HELPER_DIR:="@HELPER_DIR@"}
270
: ${HELPER_IMG:="@HELPER_IMG@"}
207 271
: ${HELPER_KERNEL:="@HELPER_KERNEL@"}
208 272
: ${HELPER_INITRD:="@HELPER_INITRD@"}
209 273
: ${HELPER_SOFT_TIMEOUT=120}
210 274
: ${HELPER_HARD_TIMEOUT=15}
211
: ${HELPER_USR="nobody"}
275
: ${HELPER_USER="nobody"}
212 276

  
213 277
SCRIPT_NAME=$(basename $0)
214 278

  
......
229 293
    exit 1
230 294
fi
231 295

  
232

  
233
if [ -z "$OS_API_VERSION" -o "$OS_API_VERSION" = "5" ]; then
234
    OS_API_VERSION=5
235
    GETOPT_RESULT=`getopt -o o:n:i:b:s: -n '$0' -- "$@"`
236
    if [ $? != 0 ] ; then log_error "Terminating..."; exit 1 ; fi
237
    get_api5_arguments $GETOPT_RESULT
238
elif [ "$OS_API_VERSION" = "10" -o "$OS_API_VERSION" = "15" ]; then
239
    get_api10_arguments
240
elif [ "$OS_API_VERSION" = "20" ]; then
241
    get_api20_arguments
242
    IMAGE_NAME=$IMG_ID
243
    IMAGE_TYPE=$IMG_FORMAT
244
else
245
    log_error "Unknown OS API VERSION $OS_API_VERSION"
246
    exit 1
247
fi
248

  
249
if [ -n "$OS_VARIANT" ]; then
250
    if [ ! -d "$VARIANTS_DIR" ]; then
251
        log_error "OS Variants directory $VARIANTS_DIR doesn't exist"
252
        exit 1
253
    fi
254
    VARIANT_CONFIG="$VARIANTS_DIR/$OS_VARIANT.conf"
255
    if [ -f "$VARIANT_CONFIG" ]; then
256
        . "$VARIANT_CONFIG"
257
    else
258
        if grep -qxF "$OS_VARIANT" variants.list; then
259
            log_error "ERROR: instance-image configuration error"
260
            log_error "  Published variant $OS_VARIANT is missing its config" \
261
                      "file"
262
            log_error "  Please create $VARIANT_CONFIG or unpublish the variant"
263
            log_error "  (by removing $OS_VARIANT from variants.list)"
264
        else
265
            log_error "Unofficial variant $OS_VARIANT is unsupported"
266
            log_error "Most probably this is a user error, forcing a wrong name"
267
            log_error "To support this variant please create file" \
268
                        "$VARIANT_CONFIG"
269
        fi
270
        exit 1
271
    fi
272
fi
273

  
274 296
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
b/snf-image-host/configure.ac
25 25

  
26 26
AM_CONDITIONAL(PROGMONSUPPORT, [test -n "$PROGRESS_MONITOR"])
27 27

  
28
# --with-helper..
29
AC_ARG_WITH([helper],
30
    [AS_HELP_STRING([--with-helper=IMG_PATH],
31
        [Path to helper VM image [LOCALSTATEDIR/lib/snf-image/helper.img]]
28
# --with-helper-dir
29
AC_ARG_WITH([helper-dir],
30
    [AS_HELP_STRING([--with-helper-dir=DIR],
31
        [top-level directory to host the helper VM
32
        [LOCALSTATEDIR/lib/snf-image/helper]]
32 33
    )],
33
    [helper="$withval"],
34
    [helper="$localstatedir/lib/snf-image/helper.img"])
35
AC_SUBST(HELPER, $helper)
34
    [helper_dir="$withval"],
35
    [helper_dir="$localstatedir/lib/snf-image/helper"])
36
AC_SUBST(HELPER_DIR, $helper_dir)
37

  
38
# --with-helper-img
39
AC_ARG_WITH([helper-img],
40
    [AS_HELP_STRING([--with-helper-img=IMG_PATH],
41
        [Path to helper VM image [HELPERDIR/image]]
42
    )],
43
    [helper_img="$withval"],
44
    [helper_img="$helper_dir/image"])
45
AC_SUBST(HELPER_IMG, $helper_img)
36 46

  
37 47
# --with-helper-kernel
38
AC_ARG_WITH([helper_kernel],
48
AC_ARG_WITH([helper-kernel],
39 49
    [AS_HELP_STRING([--with-helper-kernel=KERNEL_PATH],
40
        [Path to a kernel to use to boot the helper VM image 
41
        [LOCALSTATEDIR/lib/snf-image/helper-kernel]]
50
        [Path to the helper VM kernel [HELPERDIR/kernel]]
42 51
    )],
43 52
    [helper_ernel="$withval"],
44
    [helper_kernel="$localstatedir/lib/snf-image/helper-kernel"])
53
    [helper_kernel="$helper_dir/kernel"])
45 54
AC_SUBST(HELPER_KERNEL, ${helper_kernel})
46 55

  
47 56
# --with-helper-initrd..
48
AC_ARG_WITH([helper_initrd],
57
AC_ARG_WITH([helper-initrd],
49 58
    [AS_HELP_STRING([--with-helper-initrd=INITRD_PATH],
50
        [Path to an initial ramdisk to use to boot the helper VM image
51
        [LOCALSTATEDIR/lib/snf-image/helper-initrd]]
59
        [Path to the helper VM initial ramdist [HELPERDIR/initrd]]
52 60
    )],
53 61
    [helper_initrd="$withval"],
54
    [helper_initrd="$localstatedir/lib/snf-image/helper-initrd"])
62
    [helper_initrd="$helper_dir/initrd"])
55 63
AC_SUBST(HELPER_INITRD, ${helper_initrd})
56 64

  
57 65
# --with-os-dir=...
b/snf-image-host/create
33 33

  
34 34
. common.sh
35 35

  
36
ganeti_os_main
37

  
36 38
case "$IMAGE_TYPE" in
37 39
    extdump)
38 40
	IMAGE_FILE="${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}.extdump";;
......
94 96
CLEANUP+=("rm -f $result_file")
95 97

  
96 98
$TIMELIMIT -t $HELPER_SOFT_TIMEOUT -T $HELPER_HARD_TIMEOUT \
97
    kvm -runas $HELPER_USR -drive file=${HELPER},snapshot=on \
99
    kvm -runas $HELPER_USER -drive file=${HELPER_IMG},snapshot=on \
98 100
    -drive file=$root_dev,format=raw,if=virtio,cache=none \
99 101
    -boot c -serial stdio -serial file:$result_file -fda $floppy \
100 102
    -vga none -nographic -parallel none -monitor null -nographic \
b/snf-image-host/defaults
17 17
# IMAGE_DEBUG: turn on debugging output for the scripts
18 18
# IMAGE_DEBUG=0
19 19

  
20
# HELPER: path to the image file of the helper vm
21
# HELPER="var/lib/snf-image/helper.img"
20
# HELPER_DIR: Directory hosting the helper files
21
# HELPER_DIR: /var/lib/snf-image/helper/
22 22

  
23
# HELPER_KERNEL: path to the kernel, kvm should use to run the helper image
24
# HELPER_KERNEL="/var/lib/snf-image/helper-kernel"
23
# HELPER_IMG: Path to the helper VM image
24
# HELPER_IMG="$(HELPER_DIR)/image"
25 25

  
26
# HELPER_INITRD: path to the init ramdisk the helper vm should use.
27
# HELPER_INITRD="/var/lib/snf-image/helper-initrd"
26
# HELPER_KERNEL: Path to the helper VM kernel
27
# HELPER_KERNEL="$(HELPER_DIR)/kernel"
28

  
29
# HELPER_PKG: Path to the snf-image-helper package
30
# HELPER_PKG="$(HELPER_DIR)/snf-image-helper.deb"
31

  
32
# HELPER_INITRD: Path to the helper VM initial ramdisk
33
# HELPER_INITRD="$(HELPER_DIR)/initrd"
28 34

  
29 35
# HELPER_TIMOUT: Soft and hard timeout limits for helper instance.
30 36
# Helper instance will be terminated after a given time if it hasn't exited by
......
36 42
# HELPER_USR: For security reasons, the helper vm is not adviced to to run as
37 43
# root. It should drop privileges just before the guest execution starts. The
38 44
# user the helper vm should run as is specifies by HELPER_USR variable.
39
# HELPER_USR="nobody"
45
# HELPER_USER="nobody"
40 46

  
41 47
# Paths for needed programs. Uncommend and change the variables below, if you
42 48
# don't want to use the default one.

Also available in: Unified diff