Display help information in a consistent format. Print error messages and help information to stderr. Prefix error messages with the name of the script (for easier debugging as part of larger scripts).
Allow help information to be printed as a non-root user. Fix file mode for lxc-checkconfig.in. Signed-off-by: David Ward <david.w...@ll.mit.edu> --- src/lxc/lxc-checkconfig.in | 15 +++---- src/lxc/lxc-clone.in | 70 +++++++++++++++----------------- src/lxc/lxc-create.in | 96 ++++++++++++++++++++----------------------- src/lxc/lxc-destroy.in | 40 ++++++++++++------ src/lxc/lxc-setcap.in | 36 +++++++++++----- src/lxc/lxc-setuid.in | 35 ++++++++++----- 6 files changed, 158 insertions(+), 134 deletions(-) mode change 100755 => 100644 src/lxc/lxc-checkconfig.in diff --git a/src/lxc/lxc-checkconfig.in b/src/lxc/lxc-checkconfig.in old mode 100755 new mode 100644 index 39da910..8c2b5e5 --- a/src/lxc/lxc-checkconfig.in +++ b/src/lxc/lxc-checkconfig.in @@ -32,7 +32,7 @@ is_enabled() { } if [ ! -f $CONFIG ]; then - echo "Kernel config $CONFIG not found, looking in other places..." + echo "Kernel configuration not found at $CONFIG; searching..." KVER="`uname -r`" HEADERS_CONFIG="/lib/modules/$KVER/build/.config" BOOT_CONFIG="/boot/config-$KVER" @@ -40,15 +40,14 @@ if [ ! -f $CONFIG ]; then [ -f "${BOOT_CONFIG}" ] && CONFIG=${BOOT_CONFIG} GREP=grep if [ ! -f $CONFIG ]; then - echo - echo "The kernel configuration can not be retrieved." - echo "Please recompile with IKCONFIG_PROC, or" - echo "install the kernel headers, or specify" - echo "the path to the config file with: CONFIG=<path> lxc-checkconfig" - echo + echo "$(basename $0): unable to retrieve kernel configuration" >&2 + echo >&2 + echo "Try recompiling with IKCONFIG_PROC, installing the kernel headers," >&2 + echo "or specifying the kernel configuration path with:" >&2 + echo " CONFIG=<path> $(basename $0)" >&2 exit 1 else - echo "Found kernel config file $CONFIG" + echo "Kernel configuration found at $CONFIG" fi fi diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in index 386be30..c7413f2 100644 --- a/src/lxc/lxc-clone.in +++ b/src/lxc/lxc-clone.in @@ -24,22 +24,24 @@ set -e usage() { - echo "usage: lxc-clone -o <orig> -n <new> [-s] [-h] [-L fssize] [-v vgname] [-p lxc_lv_prefix] [-t fstype]" + echo "usage: $(basename $0) -o ORIG_NAME -n NEW_NAME [-s] [-h] [-L FS_SIZE]" >&2 + echo " [-v VG_NAME] [-p LV_PREFIX] [-t FS_TYPE]" >&2 } help() { usage - echo - echo "creates a lxc system object." - echo - echo "Options:" - echo "orig : name of the original container" - echo "new : name of the new container" - echo "-s : make the new rootfs a snapshot of the original" - echo "fssize : size if creating a new fs. By default, 2G" - echo "vgname : lvm volume group name, lxc by default" - echo "lvprefix : lvm volume name prefix, none by default, e.g. --lvprefix=lxc_ then new lxc lv name will be lxc_newname" - echo "fstype : new container file system type, ext3 by default (only works for non-snapshot lvm)" + echo >&2 + echo "Clone an existing container on the system." >&2 + echo >&2 + echo "Options:" >&2 + echo " -o ORIG_NAME specify the name of the original container" >&2 + echo " -n NEW_NAME specify the name of the new container" >&2 + echo " -s make the new rootfs a snapshot of the original" >&2 + echo " -L FS_SIZE specify the new filesystem size (default: 2G)" >&2 + echo " -v VG_NAME specify the new LVM volume group name (default: lxc)" >&2 + echo " -p LV_PREFIX add a prefix to new LVM logical volume names" >&2 + echo " -t FS_TYPE specify the new filesystem type (default: ext3;" >&2 + echo " only works for non-snapshot LVM)" >&2 } shortoptions='ho:n:sL:v:p:t:' @@ -62,8 +64,8 @@ fi eval set -- "$getopt" while true; do - case "$1" in - -h|--help) + case "$1" in + -h|--help) help exit 1 ;; @@ -102,52 +104,46 @@ while true; do break ;; *) - echo $1 usage exit 1 ;; - esac + esac done if [ -z "$lxc_path" ]; then - echo "no configuration path defined !" + echo "$(basename $0): no configuration path defined" >&2 exit 1 fi if [ ! -r $lxc_path ]; then - echo "configuration path '$lxc_path' not found" + echo "$(basename $0): configuration path '$lxc_path' not found" >&2 exit 1 fi if [ -z "$lxc_orig" ]; then - echo "no original container name specified" + echo "$(basename $0): no original container name specified" >&2 usage exit 1 fi if [ -z "$lxc_new" ]; then - echo "no new container name specified" + echo "$(basename $0): no new container name specified" >&2 usage exit 1 fi if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" + echo "$(basename $0): must be run as root" >&2 exit 1 fi -if [ ! -r $lxc_path ]; then - echo "no configuration path defined !" - exit 1 -fi - if [ ! -d "$lxc_path/$lxc_orig" ]; then - echo "'$lxc_orig' does not exist" + echo "$(basename $0): '$lxc_orig' does not exist" >&2 exit 1 fi if [ -d "$lxc_path/$lxc_new" ]; then - echo "'$lxc_new' already exists" + echo "$(basename $0): '$lxc_new' already exists" >&2 exit 1 fi @@ -166,7 +162,7 @@ cleanup() { if [ $frozen -eq 1 ]; then lxc-unfreeze -n $lxc_orig fi - echo aborted + echo "$(basename $0): aborted" >&2 exit 1 } trap cleanup SIGHUP SIGINT SIGTERM @@ -195,8 +191,8 @@ lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1 || container_running=False sed -i '/lxc.rootfs/d' $lxc_path/$lxc_new/config oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F= '{ print $2 '}` if [ -b $oldroot ]; then - type vgscan || { echo "Please install lvm"; false; } - lvdisplay $oldroot > /dev/null 2>&1 || { echo "non-lvm blockdev cloning not supported"; false; } + type vgscan || { echo "$(basename $0): lvm is not installed" >&2; false; } + lvdisplay $oldroot > /dev/null 2>&1 || { echo "$(basename $0): non-lvm blockdev cloning is not supported" >&2; false; } lvm=TRUE # ok, create a snapshot of the lvm device if [ $container_running = "True" ]; then @@ -211,16 +207,16 @@ if [ -b $oldroot ]; then if [ $snapshot = "no" ]; then #mount snapshot mkdir -p ${rootfs}_snapshot - mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "failed to mount new rootfs_snapshot"; false; } + mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "$(basename $0): failed to mount new rootfs_snapshot" >&2; false; } #create a new lv lvcreate -L $lxc_size $lxc_vg -n ${lxc_lv_prefix}$lxc_new echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $lxc_path/$lxc_new/config # and mount it so we can tweak it mkdir -p $lxc_path/$lxc_new/rootfs mkfs -t $fstype /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new - mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; false; } + mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "$(basename $0): failed to mount new rootfs" >&2; false; } mounted=1 - rsync -ax ${rootfs}_snapshot/ ${rootfs}/ || { echo "copy of data to new lv failed"; false; } + rsync -ax ${rootfs}_snapshot/ ${rootfs}/ || { echo "$(basename $0): copying data to new lv failed" >&2; false; } umount ${rootfs}_snapshot rmdir ${rootfs}_snapshot lvremove -f $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot @@ -229,18 +225,18 @@ if [ -b $oldroot ]; then echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $lxc_path/$lxc_new/config # and mount it so we can tweak it mkdir -p $lxc_path/$lxc_new/rootfs - mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; false; } + mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "$(basename $0): failed to mount new rootfs" >&2; false; } mounted=1 fi elif out=$(btrfs subvolume list "$lxc_path/$lxc_orig/rootfs" 2>&1); then - out=$(btrfs subvolume snapshot "$lxc_path/$lxc_orig/rootfs" "$rootfs" 2>&1) || { echo "failed btrfs snapshot"; false; } + out=$(btrfs subvolume snapshot "$lxc_path/$lxc_orig/rootfs" "$rootfs" 2>&1) || { echo "$(basename $0): btrfs snapshot failed" >&2; false; } echo "lxc.rootfs = $rootfs" >> "$lxc_path/$lxc_new/config" else if [ $snapshot = "yes" ]; then - echo "Can't snapshot a directory" + echo "$(basename $0): cannot snapshot a directory" >&2 cleanup fi if [ $container_running = "True" ]; then diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in index 9b12e5f..bd9a438 100644 --- a/src/lxc/lxc-create.in +++ b/src/lxc/lxc-create.in @@ -21,44 +21,41 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA usage() { - echo "usage: lxc-create -n <name> [-f configuration] [-t template] [-h] [fsopts] -- [template_options]" - echo " fsopts: -B none" - echo " fsopts: -B lvm [--lvname lvname] [--vgname vgname] [--fstype fstype] [--fssize fssize]" - echo " fsopts: -B btrfs" - echo " flag is not necessary, if possible btrfs support will be used" -# echo " fsopts: -B union [--uniontype overlayfs]" -# echo " fsopts: -B loop [--fstype fstype] [--fssize fssize]" -# echo " fsopts: -B qemu-nbd [--type qed|qcow2|raw] [--fstype fstype] [--fssize fssize] # Qemu qed disk format" + echo "usage: $(basename $0) -n NAME [-f CONFIG_FILE] [-t TEMPLATE] [FS_OPTIONS] --" >&2 + echo " [TEMPLATE_OPTIONS]" >&2 + echo >&2 + echo "where FS_OPTIONS is one of:" >&2 + echo " -B none" >&2 + echo " -B lvm [--lvname LV_NAME] [--vgname VG_NAME] [--fstype FS_TYPE]" >&2 + echo " [--fssize FS_SIZE]" >&2 + echo " -B btrfs" >&2 } help() { usage - echo - echo "creates a lxc system object." - echo - echo "Options:" - echo "name : name of the container" - echo "configuration: lxc configuration" - echo "template : lxc-template is an accessible template script" - echo - echo "The container backing store can be altered using '-B'. By default it" - echo "is 'none', which is a simple directory tree under /var/lib/lxc/<name>/rootfs" - echo "Otherwise, the following option values may be relevant:" - echo "lvname : [for -lvm] name of lv in which to create lv," - echo " container-name by default" - echo "vgname : [for -lvm] name of vg in which to create lv, 'lxc' by default" - echo "fstype : name of filesystem to create, ext4 by default" - echo "fssize : size of filesystem to create, 500M by default" - echo + echo >&2 + echo "Create a new container on the system." >&2 + echo >&2 + echo "Options:" >&2 + echo " -n NAME specify the name of the container" >&2 + echo " -f CONFIG_FILE use an existing configuration file" >&2 + echo " -t TEMPLATE use an accessible template script" >&2 + echo " -B BACKING_STORE alter the container backing store (default: none)" >&2 + echo " --lvname LV_NAME specify the LVM logical volume name" >&2 + echo " (default: container name)" >&2 + echo " --vgname VG_NAME specify the LVM volume group name (default: lxc)" >&2 + echo " --fstype FS_TYPE specify the filesystem type (default: ext4)" >&2 + echo " --fssize FS_SIZE specify the filesystem size (default: 500M)" >&2 + echo >&2 if [ -z $lxc_template ]; then - echo "for template-specific help, specify a template, for instance:" - echo "lxc-create -t ubuntu -h" + echo "To see template-specific options, specify a template. For example:" >&2 + echo " $(basename $0) -t ubuntu -h" >&2 exit 0 fi - type ${templatedir}/lxc-$lxc_template >/dev/null - echo - echo "template-specific help follows: (these options follow '--')" + type ${templatedir}/lxc-$lxc_template 2>/dev/null if [ $? -eq 0 ]; then + echo >&2 + echo "Template-specific options (TEMPLATE_OPTIONS):" >&2 ${templatedir}/lxc-$lxc_template -h fi } @@ -133,7 +130,6 @@ while true; do shift break;; *) - echo $1 usage exit 1 ;; @@ -141,17 +137,17 @@ while true; do done if [ -z "$lxc_path" ]; then - echo "no configuration path defined !" + echo "$(basename $0): no configuration path defined" >&2 exit 1 fi if [ ! -r $lxc_path ]; then - echo "configuration path '$lxc_path' not found" + echo "$(basename $0): configuration path '$lxc_path' not found" >&2 exit 1 fi if [ -z "$lxc_name" ]; then - echo "no container name specified" + echo "$(basename $0): no container name specified" >&2 usage exit 1 fi @@ -161,20 +157,20 @@ if [ -z "$lvname" ]; then fi if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" + echo "$(basename $0): must be run as root" >&2 exit 1 fi case "$backingstore" in lvm|none|btrfs|_unset) :;; - *) echo "'$backingstore' is not known ('none', 'lvm', 'btrfs')" + *) echo "$(basename $0): '$backingstore' is not known (try 'none', 'lvm', 'btrfs')" >&2 usage exit 1 ;; esac if [ -d "$lxc_path/$lxc_name" ]; then - echo "'$lxc_name' already exists" + echo "$(basename $0): '$lxc_name' already exists" >&2 exit 1 fi @@ -187,7 +183,7 @@ if [ "$backingstore" = "_unset" -o "$backingstore" = "btrfs" ]; then backingstore="btrfs" else if [ "$backingstore" = "btrfs" ]; then - echo "missing 'btrfs' command or $lxc_path is not btrfs"; + echo "$(basename $0): missing 'btrfs' command or $lxc_path is not btrfs" >&2 exit 1; fi backingstore="none" @@ -197,34 +193,32 @@ fi if [ $backingstore = "lvm" ]; then which vgscan > /dev/null if [ $? -ne 0 ]; then - echo "vgscan not found. Please install lvm2 package" + echo "$(basename $0): vgscan not found (is lvm2 installed?)" >&2 exit 1 fi grep -q "\<$fstype\>" /proc/filesystems if [ $? -ne 0 ]; then - echo "$fstype is not listed in /proc/filesystems" - usage + echo "$(basename $0): $fstype is not listed in /proc/filesystems" >&2 exit 1 fi vgscan | grep -q "Found volume group \"$vgname\"" if [ $? -ne 0 ]; then - echo "Could not find volume group \"$vgname\"" - usage + echo "$(basename $0): could not find volume group \"$vgname\"" >&2 exit 1 fi rootdev=/dev/$vgname/$lvname lvdisplay $rootdev > /dev/null 2>&1 if [ $? -eq 0 ]; then - echo "backing store already exists: $rootdev" - echo "please delete it (using \"lvremove $rootdev\") and try again" + echo "$(basename $0): backing store already exists: $rootdev" >&2 + echo "please delete it (using \"lvremove $rootdev\") and try again" >&2 exit 1 fi elif [ "$backingstore" = "btrfs" ]; then mkdir "$lxc_path/$lxc_name" if ! out=$(btrfs subvolume create "$rootfs" 2>&1); then - echo "failed to create subvolume in $rootfs: $out"; + echo "$(basename $0): failed to create subvolume in $rootfs: $out" >&2 exit 1; fi fi @@ -235,7 +229,7 @@ cleanup() { lvremove -f $rootdev fi ${bindir}/lxc-destroy -n $lxc_name - echo aborted + echo "$(basename $0): aborted" >&2 exit 1 } @@ -247,7 +241,7 @@ if [ -z "$lxc_config" ]; then touch $lxc_path/$lxc_name/config else if [ ! -r "$lxc_config" ]; then - echo "'$lxc_config' configuration file not found" + echo "$(basename $0): '$lxc_config' configuration file not found" >&2 exit 1 fi @@ -265,9 +259,9 @@ fi if [ ! -z $lxc_template ]; then - type ${templatedir}/lxc-$lxc_template >/dev/null + type ${templatedir}/lxc-$lxc_template 2>/dev/null if [ $? -ne 0 ]; then - echo "unknown template '$lxc_template'" + echo "$(basename $0): unknown template '$lxc_template'" >&2 cleanup fi @@ -299,7 +293,7 @@ if [ ! -z $lxc_template ]; then ${templatedir}/lxc-$lxc_template --path=$lxc_path/$lxc_name --name=$lxc_name $* if [ $? -ne 0 ]; then - echo "failed to execute template '$lxc_template'" + echo "$(basename $0): failed to execute template '$lxc_template'" >&2 cleanup fi diff --git a/src/lxc/lxc-destroy.in b/src/lxc/lxc-destroy.in index b0f2da5..76cad86 100644 --- a/src/lxc/lxc-destroy.in +++ b/src/lxc/lxc-destroy.in @@ -26,24 +26,28 @@ # usage() { - echo "usage: $0 -n <name> [-f]" - echo " -f: if a container is running, stop it first. Default is to abort" + echo "usage: $(basename $0) -n NAME [-f]" >&2 } -if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" - exit 1 -fi +help() { + usage + echo >&2 + echo "Remove an existing container on the system." >&2 + echo >&2 + echo "Options:" >&2 + echo " -n NAME specify the name of the container" >&2 + echo " -f stop the container if it is running (rather than abort)" >&2 +} -shortoptions='n:f' -longoptions='name:' +shortoptions='hn:f' +longoptions='help,name:' localstatedir=@LOCALSTATEDIR@ lxc_path=@LXCPATH@ force=0 getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") if [ $? != 0 ]; then - usage $0 + usage exit 1; fi @@ -51,6 +55,10 @@ eval set -- "$getopt" while true; do case "$1" in + -h|--help) + help + exit 1 + ;; -n|--name) shift lxc_name=$1 @@ -64,21 +72,25 @@ while true; do shift break;; *) - echo $1 - usage $0 + usage exit 1 ;; esac done if [ -z "$lxc_name" ]; then - echo "no container name specified" + echo "$(basename $0): no container name specified" >&2 usage $0 exit 1 fi +if [ "$(id -u)" != "0" ]; then + echo "$(basename $0): must be run as root" >&2 + exit 1 +fi + if [ ! -d "$lxc_path/$lxc_name" ]; then - echo "'$lxc_name' does not exist" + echo "$(basename $0): '$lxc_name' does not exist" >&2 exit 1 fi @@ -88,7 +100,7 @@ if [ $? -eq 0 ]; then if [ $force -eq 1 ]; then lxc-stop -n $lxc_name else - echo "Container $lxc_name is running, aborting the deletion." + echo "$(basename $0): '$lxc_name' is running; aborted" >&2 exit 1 fi fi diff --git a/src/lxc/lxc-setcap.in b/src/lxc/lxc-setcap.in index 47954ab..52d4b48 100644 --- a/src/lxc/lxc-setcap.in +++ b/src/lxc/lxc-setcap.in @@ -37,9 +37,17 @@ LXC_RESTART_CAPS="$LXC_START_CAPS,cap_mknod" LXC_CHECKPOINT_CAPS="$LXC_COMMON_CAPS,cap_sys_ptrace,cap_mknod" LXC_DROP_CAPS="" -usage() -{ - echo "lxc-setcap [-d] : set or remove capabilities on the lxc tools" +usage() { + echo "usage: $(basename $0) [-d]" >&2 +} + +help() { + usage + echo >&2 + echo "Set or drop file capabilities on the lxc tools." >&2 + echo >&2 + echo "Options:" >&2 + echo " -d drop file capabilities" >&2 } lxc_setcaps() @@ -69,32 +77,31 @@ lxc_dropcaps() setcap -r @BINDIR@/lxc-netstat setcap -r @BINDIR@/lxc-checkpoint setcap -r @LXCINITDIR@/lxc-init + chmod 0755 @LXCPATH@ } +shortoptions='hd' +longoptions='help' libdir=@LIBDIR@ localstatedir=@LOCALSTATEDIR@ -if [ "$(id -u)" != "0" ]; then - echo "You have to be root to run this script" - exit 1 -fi - +getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") if [ $? != 0 ]; then usage exit 1 fi -set -- $(getopt dh "$@") +eval set -- "$getopt" -for i in "$@"; do +while true; do case "$1" in -d) LXC_DROP_CAPS="yes" shift ;; - -h) - usage + -h|--help) + help exit 0 ;; --) @@ -108,6 +115,11 @@ for i in "$@"; do esac done; +if [ "$(id -u)" != "0" ]; then + echo "$(basename $0): must be run as root" >&2 + exit 1 +fi + if [ -z "$LXC_DROP_CAPS" ]; then lxc_setcaps else diff --git a/src/lxc/lxc-setuid.in b/src/lxc/lxc-setuid.in index 00870a8..0919eac 100644 --- a/src/lxc/lxc-setuid.in +++ b/src/lxc/lxc-setuid.in @@ -25,9 +25,17 @@ # When the capabilities are set, a non root user can manage the containers. # -usage() -{ - echo "lxc-setuid [-d] : set or remove setuid on the lxc tools" +usage() { + echo "usage: $(basename $0) [-d]" >&2 +} + +help() { + usage + echo >&2 + echo "Set or drop the setuid attribute on the lxc tools." >&2 + echo >&2 + echo "Options:" >&2 + echo " -d drop the setuid attribute" >&2 } setuid() @@ -70,29 +78,27 @@ lxc_dropuid() chmod 0755 @LXCPATH@ } +shortoptions='hd' +longoptions='help' libdir=@LIBDIR@ localstatedir=@LOCALSTATEDIR@ -if [ "$(id -u)" != "0" ]; then - echo "You have to be root to run this script" - exit 1 -fi - +getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") if [ $? != 0 ]; then usage exit 1 fi -set -- $(getopt dh "$@") +eval set -- "$getopt" -for i in "$@"; do +while true; do case "$1" in -d) LXC_DROP_CAPS="yes" shift ;; - -h) - usage + -h|--help) + help exit 0 ;; --) @@ -106,6 +112,11 @@ for i in "$@"; do esac done; +if [ "$(id -u)" != "0" ]; then + echo "$(basename $0): must be run as root" >&2 + exit 1 +fi + if [ -z "$LXC_DROP_CAPS" ]; then lxc_setuid else -- 1.7.1 ------------------------------------------------------------------------------ Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service. http://www.accelacomm.com/jaw/sfnl/114/51521223/ _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel