--- /dev/null
+# 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.
+
+OUTPUT=/dev/ttyS0
+RESULT=/dev/ttyS2
+
+# Programs
+XMLSTARLET=xmlstarlet
+INSTALL_MBR=install-mbr
+
+CLEANUP=( )
+
+log_error() {
+ echo "$@" >&2
+ exit 1
+}
+
+get_base_distro() {
+ local root_dir=$1
+
+ if [ -e "$root_dir/etc/debian_version" ]; then
+ echo "debian"
+ elif [ -e "$root_dir/etc/redhat-release" ]; then
+ echo "redhat"
+ elif [ -e "$root_dir/etc/slackware-version" ]; then
+ echo "slackware"
+ elif [ -e "$root_dir/SuSE-release" ]; then
+ echo "suse"
+ elif [ -e "$root_dir/gentoo-release" ]; then
+ echo "gentoo"
+ fi
+}
+
+get_distro() {
+ local root_dir=$1
+
+ if [ -e "$root_dir/etc/debian_version" ]; then
+ distro="debian"
+ if [ -e ${root_dir}/etc/lsb-release ]; then
+ ID=$(grep $DISTRIB_ID=${root_dir}/etc/lsb-release | cut -d= -f2)
+ if [ "x$ID" = "xUbuntu" ]; then
+ distro="ubuntu"
+ fi
+ fi
+ echo "$distro"
+ elif [ -e "$root_dir/etc/fedora-release" ]; then
+ echo "fedora"
+ elif [ -e "$root_dir/etc/centos-release" ]; thne
+ echo "centos"
+ elif [ -e "$root_dir/etc/redhat-release" ]; then
+ echo "redhat"
+ elif [ -e "$root_dir/etc/slackware-version" ]; then
+ echo "slackware"
+ elif [ -e "$root_dir/SuSE-release" ]; then
+ echo "suse"
+ elif [ -e "$root_dir/gentoo-release" ]; then
+ echo "gentoo"
+ fi
+}
+
+cleanup() {
+# if something fails here, it souldn't call cleanup again...
+ trap - EXIT
+
+ if [ ${#CLEANUP[*]} -gt 0 ]; then
+ LAST_ELEMENT=$((${#CLEANUP[*]}-1))
+ REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
+ for i in $REVERSE_INDEXES; do
+ # If something fails here, it's better to retry it for a few times
+ # before we give up with an error. This is needed for kpartx when
+ # dealing with ntfs partitions mounted through fuse. umount is not
+ # synchronous and may return while the partition is still busy. A
+ # premature attempt to delete partition mappings through kpartx on a
+ # device that hosts previously mounted ntfs partition may fail with
+ # an `device-mapper: remove ioctl failed: Device or resource busy'
+ # error. A sensible workaround for this is to wait for a while and
+ # then try again.
+ local cmd=${CLEANUP[$i]}
+ $cmd || for interval in 0.25 0.5 1 2 4; do
+ echo "Command $cmd failed!"
+ echo "I'll wait for $interval secs and will retry..."
+ sleep $interval
+ $cmd && break
+ done
+ test $? -eq 1 && { echo "Giving Up..."; exit 1; }
+ done
+ fi
+ echo "Clean UP executed"
+}
+
+trap cleanup EXIT
+
+# Redirect stdout and stderr
+exec &> $OUTPUT
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
--- /dev/null
+#!/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.
+
+. /usr/share/snf-image/common.sh
+
+# terminate helper vm when the script exits
+CLEANUP+=("telinit 0")
+
+floppy=$(mktemp -d floppy.XXXXXXXX) || exit 1
+CLEANUP+=("rm -f $floppy")
+
+if [ -e /dev/fd0 ]; then
+ mount /dev/fd0 $floppy
+ source $floppy
+ umount $floppy
+else
+ log_error "Floppy Device is not present!"
+fi
+
+# Mount the instance's partition
+target=$(mktemp -d target.XXXXXXXX) || exit 1
+CLEANUP+=("rm -f $target")
+mount /dev/sdb $target
+CLEANUP+=("umount $target")
+
+SNF_IMAGE_TARGET=$target
+
+RUN_PARTS=`which run-parts`
+if [ -n "$RUN_PARTS" -a -n "/usr/lib/snf-image/tasks" ]; then
+ set | egrep ^SNF_IMAGE_\\w+= | cut -d= -f1 | while read line; do
+ export $line
+ done
+ $RUN_PARTS "/usr/lib/snf-image/tasks"
+fi
+
+cleanup
+trap - EXIT
+
+# never called...
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (c) 2011 Greek Research and Technology Network
+#
+"""Generate a Hash from a given Password
+
+This program takes a Password as an argument and
+returns to standard output a hash followed by a newline.
+To do this, it generates internally a random salt.
+
+"""
+
+import sys
+import crypt
+
+from string import ascii_letters, digits
+from random import choice
+from os.path import basename
+from optparse import OptionParser
+
+
+# This dictionary maps the hashing algorithm method
+# with its <ID> as documented in:
+# http://www.akkadia.org/drepper/SHA-crypt.txt
+HASH_ID_FROM_METHOD = {
+ 'md5': '1',
+ 'blowfish': '2a',
+ 'sun-md5': 'md5',
+ 'sha256': '5',
+ 'sha512': '6'
+}
+
+def random_salt(length=8):
+ pool = ascii_letters + digits + "/" + "."
+ return ''.join(choice(pool) for i in range(length))
+
+
+def parse_arguments(input_args):
+ usage = "usage: %prog [-h] [-m encrypt-method] <password>"
+ parser = OptionParser(usage=usage)
+ parser.add_option("-m", "--encrypt-method",
+ dest="encrypt_method",
+ type='choice',
+ default="sha512",
+ choices=HASH_ID_FROM_METHOD.keys(),
+ help="encrypt password with ENCRYPT_METHOD [%default] \
+ (supported: " + ", ".join(HASH_ID_FROM_METHOD.keys()) +")",
+ )
+
+ (opts, args) = parser.parse_args(input_args)
+
+ if len(args) != 1:
+ parser.error('password is missing')
+
+ return (args[0], opts.encrypt_method)
+
+
+def main():
+ (password, method) = parse_arguments(sys.argv[1:])
+ salt = random_salt()
+ hash = crypt.crypt(password, "$"+HASH_ID_FROM_METHOD[method]+"$"+salt)
+ sys.stdout.write("%s\n" % (hash))
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main())
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
--- /dev/null
+#! /bin/sh
+
+### BEGIN TASK INFO
+# Provides: InstallUnattend
+# Requires:
+# Short-Description: Installs Unattend.xml for unattended windows setup
+### END TAST INFO
+
+set -e
+. /usr/share/snf-image/common.sh
+
+if [ -z "$SNF_IMAGE_TARGET" ]; then
+ log_error "Target dir is missing"
+fi
+
+if [ "$SNF_IMAGE_TYPE" != "ntfsdump" ]; then
+ exit 0
+fi
+
+if [ -e /usr/share/snf-image/unattend.xml ]; then
+ cat /usr/share/snf-image/unattend.xml > $SNF_IMAGE_TARGET/Unattend.xml
+fi
+
+exit 0
--- /dev/null
+#! /bin/sh
+
+### BEGIN TASK INFO
+# Provides: AssignHostname
+# Requires: InstallUnattend
+# Short-Description: Assign the Hostname of Computer Name in the instance
+### END TAST INFO
+
+set -e
+. /usr/share/snf-image/common.sh
+
+windows_hostname() {
+ local target=$1
+ local password=$2
+
+ local tmp_unattend=`mktemp` || exit 1
+ CLEANUP+=("rm $tmp_unattend")
+
+ echo -n "Assigning new computer name..."
+
+ local namespace="urn:schemas-microsoft-com:unattend"
+
+ $XMLSTARLET ed -N x=$namespace -u "/x:unattend/x:settings/x:component/x:ComputerName" -v $password "$target/Unattend.xml" > $tmp_unattend
+
+ cat $tmp_unattend > "$target/Unattend.xml"
+ echo done
+}
+
+linux_hostname() {
+ local target=$1
+ local hostname=$2
+
+ local distro=$(get_base_distro $target)
+
+ case "$distro" in
+ debian)
+ echo "$hostname" > $target/etc/hostname;;
+ redhat)
+ sed -ie "s/HOSTNAME=.*$/HOSTNAME=$hostname/g" $target/etc/sysconfig/network;;
+ slackware|suse)
+ #local domain=$(sed -e 's/^[^\.]*//g' < /etc/HOSTNAME)
+
+ # In slackware hostname and domain name are joined together. For now I
+ # will not retain the domain name.
+
+ echo $hostname > ${target}/etc/HOSTNAME;;
+ gentoo)
+ sed -ie "s/\(\(HOSTNAME\)\|\(hostname\)\)=.*$/\1=\"$hostname\"/" $target/etc/conf.d/hostname;;
+ esac
+
+ # Some Linux distributions assign the hostname to 127.0.1.1 in order to be
+ # resolvable to an IP address. Lets replace this if found in /etc/hosts
+ sed -ie "s/^[[:blank:]]*127\.0\.1\.1[[:blank:]].\+$/127.0.1.1\t$hostname/" $target/etc/hosts
+}
+
+if [ -z "$SNF_IMAGE_TARGET" -o ! -d "$SNF_IMAGE_TARGET" ]; then
+ log_error "Missing target directory"
+fi
+
+if [ -z "$SNF_IMAGE_HOSTNAME" ]; then
+ log_error "Hostname is missing"
+fi
+
+if [ "$SNF_IMAGE_TYPE" = "ntfsdump" ]; then
+ windows_hostname $SNF_IMAGE_TARGET $SNF_IMAGE_PASSWORD
+elif [ "$SNF_IMAGE_TYPE" = "extdump" ]; then
+ linux_hostname $SNF_IMAGE_TARGET $SNF_IMAGE_PASSWORD
+fi
+
+echo "done"
+
+cleanup
+trap - EXIT
+
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+
--- /dev/null
+#! /bin/sh
+
+### BEGIN TASK INFO
+# Provides: ChangePassword
+# Requires: InstallUnattend
+# Short-Description: Changes Password for specified users
+### END TAST INFO
+
+set -e
+. /usr/share/snf-image/common.sh
+
+windows_password() {
+ local target=$1
+ local password=$2
+
+ local tmp_unattend=`mktemp` || exit 1
+ CLEANUP+=("rm $tmp_unattend")
+
+ echo -n "Installing new admin password..."
+
+ local namespace="urn:schemas-microsoft-com:unattend"
+
+ $XMLSTARLET ed -N x=$namespace -u "/x:unattend/x:settings/x:component/x:UserAccounts/x:AdministratorPassword/x:Value" -v $password "$target/Unattend.xml" > $tmp_unattend
+
+ cat $tmp_unattend > "$target/Unattend.xml"
+ echo done
+}
+
+linux_password() {
+ local target=$1
+ local password=$2
+
+ local hash=$(/usr/share/snf-image/snf-passtohash.py $password)
+ if [ ! -e ${target}/etc/shadow ]; then
+ log_error "No /etc/shadow found!"
+ fi
+
+ declare -a users=("root")
+
+ local distro=$(get_distro $target)
+
+ if [ "x$disto" = "xubuntu" -o \
+ "x$disto" + "xfedora" ] ; then
+ users+=("user")
+ fi
+
+ for i in $(seq 0 1 $((${#users[@]}-1))); do
+ local tmp_shadow=$(mktemp)
+ CLEANUP+=("rm $tmp_shadow")
+
+ echo -n "Setting ${users[$i]} password..."
+
+ echo "${users[$i]}:$hash:15103:0:99999:7:::" > $tmp_shadow
+ grep -v "${users[$i]}" ${TARGET}/etc/shadow >> $tmp_shadow
+ cat $tmp_shadow > ${target}/etc/shadow
+ echo "done"
+ done
+}
+
+if [ -z "$SNF_IMAGE_TARGET" ]; then
+ log_error "Target dir is missing"
+fi
+
+if [ -z "$SNF_IMAGE_PASSWORD" ]; then
+ log_error "Password is missing"
+fi
+
+if [ "$SNF_IMAGE_TYPE" = "ntfsdump" ]; then
+ windows_password $SNF_IMAGE_TARGET $SNF_IMAGE_PASSWORD
+elif [ "$SNF_IMAGE_TYPE" = "extdump" ]; then
+ linux_password $SNF_IMAGE_TARGET $SNF_IMAGE_PASSWORD
+fi
+
+echo "done"
+
+cleanup
+trap - EXIT
+
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+
--- /dev/null
+#! /bin/sh
+
+### BEGIN TASK INFO
+# Provides: DeleteSSHKeys
+# Requires:
+# Short-Description: Remove ssh keys if present.
+### END TAST INFO
+
+set -e
+. /usr/share/snf-image/common.sh
+
+
+if [ "$SNF_IMAGE_TYPE" != "extdump" ]; then
+ exit 0
+fi
+
+HOST_KEY="/etc/ssh/ssh_host_key"
+RSA_KEY="/etc/ssh/ssh_host_rsa_key"
+DSA_KEY="/etc/ssh/ssh_host_dsa_key"
+
+for key in $HOST_KEY $RSA_KEY $DSA_KEY ; do
+ if [ -f "${SNF_IMAGE_TARGET}/${key}" ] ; then
+ rm -f ${SNF_IMAGE_TARGET}/${key}*
+ fi
+done
+
+cleanup
+trap - EXIT
+
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+
--- /dev/null
+#! /bin/sh
+
+### BEGIN TASK INFO
+# Provides: SELinuxAutorelabel
+# Requires:
+# Short-Description: Force the system to relabel at next boot
+### END TAST INFO
+
+set -e
+. /usr/share/snf-image/common.sh
+
+if [ -z "$SNF_IMAGE_TARGET" ]; then
+ log_error "Target dir is missing"
+fi
+
+if [ "$SNF_IMAGE_TYPE" != "extdump" ]; then
+ exit 0
+fi
+
+distro=$(get_base_distro $SNF_IMAGE_TARGET)
+
+if [ "$distro" = "redhat" ]; then
+ # we have to force a filesystem relabeling for SELinux after messing
+ # around with the filesystem in redhat derived OSs
+ echo "Enforce an automatic relabeling in the initial boot process..."
+ touch $SNF_IMAGE_TARGET/.autorelabel
+fi
+
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
dd bs=512 count=2880 if=/dev/zero of=$img
mkfs.ext2 -F $img > /dev/null
mount $img $target -o loop
- set|egrep ^snf_export_\\w+|sed -e 's/^snf_export_/GANETI_/' > $target/rules
+ set|egrep ^snf_export_\\w+=|sed -e 's/^snf_export_/SNF_IMAGE_/' > $target/rules
umount $target
}
floppy=$(mktemp --tmpdir floppy.XXXXXXXX) || exit 1
CLEANUP+=("rm -f $floppy")
-snf_export_FORMAT=${IMG_FORMAT}
+snf_export_TYPE=${IMG_FORMAT}
snf_export_PASSWORD=${IMG_PASSWD}
snf_export_HOSTNAME=${instance}