#!/bin/bash set -e PROGNAME=$(basename $0) # $HeadURL: http://sos16-vip/svn/kickstart/trunk/bin/defaults-dumper $ $LastChangedRevision: 669 $ # Load libraries . $(dirname $0)/../include/mkdi.sh main() { local TARGET_HOSTNAME ISCSISERVER_HOSTNAME ISCSISERVER_VOLUME_GROUP TARGET_ROOT_DISK_SIZE # Defaults for options VERBOSELEVEL=2 # Process options while [ "X$1" != X ]; do case $1 in # Application specific options --target-hostname=*) TARGET_HOSTNAME=${1#*=} ;; --iscsiserver-hostname=*) ISCSISERVER_HOSTNAME=${1#*=} ;; --iscsiserver-volume-group=*) ISCSISERVER_VOLUME_GROUP=${1#*=} ;; --target-root-disk-size=*) TARGET_ROOT_DISK_SIZE=${1#*=} ;; # General options --help|-h) usage 0 ;; --verbose|-v) VERBOSELEVEL=3 ;; -d) VERBOSELEVEL=$2; shift ;; --debug=*) VERBOSELEVEL=${1#*=} ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Process arguments [ $# -ge 1 ] || usage MODE=$1; shift debug 10 "main: MODE=$MODE" # Sanity checks and derivations # Guts case $MODE in create) create --target-hostname=$TARGET_HOSTNAME --iscsiserver-hostname=$ISCSISERVER_HOSTNAME --iscsiserver-volume-group=$ISCSISERVER_VOLUME_GROUP --target-root-disk-size=$TARGET_ROOT_DISK_SIZE "$@" || return $? ;; delete) delete --target-hostname=$TARGET_HOSTNAME --iscsiserver-hostname=$ISCSISERVER_HOSTNAME --iscsiserver-volume-group=$ISCSISERVER_VOLUME_GROUP --target-root-disk-size=$TARGET_ROOT_DISK_SIZE "$@" || return $? ;; list) list "$@" || return $? ;; purge) purge "$@" || return $? ;; *) usage ;; esac return 0 } create() { local TARGET_HOSTNAME ISCSISERVER_HOSTNAME ISCSISERVER_VOLUME_GROUP TARGET_ROOT_DISK_SIZE # Process options while [ "X$1" != X ]; do case $1 in # Application specific options --target-hostname=*) TARGET_HOSTNAME=${1#*=} ;; --iscsiserver-hostname=*) ISCSISERVER_HOSTNAME=${1#*=} ;; --iscsiserver-volume-group=*) ISCSISERVER_VOLUME_GROUP=${1#*=} ;; --target-root-disk-size=*) TARGET_ROOT_DISK_SIZE=${1#*=} ;; # General options --) shift; break ;; -*) internal "create: $1: invalid option" ;; *) break ;; esac shift done # Process arguments [ $# = 0 ] || internal "create: $#: wrong arg count" # Create entry # (don't do info messages here; better ones can be done later) create_or_delete --target-hostname=$TARGET_HOSTNAME --iscsiserver-hostname=$ISCSISERVER_HOSTNAME --iscsiserver-volume-group=$ISCSISERVER_VOLUME_GROUP --target-root-disk-size=$TARGET_ROOT_DISK_SIZE create || return $? return 0 } delete() { local TARGET_HOSTNAME ISCSISERVER_HOSTNAME ISCSISERVER_VOLUME_GROUP TARGET_ROOT_DISK_SIZE # Process options while [ "X$1" != X ]; do case $1 in # Application specific options --target-hostname=*) TARGET_HOSTNAME=${1#*=} ;; --iscsiserver-hostname=*) ISCSISERVER_HOSTNAME=${1#*=} ;; --iscsiserver-volume-group=*) ISCSISERVER_VOLUME_GROUP=${1#*=} ;; --target-root-disk-size=*) TARGET_ROOT_DISK_SIZE=${1#*=} ;; # General options --) shift; break ;; -*) internal "delete: $1: invalid option" ;; *) break ;; esac shift done # Process arguments [ $# = 0 ] || internal "delete: $#: wrong arg count" # Delete entry # (don't do info messages here; better ones can be done later) create_or_delete --target-hostname=$TARGET_HOSTNAME --iscsiserver-hostname=$ISCSISERVER_HOSTNAME --iscsiserver-volume-group=$ISCSISERVER_VOLUME_GROUP --target-root-disk-size=$TARGET_ROOT_DISK_SIZE delete || return $? return 0 } create_or_delete() { local TARGET_HOSTNAME ISCSISERVER_HOSTNAME ISCSISERVER_VOLUME_GROUP TARGET_ROOT_DISK_SIZE local LVCREATE_OUTPUT VIRSH_OUTPUT IETADM_OUTPUT NEXT_FREE_ISCSI_TID IETADM_CMDLINE ISCSI_TID ISCSI_IQN LV_NAME LV_PATH IOMODE IETCONF_RECORD ISCSI_TID NEXT_FREE_ISCSI_TID ISCSISERVER_VOLUME_GROUP TARGET_ROOT_DISK_SIZE # Process options while [ "X$1" != X ]; do case $1 in # Application specific options --target-hostname=*) TARGET_HOSTNAME=${1#*=} ;; --iscsiserver-hostname=*) ISCSISERVER_HOSTNAME=${1#*=} ;; --iscsiserver-volume-group=*) ISCSISERVER_VOLUME_GROUP=${1#*=} ;; --target-root-disk-size=*) TARGET_ROOT_DISK_SIZE=${1#*=} ;; # General options --) shift; break ;; -*) internal "create_or_delete: $1: invalid option" ;; *) break ;; esac shift done # Process arguments [ $# = 1 ] || internal "create_or_delete: $#: wrong arg count" MODE=$1 # Sanity checks and derivations validate_vars MODE TARGET_HOSTNAME ISCSISERVER_HOSTNAME ISCSISERVER_VOLUME_GROUP TARGET_ROOT_DISK_SIZE || return $? debug 10 "create_or_delete: MODE=$MODE, TARGET_HOSTNAME=$TARGET_HOSTNAME, ISCSISERVER_HOSTNAME=$ISCSISERVER_HOSTNAME, ISCSISERVER_VOLUME_GROUP=$ISCSISERVER_VOLUME_GROUP, TARGET_ROOT_DISK_SIZE=$TARGET_ROOT_DISK_SIZE" check_ssh_access $ISCSISERVER_HOSTNAME || return $? ISCSI_IQN=$(getiqn $ISCSISERVER_HOSTNAME $TARGET_HOSTNAME) || return $? LV_NAME=$TARGET_HOSTNAME LV_PATH=/dev/$ISCSISERVER_VOLUME_GROUP/$LV_NAME IOMODE=blockio IETCONF_RECORD="Target $ISCSI_IQN\\n\\tLun 0 Path=$LV_PATH,Type=$IOMODE\\n" # Guts if [ $MODE = create ]; then info "creating storage volume ..." # Create volume debug 10 "create_or_delete: creating the storage volume ..." LVCREATE_OUTPUT=$(ssh -n $ISCSISERVER_HOSTNAME lvcreate --size ${TARGET_ROOT_DISK_SIZE}G --name $LV_NAME $ISCSISERVER_VOLUME_GROUP 2>&1) || { error "lvcreate: failed (output was: $LVCREATE_OUTPUT)"; return 1; } info "sharing storage volume via iSCSI ..." # Set some iSCSI vars NEXT_FREE_ISCSI_TID=$({ ssh -n $ISCSISERVER_HOSTNAME cat /proc/net/iet/volume | sed -n 's/tid:\([^ ]*\).*/\1/p'; echo 0; } | sort -un | tail -1 | xargs expr 1 +) debug 10 "create_or_delete: ISCSI_IQN=$ISCSI_IQN, NEXT_FREE_ISCSI_TID=$NEXT_FREE_ISCSI_TID, LV_PATH=$LV_PATH, IOMODE=$IOMODE, IETCONF_RECORD=[$IETCONF_RECORD]" # Configure later sharing via iSCSI debug 10 "create_or_delete: adding an entry to the config file to share the volume via iSCSI ..." echo -en "$IETCONF_RECORD" | ssh $ISCSISERVER_HOSTNAME "cat >> /etc/ietd.conf" # Share it right now via iSCSI debug 10 "create_or_delete: running commands to share the volume via iSCSI right now ..." # ietadm doesn't seem to provide good return codes so we must inspect output IETADM_OUTPUT=$(ssh -n $ISCSISERVER_HOSTNAME ietadm --op new --tid=$NEXT_FREE_ISCSI_TID --params Name=$ISCSI_IQN 2>&1) [ "X$IETADM_OUTPUT" = X ] || { error "ietadm: failed (output was: $IETADM_OUTPUT)"; return 1; } IETADM_OUTPUT=$(ssh -n $ISCSISERVER_HOSTNAME ietadm --op new --tid=$NEXT_FREE_ISCSI_TID --lun=0 --params Type=$IOMODE,Path=$LV_PATH 2>&1) [ "X$IETADM_OUTPUT" = X ] || { error "ietadm: failed (output was: $IETADM_OUTPUT)"; return 1; } elif [ $MODE = delete ]; then info "unsharing storage volume via iSCSI ..." # Set some iSCSI vars debug 10 "create_or_delete: setting some iSCSI variables ..." ISCSI_TID=$(ssh -n $ISCSISERVER_HOSTNAME cat /proc/net/iet/volume | sed -n "s/tid:\(.*\) name:$ISCSI_IQN/\1/p") debug 10 "create_or_delete: ISCSI_IQN=$ISCSI_IQN, ISCSI_TID=$ISCSI_TID, LV_PATH=$LV_PATH, IOMODE=$IOMODE, IETCONF_RECORD=[$IETCONF_RECORD]" # Unshare it right now via iSCSI debug 10 "create_or_delete: unsharing right now via iSCSI ..." IETADM_CMDLINE="ietadm --op delete --tid=$ISCSI_TID" debug 10 "create_or_delete: IETADM_CMDLINE=[$IETADM_CMDLINE]" IETADM_OUTPUT=$(ssh $ISCSISERVER_HOSTNAME $IETADM_CMDLINE 2>&1) || warning "ietadm: failed (output was: $IETADM_OUTPUT)" # Unconfigure later sharing via iSCSI debug 10 "create_or_delete: unconfiguring later sharing via iSCSI ..." # Too much stuff to escape, do it locally. scp -q $ISCSISERVER_HOSTNAME:/etc/ietd.conf /tmp perl -0777 -pi -e "s@^$IETCONF_RECORD@@ms" /tmp/ietd.conf scp -q /tmp/ietd.conf $ISCSISERVER_HOSTNAME:/etc # Delete volume info "deleting storage volume ..." debug 10 "create_or_delete: deleting the storage volume ..." LVREMOVE_OUTPUT=$(ssh -n $ISCSISERVER_HOSTNAME lvremove -f /dev/$ISCSISERVER_VOLUME_GROUP/$LV_NAME 2>&1) || warning "lvremove: failed (output was: $LVREMOVE_OUTPUT)" fi return 0 } purge() { # Guts # Too dangerous to do anything! return 0 } list() { local ISCSISERVER_HOSTNAME # Process options while [ "X$1" != X ]; do case $1 in # Application specific options # General options --) shift; break ;; -*) internal "list: $1: invalid option" ;; *) break ;; esac shift done # Process arguments [ $# = 0 ] || internal "list: $#: wrong arg count" # Guts for ISCSISERVER_HOSTNAME in $KNOWN_ISCSISERVER_HOSTNAMES; do # Note grepping out 'lvol', to try to ensure that we only list storage for VMs ssh -n $ISCSISERVER_HOSTNAME lvs | grep -v lvol | sed -e '/^$/d' -e '/^ LV/d' -e "s/^/$ISCSISERVER_HOSTNAME: /" done return 0 } usage() { local RC RC=${1:-1} { echo "Usage: $PROGNAME [ ] { create | delete | list }" echo } | if [ $RC = 0 ]; then cat else cat >&2 fi exit $RC } main "$@"