Initial commit
authorNikos Skalkotos <skalkoto@grnet.gr>
Wed, 21 Sep 2011 12:15:53 +0000 (15:15 +0300)
committerNikos Skalkotos <skalkoto@grnet.gr>
Wed, 21 Sep 2011 12:15:53 +0000 (15:15 +0300)
The project is not workable yet

AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
host/common.sh.in [new file with mode: 0644]
host/create [new file with mode: 0755]
host/ganeti_api_version [new file with mode: 0644]
host/parameters.list [new file with mode: 0644]
host/variants.list [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..8acc940
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Nikos Skalkotos <skalkoto@grnet.gr>
+Constantinos Venetsanopoulos <cven@grnet.gr>
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..68514b3
--- /dev/null
@@ -0,0 +1,43 @@
+if PROGMONSUPPORT
+progress_monitor_support=yes
+else
+progress_monitor_support=no
+endif
+
+osdir=$(OS_DIR)/$(osname)
+defaultdir=$(DEFAULT_DIR)
+variantsdir=$(DESTDIR)${sysconfdir}/ganeti/snf-image/variants
+
+dist_os_SCRIPTS = host/create
+dist_os_DATA = ${srcdir}/host/ganeti_api_version ${srcdir}/host/parameters.list \
+               ${srcdir}/host/variants.list
+
+os_DATA = host/common.sh
+
+edit = sed \
+          -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
+          -e 's|@localstatedir[@]|$(localstatedir)|g' \
+          -e 's|@osdir[@]|$(osdir)|g' \
+          -e 's|@osname[@]|$(osname)|g' \
+          -e 's|@defaultdir[@]|$(defaultdir)|g' \
+          -e 's|@AWK[@]|$(AWK)|g' \
+          -e 's|@MKDIR_P[@]|$(MKDIR_P)|g' \
+          -e 's|@DUMP[@]|$(DUMP)|g' \
+          -e 's|@LOSETUP[@]|$(LOSETUP)|g' \
+          -e 's|@KPARTX[@]|$(KPARTX)|g' \
+          -e 's|@SFDISK[@]|$(SFDISK)|g' \
+          -e 's|@RESIZE2FS[@]|$(RESIZE2FS)|g' \
+          -e 's|@progress_monitor_support[@]|$(progress_monitor_support)|g' \
+          -e 's|@XMLSTARLET[@]|$(XMLSTARLET)|g' \
+          -e 's|@INSTALL_MBR[@]|$(INSTALL_MBR)|g' \
+          -e 's|@PROGRESS_MONITOR[@]|$(PROGRESS_MONITOR)|g'
+
+host/common.sh: Makefile
+       @mkdir_p@ host
+       rm -f $@ $@.tmp
+       srcdir=''; \
+                  test -f ./$@.in || srcdir=$(srcdir)/; \
+                  $(edit) $${srcdir}$@.in >$@.tmp
+       mv $@.tmp $@
+
+CLEANFILES = $(os_DATA)
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..c87d12b
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if test ! -f configure.ac ; then
+  echo "You must execute this script from the top level directory."
+  exit 1
+fi
+
+set -e
+
+rm -rf config.cache autom4te.cache
+mkdir -p autotools
+
+${ACLOCAL:-aclocal} -I autotools
+${AUTOCONF:-autoconf}
+${AUTOMAKE:-automake} --add-missing
+
+rm -rf autom4te.cache
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..d7ed0bc
--- /dev/null
@@ -0,0 +1,77 @@
+AC_PREREQ(2.59)
+AC_INIT(snf-image, 0.1, synnefo@lists.grnet.gr)
+
+AC_CONFIG_AUX_DIR(autotools)
+AC_CONFIG_SRCDIR(configure)
+
+AM_INIT_AUTOMAKE([1.9 foreign tar-ustar -Wall -Wno-portability])
+AM_INIT_AUTOMAKE([subdir-objects])
+
+# --with-progress-monitor
+AC_ARG_WITH([progress-monitor],
+  [AS_HELP_STRING([--with-progress-monitor=PRGRM_PATH],
+    [path to progress-monitor program]
+    [[snf-progress-monitor]])],
+    [if test "$withval" = "yes" ; then
+    AC_PATH_PROG(PROGRESS_MONITOR, [snf-progress-monitor], [], [$PATH:/usr/sbin:/sbin])
+    if test -z "$PROGRESS_MONITOR" ; then
+        AC_MSG_FAILURE([Could not find snf-progress-monitor.])
+    fi
+   else
+       PROGRESS_MONITOR="$withval"
+   fi],
+   [AC_MSG_NOTICE(progress-monitor support not enabled)]
+)
+
+AM_CONDITIONAL(PROGMONSUPPORT, [test -n "$PROGRESS_MONITOR"])
+
+
+# --with-os-dir=...
+AC_ARG_WITH([os-dir],
+    [AS_HELP_STRING([--with-os-dir=DIR],
+        [top-level OS directory under which to install]
+        [ (default is $datadir/ganeti/os)]
+    )],
+    [os_dir="$withval"],
+    [os_dir="$datadir/ganeti/os"])
+AC_SUBST(OS_DIR, $os_dir)
+
+# --with-default-dir=...
+AC_ARG_WITH([default-dir],
+    [AS_HELP_STRING([--with-default-dir=DIR],
+        [top-level default config directory under which to install]
+        [ (default is $sysconfdir/default)]
+    )],
+    [default_dir="$withval"],
+    [default_dir="$sysconfdir/default"])
+AC_SUBST(DEFAULT_DIR, $default_dir)
+
+# Check common programs
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_AWK
+AC_PROG_MKDIR_P
+
+AC_PATH_PROG(LOSETUP, [losetup], [], [$PATH:/usr/sbin:/sbin])
+if test -z "$LOSETUP" ; then
+  AC_MSG_ERROR([losetup not found in $PATH])
+fi
+
+AC_PATH_PROG(KPARTX, [kpartx], [], [$PATH:/usr/sbin:/sbin])
+if test -z "$KPARTX" ; then
+  AC_MSG_ERROR([kpartx not found in $PATH])
+fi
+
+AC_PATH_PROG(SFDISK, [sfdisk], [], [$PATH:/usr/sbin:/sbin])
+if test -z "$SFDISK" ; then
+  AC_MSG_ERROR([sfdisk not found in $PATH])
+fi
+
+AC_CONFIG_FILES([
+    Makefile
+])
+
+AC_OUTPUT
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+
diff --git a/host/common.sh.in b/host/common.sh.in
new file mode 100644 (file)
index 0000000..242df86
--- /dev/null
@@ -0,0 +1,248 @@
+# Copyright 2011 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are
+# those of the authors and should not be interpreted as representing official
+# policies, either expressed or implied, of GRNET S.A.
+
+AWK="awk"
+KPARTX="kpartx"
+LOSETUP="losetup"
+SFDISK="sfdisk"
+PROGRESS_MONITOR="snf-progress-monitor"
+
+progress_monitor_support="@progress_monitor_support@"
+
+CLEANUP=( )
+
+log_error() {
+    echo "$@" >&2
+}
+
+get_api5_arguments() {
+    GETOPT_RESULT=$*
+    # Note the quotes around `$TEMP': they are essential!
+    eval set -- "$GETOPT_RESULT"
+    while true; do
+        case "$1" in
+            -i|-n) instance=$2; shift 2;;
+
+            -o) old_name=$2; shift 2;;
+
+            -b) blockdev=$2; shift 2;;
+
+            -s) swapdev=$2; shift 2;;
+
+            --) shift; break;;
+
+            *)  log_error "Internal error!" >&2; exit 1;;
+        esac
+    done
+    if [ -z "$instance" -o -z "$blockdev" ]; then
+        log_error "Missing OS API Argument (-i, -n, or -b)"
+        exit 1
+    fi
+    if [ "$SCRIPT_NAME" != "export" -a -z "$swapdev"  ]; then
+        log_error "Missing OS API Argument -s (swapdev)"
+        exit 1
+    fi
+    if [ "$SCRIPT_NAME" = "rename" -a -z "$old_name"  ]; then
+        log_error "Missing OS API Argument -o (old_name)"
+        exit 1
+    fi
+}
+
+get_api10_arguments() {
+    if [ -z "$INSTANCE_NAME" -o -z "$HYPERVISOR" -o -z "$DISK_COUNT" ]; then
+        log_error "Missing OS API Variable:"
+        log_error "(INSTANCE_NAME HYPERVISOR or DISK_COUNT)"
+        exit 1
+    fi
+    instance=$INSTANCE_NAME
+    if [ $DISK_COUNT -lt 1 -o -z "$DISK_0_PATH" ]; then
+        log_error "At least one disk is needed"
+        exit 1
+    fi
+    if [ "$SCRIPT_NAME" = "export" ]; then
+        if [ -z "$EXPORT_DEVICE" ]; then
+        log_error "Missing OS API Variable EXPORT_DEVICE"
+    fi
+    blockdev=$EXPORT_DEVICE
+    elif [ "$SCRIPT_NAME" = "import" ]; then
+        if [ -z "$IMPORT_DEVICE" ]; then
+        log_error "Missing OS API Variable IMPORT_DEVICE"
+        fi
+        blockdev=$IMPORT_DEVICE
+    else
+        blockdev=$DISK_0_PATH
+    fi
+    if [ "$SCRIPT_NAME" = "rename" -a -z "$OLD_INSTANCE_NAME" ]; then
+        log_error "Missing OS API Variable OLD_INSTANCE_NAME"
+    fi
+    old_name=$OLD_INSTANCE_NAME
+}
+
+get_api20_arguments() {
+    get_api_10_arguments
+    if [ -z "$OSP_IMG_ID"]; then
+        log_error "Missing OS API Parameter: OSP_IMG_ID"
+        exit 1
+    fi
+    if [ -z "$OSP_IMG_FORMAT"]; then
+        log_error "Missing OS API Parameter: OSP_IMG_FORMAT"
+        exit 1
+    fi
+    if [ -z "$OSP_IMG_PASSWD"]; then
+        log_error "Missing OS API Parameter: OSP_IMG_PASSWD"
+        exit 1
+    fi
+
+    IMG_ID=$OSP_IMG_ID
+    IMG_FORMAT=$OSP_IMG_FORMAT
+    IMG_PASSWD=$OSP_IMG_PASSWD
+}
+
+map_disk0() {
+    blockdev="$1"
+    filesystem_dev_base=`$KPARTX -l -p- $blockdev | \
+                            grep -m 1 -- "-1.*$blockdev" | \
+                            $AWK '{print $1}'`
+    if [ -z "$filesystem_dev_base" ]; then
+        log_error "Cannot interpret kpartx output and get partition mapping"
+        exit 1
+    fi
+    $KPARTX -a -p- $blockdev > /dev/null
+    filesystem_dev="/dev/mapper/${filesystem_dev_base/%-1/}"
+    if [ ! -b "/dev/mapper/$filesystem_dev_base" ]; then
+        log_error "Can't find kpartx mapped partition:" \
+                                            "/dev/mapper/$filesystem_dev_base"
+        exit 1
+    fi
+    echo "$filesystem_dev"
+}
+
+unmap_disk0() {
+    $KPARTX -d -p- $1
+}
+
+format_disk0() {
+    local device="$1"
+    local image_type="$2"
+    
+    declare -A part_id=( ['extdump']="83" ["ntfsdump"]="7" )
+
+    # The -f is needed, because we use an optimal alignment and sfdisk complains
+    # about partitions not ending on clylinder boundary.
+    local sfdisk_cmd="$SFDISK -uS -H 255 -S 63 -f --quiet --Linux --DOS $device"
+
+    $sfdisk_cmd > /dev/null <<EOF
+2048,,${part_id["$image_type"]},*
+EOF
+}
+
+cleanup() {
+    if [ ${#CLEANUP[*]} -gt 0 ]; then
+        LAST_ELEMENT=$((${#CLEANUP[*]}-1))
+        REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
+        for i in $REVERSE_INDEXES; do
+            ${CLEANUP[$i]}
+        done
+    fi
+}
+
+trap cleanup EXIT
+
+DEFAULT_FILE="@sysconfdir@/default/snf-image"
+if [ -f "$DEFAULT_FILE" ]; then
+    . "$DEFAULT_FILE"
+fi
+
+: ${ARCH:="x86_64}
+: ${CUSTOMIZE_DIR:="@sysconfdir@/ganeti/snf-image/hooks"}
+: ${VARIANTS_DIR:="@sysconfdir@/ganeti/snf-image/variants"}
+: ${IMAGE_DIR:="@localstatedir@/lib/snf-image"}
+
+SCRIPT_NAME=$(basename $0)
+
+if [ -f /sbin/blkid -a -x /sbin/blkid ]; then
+    VOL_ID="/sbin/blkid -c /dev/null -o value -s UUID"
+    VOL_TYPE="/sbin/blkid -c /dev/null -o value -s TYPE"
+else
+    for dir in /lib/udev /sbin; do
+        if [ -f $dir/vol_id -a -x $dir/vol_id ]; then
+            VOL_ID="$dir/vol_id -u"
+            VOL_TYPE="$dir/vol_id -t"
+        fi
+    done
+fi
+
+if [ -z "$VOL_ID" ]; then
+    log_error "vol_id or blkid not found, please install udev or util-linux"
+    exit 1
+fi
+
+
+if [ -z "$OS_API_VERSION" -o "$OS_API_VERSION" = "5" ]; then
+    OS_API_VERSION=5
+    GETOPT_RESULT=`getopt -o o:n:i:b:s: -n '$0' -- "$@"`
+    if [ $? != 0 ] ; then log_error "Terminating..."; exit 1 ; fi
+    get_api5_arguments $GETOPT_RESULT
+elif [ "$OS_API_VERSION" = "10" -o "$OS_API_VERSION" = "15" ]; then
+    get_api10_arguments
+elif [ "$OS_API_VERSION" = "20" ]; then
+    get_api20_arguments
+    IMAGE_NAME=$IMG_ID
+    IMAGE_TYPE=$IMG_FORMAT
+else
+    log_error "Unknown OS API VERSION $OS_API_VERSION"
+    exit 1
+fi
+
+if [ -n "$OS_VARIANT" ]; then
+    if [ ! -d "$VARIANTS_DIR" ]; then
+        log_error "OS Variants directory $VARIANTS_DIR doesn't exist"
+        exit 1
+    fi
+    VARIANT_CONFIG="$VARIANTS_DIR/$OS_VARIANT.conf"
+    if [ -f "$VARIANT_CONFIG" ]; then
+        . "$VARIANT_CONFIG"
+    else
+        if grep -qxF "$OS_VARIANT" variants.list; then
+            log_error "ERROR: instance-image configuration error"
+            log_error "  Published variant $OS_VARIANT is missing its config" \
+                      "file"
+            log_error "  Please create $VARIANT_CONFIG or unpublish the variant"
+            log_error "  (by removing $OS_VARIANT from variants.list)"
+        else
+            log_error "Unofficial variant $OS_VARIANT is unsupported"
+            log_error "Most probably this is a user error, forcing a wrong name"
+            log_error "To support this variant please create file" \
+                        "$VARIANT_CONFIG"
+        fi
+        exit 1
+    fi
+fi
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/host/create b/host/create
new file mode 100755 (executable)
index 0000000..83e8316
--- /dev/null
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+# Copyright 2011 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are
+# those of the authors and should not be interpreted as representing official
+# policies, either expressed or implied, of GRNET S.A.
+
+set -e
+
+. common.sh
+
+case "$IMAGE_TYPE" in
+    extdump)
+       IMAGE_FILE="${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.extdump";;
+    ntfsdump)
+        IMAGE_FILE="${IMAGE_DIR}/${IMAGE_NAME}-${ARCH}-root.ntfsdump";;
+    *)
+        log_error "Unknown image type: \`$IMAGE_TYPE'.";
+        exit 1
+esac
+
+if [ ! -e "$IMAGE_FILE" ]; then
+    log_error "Image file \`$IMAGE_FILE' does not exit."
+    exit 1
+fi
+
+MONITOR="" #Empty if progress monitor support is disabled
+if [ "$progress_monitor_support" = "yes" ]; then
+    IMAGE_SIZE="$(stat -L -c %s ${IMAGE_FILE})"
+    MONITOR="$PROGRESS_MONITOR -i ${INSTANCE_NAME} -r ${IMAGE_SIZE}"
+fi
+
+# If the target device is not a real block device we'll first losetup it.
+# This is needed for file disks.
+if [ ! -b $blockdev ]; then
+    ORIGINAL_BLOCKDEV=$blockdev
+    blockdev=$($LOSETUP -sf $blockdev)
+    CLEANUP+=("$LOSETUP -d $blockdev")
+fi
+
+${IMAGE_TYPE}_format_disk0 $blockdev
+
+filesystem_dev=$(map_disk0 $blockdev)
+CLEANUP+=("unmap_disk0 $blockdev")
+
+root_dev="${filesystem_dev}-1"
+
+# dd the dump to its new home :-)
+# Deploying an image file on a target block device is a streaming
+# copy operation. Enable the direct I/O flag on the output fd to 
+# avoid polluting the host cache with useless data.
+$MONITOR dd bs=4M if=$IMAGE_FILE of=$root_dev oflag=direct
+
+#Invoke the helper vm to do the dirty job...
+
+# Execute cleanups
+cleanup
+trap - EXIT
+
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/host/ganeti_api_version b/host/ganeti_api_version
new file mode 100644 (file)
index 0000000..00c5455
--- /dev/null
@@ -0,0 +1,4 @@
+20
+15
+10
+5
diff --git a/host/parameters.list b/host/parameters.list
new file mode 100644 (file)
index 0000000..f9cd23e
--- /dev/null
@@ -0,0 +1,3 @@
+img_id The id of the image to be installed (the id will be the image's file name prefix)
+img_format The format of the image to be installed
+img_passwd The root password which will be injected into the image 
diff --git a/host/variants.list b/host/variants.list
new file mode 100644 (file)
index 0000000..4ad96d5
--- /dev/null
@@ -0,0 +1 @@
+default