--- tools/create-ovirt-iso-nodes | 135 ++++++++++++++++++++++++++ tools/edit-livecd | 220 ++++++++++++++++++++++++++++++++++++++++++ tools/livecd-iso-to-iscsi | 201 ++++++++++++++++++++++++++++++++++++++ tools/livecd-rpms | 28 ++++++ tools/livecd-setauth | 50 ++++++++++ 5 files changed, 634 insertions(+), 0 deletions(-) create mode 100755 tools/create-ovirt-iso-nodes create mode 100755 tools/edit-livecd create mode 100755 tools/livecd-iso-to-iscsi create mode 100755 tools/livecd-rpms create mode 100755 tools/livecd-setauth
diff --git a/tools/create-ovirt-iso-nodes b/tools/create-ovirt-iso-nodes new file mode 100755 index 0000000..fe2e7ab --- /dev/null +++ b/tools/create-ovirt-iso-nodes @@ -0,0 +1,135 @@ +#!/bin/bash +# +# Create fake oVirt Nodes for testing CDROM boot +# Copyright 2008 Red Hat, Inc. +# Written by Perry Myers <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +PATH=$PATH:/sbin:/usr/sbin + +ME=$(basename "$0") +warn() { printf '%s: %s\n' "$ME" "$*" >&2; } +try_h() { printf "Try \`$ME -h' for more information.\n" >&2; } +die() { warn "$@"; try_h; exit 1; } + +NET_DEFAULT=network:default +IMGDIR_DEFAULT=/var/lib/libvirt/images +imgdir=$IMGDIR_DEFAULT +NODEIMG_DEFAULT=/usr/share/ovirt-node-image/ovirt-node-image.iso +nodeimg=$NODEIMG_DEFAULT +NUM_DISKS_DEFAULT=1 +RANGE_DEFAULT="6-9" +RAM_DEFAULT=512 +VCPUS_DEFAULT=1 + +NODE_DISK_FMT=qcow2 +NODE_DISK_SIZE=6144M + +gen_fake_managed_node() { + local num=$1 + local src_nodeimg=$2 + local last_mac=$(( 54 + $num )) + + local os_variant=fedora10 + if [ "$no_virtio" = 1 ]; then + os_variant=fedora8 + fi + + echo "Creating fake node$num using $nodeimg..." + local dest_nodeimg="$imgdir/node${num}-$(basename $src_nodeimg)" + echo "$src_nodeimg -> $dest_nodeimg" + rsync -av $src_nodeimg $dest_nodeimg + + virsh destroy node$num > /dev/null 2>&1 + virsh undefine node$num > /dev/null 2>&1 + + local disks= + for ((i=0;i<$num_disks;i+=1)); do + qemu-img create -f $NODE_DISK_FMT \ + $imgdir/node${num}-${i}.$NODE_DISK_FMT $NODE_DISK_SIZE + disks="$disks --disk path=$imgdir/node${num}-${i}.$NODE_DISK_FMT" + done + + # FIXME: virt-install should be changed to have a --nostart parameter + # that just defines the VM w/o starting it. + virt-install --name=node$num --ram=$ram --vcpus=$vcpus $disks \ + --cdrom=$dest_nodeimg --livecd \ + --network=$net --mac=00:16:3e:12:34:$last_mac \ + --vnc --accelerate --hvm --noautoconsole \ + --os-type=linux --os-variant=$os_variant \ + --force --noreboot + virsh destroy node$num > /dev/null 2>&1 + echo "node$num created" +} + +usage() { + case $# in 1) warn "$1"; try_h; exit 1;; esac + cat <<EOF +Usage: $ME [-d image_dir] [-n node.iso] [-c num_disks] [-s start-stop] + [-v vcpus] [-r ram] [-x] [-b network] + -n: node.iso to boot (default: $NODEIMG_DEFAULT) + -b: network name (default: $NET_DEFAULT) + -d: directory to place virtual disk (default: $IMGDIR_DEFAULT) + -c: number of disks per fake node (default: $NUM_DISKS_DEFAULT) + -s: node range (default: $RANGE_DEFAULT) + -v: vcpus per node (default: $VCPUS_DEFAULT) + -r: ram in MB per node (default: $RAM_DEFAULT) + -x: toggle virtio devices off + -h: display this help and exit +EOF +} + +err=0 help=0 +no_virtio=0 +num_disks=$NUM_DISKS_DEFAULT +range=$RANGE_DEFAULT +ram=$RAM_DEFAULT +vcpus=$VCPUS_DEFAULT +net=$NET_DEFAULT +while getopts :d:n:b:s:c:v:r:xh c; do + case $c in + n) nodeimg=$OPTARG;; + d) imgdir=$OPTARG;; + b) net=$OPTARG;; + c) num_disks=$OPTARG;; + s) range=$OPTARG;; + v) vcpus=$OPTARG;; + r) ram=$OPTARG;; + x) no_virtio=1;; + h) help=1;; + '?') err=1; warn "invalid option: \`-$OPTARG'";; + :) err=1; warn "missing argument to \`-$OPTARG' option";; + *) err=1; warn "internal error: \`-$OPTARG' not handled";; + esac +done +test $err = 1 && { try_h; exit 1; } +test $help = 1 && { usage; exit 0; } + +# first, check to see we are root +if [ $( id -u ) -ne 0 ]; then + die "Must run as root" +fi + +mkdir -p $imgdir + +test -f $nodeimg || die "could not find $nodeimg" + +# define the fake managed nodes we will use. +range_start=$(echo $range | cut -d '-' -f 1) +range_stop=$(echo $range | cut -d '-' -f 2) + +for i in `seq $range_start $range_stop` ; do + gen_fake_managed_node $i $nodeimg +done diff --git a/tools/edit-livecd b/tools/edit-livecd new file mode 100755 index 0000000..d69ca9d --- /dev/null +++ b/tools/edit-livecd @@ -0,0 +1,220 @@ +#!/bin/bash +# +# Edit a livecd to insert files +# Copyright 2008 Red Hat, Inc. +# Written by Perry Myers <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#!/bin/bash + +PATH=$PATH:/sbin:/usr/sbin + +ME=$(basename "$0") +warn() { printf '%s: %s\n' "$ME" "$*" >&2; } +try_h() { printf "Try \`$ME -h' for more information.\n" >&2; } +die() { warn "$@"; try_h; exit 1; } + +NODEIMG_DEFAULT=/usr/share/ovirt-node-image/ovirt-node-image.iso +CD=$NODEIMG_DEFAULT + +usage() { + case $# in 1) warn "$1"; try_h; exit 1;; esac + cat <<EOF +Usage: $ME -i LiveCD.iso [-b bootparams] [-p program] + -b BOOTPARAMS optional parameters appended to the kernel command line + -i LIVECD.iso LiveCD ISO to edit (default: $NODEIMG_DEFAULT) + -o OUTPUT.iso specify the output file (required) + -p CODE Arbitrary CODE that is eval'd while 'cd'd into the root of + the livecd root filesystem. Note; the code is not run in + a chroot environment, so it can access the host filesystem. + If this option is omitted, this program pauses and allows + the user (in another terminal) to modify the filesystem + manually. Type <enter> when done, and the script + re-packages the ISO. + -h display this help and exit + +EXAMPLES + + Example Script: + #!/bin/sh + touch etc/sysconfig/foo + Save as foo and make executable: + chmod a+x foo + Run this to create a file /etc/sysconfig/foo in the livecd filesystem + (note the use of "\$PWD/foo", not "./foo", since it will be run from a + different directory): + + $ME -i input.iso -o /tmp/result.iso -p "\$PWD/foo" + + or, equivalently, but without a separate script: + + $ME -i input.iso -o /tmp/result.iso -p 'touch etc/sysconfig/foo' + +EOF +} + +# exit after any error: +set -e + +CODE= +OUTPUT_FILE= + +err=0 help=0 +while getopts :b:hi:o:p: c; do + case $c in + i) CD=$OPTARG;; + b) PARAMS=$OPTARG;; + o) OUTPUT_FILE=$OPTARG;; + p) CODE=$OPTARG;; + h) help=1;; + '?') err=1; warn "invalid option: \`-$OPTARG'";; + :) err=1; warn "missing argument to \`-$OPTARG' option";; + *) err=1; warn "internal error: \`-$OPTARG' not handled";; + esac +done +test $err = 1 && { try_h; exit 1; } +test $help = 1 && { usage; exit 0; } + +# Require "-o OUTPUT_FILE" +test -z "$OUTPUT_FILE" \ + && { warn "no output file specified; use -o FILE.iso"; try_h; exit 1; } + +# Fail if there are any extra command-line arguments. +if test $OPTIND -le $#; then + bad_arg=$(eval "echo \$$OPTIND") + warn "extra argument '$bad_arg'"; try_h; exit 1 +fi + +# first, check to see we are root +if [ $( id -u ) -ne 0 ]; then + die "Must run as root" +fi + +# Check for some prerequisites. +# "type" prints "PROG not found" if it's not in $PATH. +type mkisofs +type mksquashfs +type sed +type implantisomd5 + +sane_name() +{ + case $1 in + *[^a-zA-Z0-9._,+:/@%=-]*) false;; + *) true;; + esac +} + +# Fail if names we'll use contain white space or shell meta-characters +sane_name "$PWD" || die "invalid working directory name: $PWD" +sane_name "$CD" || die "invalid ISO name: $CD" + +WDIR=`mktemp -d $PWD/livecd.XXXXXXXXXX` + +addExit() { + EXIT="$@ ; $EXIT" + trap "$EXIT" EXIT HUP TERM INT QUIT +} + +mnt() { + local margs="$1" ; shift + local mp="$WDIR/$1" + for D in "$@" ; do + mkdir -v -p "$WDIR/$D" + done + eval mount -v $margs "$mp" + addExit "df | grep $mp > /dev/null 2>&1 && umount -v $mp" +} + +addExit "rm -rf $WDIR" + +ID_FS_LABEL= # initialize, in case vol_id fails +eval "$(/lib/udev/vol_id $CD)" +LABEL=$ID_FS_LABEL + +# mount the CD image +mnt "-t iso9660 $CD -o loop,ro" cd + +# mount compressed filesystem +mnt "-t squashfs $WDIR/cd/LiveOS/squashfs.img -o ro,loop" sq + +# create writable copy of the new filesystem for the CD +cp -pr $WDIR/cd $WDIR/cd-w + +# create writable copy of the filesystem for the new compressed +# squashfs filesystem +cp -pr $WDIR/sq $WDIR/sq-w + +# mount root filesystem +mnt "-t ext2 $WDIR/sq-w/LiveOS/ext3fs.img -o rw,loop" ex + +echo ">>> Updating CD content" +if [ -n "$CODE" ]; then + ( + cd $WDIR/ex + set +e + eval "$CODE" + set -e + ) +else + echo "***" + echo "*** Pausing to allow manual changes. Press any key to continue." + echo "***" + read +fi + +# Try to unmount. But this is likely to fail, so let the user retry, +# e.g., if he forgot to "cd" out of $WDIR/ex. +while :; do + echo ">>> Unmounting ext3fs" + umount $WDIR/ex && break + echo ">>> Unmounting the working file system copy failed" + echo "***" + echo "*** Did you forget to 'cd' out of $WDIR/ex?" + echo "***" + echo "*** Press any key to repeat the attempt." + echo "***" + read +done + +echo ">>> Compressing filesystem" +mksquashfs $WDIR/sq-w/ $WDIR/cd-w/LiveOS/squashfs.img -noappend + +echo ">>> Recomputing MD5 sums" +( cd $WDIR/cd-w && find . -type f -not -name md5sum.txt \ + -not -path '*/isolinux/*' -print0 | xargs -0 -- md5sum > md5sum.txt ) + +if [ -n "$PARAMS" ]; then + case $PARAMS in + *...@*) warn "PARAMS contains the @ sed delimiter, be sure it's escaped";; + esac + echo ">>> Appending boot parameters" + sed -i 's...@^ append .*$@& '"$PARAMS@" "$WDIR/cd-w/isolinux/isolinux.cfg" +fi + +echo ">>> Creating ISO image $ISO" +mkisofs \ + -V "$LABEL" \ + -r -cache-inodes -J -l \ + -b isolinux/isolinux.bin \ + -c isolinux/boot.cat \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -o "$OUTPUT_FILE" \ + $WDIR/cd-w + +echo ">>> Implanting ISO MD5 Sum" +implantisomd5 --force "$OUTPUT_FILE" + +# The trap ... callbacks will unmount everything. +set +e diff --git a/tools/livecd-iso-to-iscsi b/tools/livecd-iso-to-iscsi new file mode 100755 index 0000000..fd3934d --- /dev/null +++ b/tools/livecd-iso-to-iscsi @@ -0,0 +1,201 @@ +#!/usr/bin/python +# Convert a live CD iso into iscsi root bootable format +# iSCSI lun must be accessible via this script +# Copyright 2009 Red Hat, Inc. +# Written by Joey boggs <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +from optparse import OptionParser +from tempfile import mkdtemp +import dbus +import dbus.glib +import sys +import os +import subprocess +import shutil + +parser = OptionParser() +parser.add_option("--iso", dest="iso", help="LiveCD iso filename") +parser.add_option("--target", dest="target", help="iSCSI target ip address") +parser.add_option("--targetname", dest="targetname", help="iSCSI target lun") +parser.add_option("--targetport", dest="targetport", default="3260", help="iSCSI port number, defaults to 3260") +parser.add_option("--user", dest="user", help="Target username(optional)") +parser.add_option("--password", dest="password", help="Target password") +parser.add_option("--reverse_user", dest="reverse_user", help="Reverse CHAP username(optional)") +parser.add_option("--reverse_password", dest="reverse_password", help="Reverse CHAP password(optional)") +parser.add_option("--disk", dest="disk", help="iSCSI disk device name") +parser.add_option("--disk-label", dest="disk_label", default="ovirt-node-root", help="file system label") + +(options, args) = parser.parse_args() + +def fail(msg): + print(msg) + sys.exit(1) + +if os.geteuid () != 0: + fail("You must run as root") + +if options.iso is None: + fail("ERROR: iso file must be defined") +else: + options.iso = os.path.abspath(options.iso) + +if options.target is None: + fail("ERROR: iscsi target must be defined") + +if options.targetname is None: + fail("ERROR: iscsi targetname must be defined") + +if len(options.disk_label.strip()) > 15: + fail("ERROR: disk label must be 14 characters or less") + +try: + file = os.mkdir("tftpboot") +except OSError, e: + tftp_remove = raw_input("tftpboot directory exists, overwrite? (y/N)? ") + if tftp_remove.lower() == "y": + shutil.rmtree("tftpboot") + os.mkdir("tftpboot") + else: + print "Aborting" + sys.exit(1) + +if options.disk is None: + print "Below are the detected disks, if the iscsi disk is not shown, please ensure you are logged into the correct target\n" + bus = dbus.SystemBus () + hal_obj = bus.get_object ('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager') + hal = dbus.Interface (hal_obj, 'org.freedesktop.Hal.Manager') + udis = hal.FindDeviceByCapability ('storage') + dev_dict = {} + dev_count = 1 + for udi in udis: + dev_obj = bus.get_object ('org.freedesktop.Hal', udi) + dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device') + dev_bus=dev.GetProperty ('storage.bus') + dev_name=dev.GetProperty ('block.device') + dev_size=dev.GetProperty ('storage.size') + dev_size=(dev_size/1024/1024) + basename=os.path.basename(udi) + if dev_bus == "scsi": + print "%s. %s %sM %s \n" % (dev_count,dev_name,dev_size,basename) + dev_dict[str(dev_count)] = dev_name + dev_count = dev_count + 1 + print "Enter Q to Quit" + dev_choice = raw_input("Which device? ") + while not dev_dict.has_key(dev_choice): + if dev_choice.lower() == "q": + print "Aborting" + sys.exit(1) + else: + print "%s is an invalid choice" % dev_choice + dev_choice = raw_input("Which device? ") + options.disk = dev_dict[dev_choice] + +cont = raw_input("Creating file system on %s, do you wish to continue (y/N) " % options.disk) +if cont.lower() != "y": + print "Aborting" + sys.exit(1) + +isomount = mkdtemp() +isomount_ret = subprocess.call(["mount", "-o", "loop", options.iso, isomount]) +if isomount_ret != 0: + fail("Error mounting %s" % options.iso) + +kernel="%s/isolinux/vmlinuz0" % isomount +initrd="%s/isolinux/initrd0.img" % isomount +squashfs="%s/LiveOS/squashfs.img" % isomount +ext3fs="tftpboot/squashfs-root/LiveOS/ext3fs.img" +shutil.copy(kernel,"tftpboot") +shutil.copy(initrd,"tftpboot") + +unsquash = subprocess.call(["unsquashfs", squashfs]) + +# workaround until bug is fixed with squashfs -d option +shutil.move("squashfs-root","tftpboot/squashfs-root") + +print "Placing embedded file system on %s" % options.disk +dd_cmd="dd if=%s of=%s" % (ext3fs,options.disk) +copy_iscsi_ret = subprocess.call(dd_cmd, shell=True) +if copy_iscsi_ret != 0: + fail("Error copying to %s" % options.disk) + +umount_ret = subprocess.call(["umount", isomount]) +if umount_ret != 0: + fail("Error unmounting %s, continuing" % isomount) +else: + os.rmdir(isomount) +shutil.rmtree("tftpboot/squashfs-root") + +pxe_template = """ + +# pxelinux configuration. +DEFAULT pxeboot +TIMEOUT 20 +PROMPT 0 +LABEL ovirt-node-iscsi + KERNEL /vmlinuz0 + APPEND initrd=/initrd0.img ro root=LABEL=%(disk_label)s netroot=iscsi:%(user)s%(password)s...@%(target)s::%(target_port)s::%(target_name)s ip=eth0:dhcp + ipappend 2 +ONERROR LOCALBOOT 0 +""" + +# insert empty values for unneeded variables in the pxe template +if not options.user is None: + options.user = options.user + ":" +else: + options.user = "" + +if not options.password is None: + options.password = options.password + ":" +else: + options.password = "" + +if not options.reverse_user is None: + options.reverse_user = options.reverse_user + ":" +else: + options.reverse_user = "" + +if not options.reverse_password is None: + options.reverse_password = options.reverse_password + ":" +else: + options.reverse_password = "" + +os.mkdir("tftpboot/pxelinux.cfg") +pxe_cfg = pxe_template % { + "disk_label": options.disk_label, + "target": options.target, + "target_port": options.targetport, + "target_name": options.targetname, + "user": options.user, + "password": options.password, + "reverse_user": options.reverse_user, + "reverse_password": options.reverse_password + } + +pxe_conf = open("tftpboot/pxelinux.cfg/default", 'w') +pxe_conf.write(pxe_cfg) +pxe_conf.close() + +if os.path.exists("/usr/share/syslinux/pxelinux.0"): + shutil.copy("/usr/share/syslinux/pxelinux.0","tftpboot") +elif os.path.exists("/usr/lib/syslinux/pxelinux.0"): + shutil.copy("/usr/lib/syslinux/pxelinux.0","tftpboot") +else: + print "Warning: You need to add pxelinux.0 to tftpboot/ subdirectory" + +print "Your iscsiroot has been setup on %s" % options.disk +print "" +print "Copy the tftpboot/ subdirectory to your tftpserver root directory" +print "Set up your DHCP, TFTP and PXE server to serve /tftpboot/.../pxeboot.0" diff --git a/tools/livecd-rpms b/tools/livecd-rpms new file mode 100755 index 0000000..0649cba --- /dev/null +++ b/tools/livecd-rpms @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Script to install/update a livecd with a set of RPMS provided in a directory +# Copyright 2009 Red Hat, Inc. +# Written by Perry Myers <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if [[ $# < 1 ]]; then + echo "Usage: $0 rpmdir" + exit 1 +fi + +RPMDIR=$1 + +rpm --root $PWD -Uvh $(find $RPMDIR -type f -name "*.rpm" -print) + diff --git a/tools/livecd-setauth b/tools/livecd-setauth new file mode 100755 index 0000000..eb8922f --- /dev/null +++ b/tools/livecd-setauth @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Script to interactively add root password and authorized_keys file +# to a livecd +# Copyright 2008 Red Hat, Inc. +# Written by Perry Myers <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +DEFAULT_AUTH=~/.ssh/authorized_keys + +printf "Do you want to set a root password? [y/N]: " +read yesno +if [ "$yesno" = "y" -o "$yesno" = "Y" ]; then + chroot . passwd root +fi + +printf "Do you want to set an authorized_keys file? [y/N]: " +read yesno +if [ "$yesno" = "y" -o "$yesno" = "Y" ]; then + echo "Enter the location of the authorized_keys file [default: $DEFAULT_AUTH]: " + read -e authkeys + if [ -z "$authkeys" ]; then + authkeys=$DEFAULT_AUTH + fi + + authkeys=$(eval echo $authkeys) + if [ -f $authkeys ]; then + SSH=root/.ssh + AUTH=$SSH/authorized_keys + + mkdir -p $SSH + chmod 755 $SSH + cp -v $authkeys $AUTH + chmod 644 $AUTH + else + echo "$authkeys not found, skipping" + fi +fi -- 1.6.2.5 _______________________________________________ Ovirt-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/ovirt-devel
