=== modified file 'bin/confz' --- bin/confz 2014-06-19 14:42:02 +0000 +++ bin/confz 2014-06-19 13:00:37 +0000 @@ -1,18 +1,16 @@ #!/bin/zsh # vim: ft=zsh noet ts=4 sts=4 sw=4 -setopt extended_glob warn_create_global - -typeset -gA vars vars_prev -typeset -ga do_command - -# helper that prints out error message and exits +setopt extendedglob warn_create_global + +typeset -gA vars +typeset -g c c_prev + die() { - print -r - "$@" >&2 + print -r - "$@" exit 1 } -# autoload all relevant functions and run confz_*_init confz_load() { local func local -a match mbegin mend confz_functions func_files @@ -33,72 +31,46 @@ done } -# check & run a dependency require() { - # usage: require [] [-- ] - # where: - # is a dependency name as defined by function confz__check - # are variable assignments in the form of: - # foo=bar -- sets ${vars[foo]} in calee to value "bar" - # :foo -- passes ${vars[foo]} from caller to calee - # %foo -- passes ${vars[foo]} from callee to caller - # %foo=bar -- passes ${vars[foo]} from callee - # to variable ${vars[bar]} of caller - # are arguments passed to the dependency function - - local name outer inner - local -a do_command_prev - local -A vars_switch lift + local name arg c_switch + local -a lift + + c_prev=$c + c=${(j: :)${(q)*}} name=$1 shift - # store $vars - vars_prev=( "${(kv)vars[@]}" ) - vars=( ) - - # parse variable assignments while $(($#)); do + # TODO: nice regexps here case $1 in - (:*) vars[${1#:}]=vars_prev[${1#:}];; - (%*=*) lift[${${1#%}%%=*}]=${${1#%}#*=};; - (%*) lift[${1#%}]=${1#%};; - (*=*) vars[${1%%=*}]=${1#*=};; - (--) break;; - (*) die "$name: unrecognised argument: ${(qqq)1}";; + (:*) vars[$c\|${1#:}]=vars[$c_prev\|${1#:}];; + (%*) lift+=( ${1#%} );; + (*=*) vars[$c\|${1%%=*}]=${1#*=};; + (--) break;; + (*) die "$name: unrecognised argument: ${(qqq)1}";; esac shift done - # store old $do_command - do_command_prev=( "${do_command[@]}" ) - do_command=( confz_${name}_do ) - - # perform check & run if confz_${name}_check "$@"; then - "${do_command[@]}" "$@" || die "$name: command failed with error $?" + confz_${name}_do "$@" || die "$name: failed with error $?" fi confz_${name}_check "$@" || die "$name: check failed with error $?" - # restore $do_command - do_command=( "${do_command_prev[@]}" ) - - # lift %variables from calee to caller - for outer inner in ${(kv)lift}; do - vars_prev[$outer]=vars[$inner] + for arg in $lift; do + vars[$c_prev\|$arg]=vars[$c\|$arg] done - # restore old $vars and put calee's $vars into $vars_prev - vars_switch=( "${(kv)vars[@]}" ) - vars=( "${(kv)vars_prev[@]}" ) - vars_prev=( "${(kv)vars_switch[@]}" ) + c_switch=$c + c=$c_prev + c_prev=$c_switch } -# "dependency" that represents toplevel and gets it's deps out of argv confz_main_check() { local arg local -a args - for arg in "$@"; do + for arg in $argv; do if [[ $arg == ';' ]]; then require $args args=() @@ -109,10 +81,8 @@ $(( $#args )) && require $args } -# noop for the toplevel, functionality is in the dependencies confz_main_do() { true } -# run the toplevel -require main -- "$@" +require main === modified file 'zsh-functions/confz_fs_init' --- zsh-functions/confz_fs_init 2014-06-19 14:42:02 +0000 +++ zsh-functions/confz_fs_init 2014-06-19 13:00:37 +0000 @@ -1,57 +1,45 @@ # vim: ft=zsh noet ts=4 sts=4 sw=4 -# -# confz functions for dealing with filesystem and mounting -# - - -# configure LVM2 logical volume -confz_logical_volume_check() { - [[ -n ${vars[vg_name]:=$DEFAULT_VG} ]] || \ +confz_lv_check() { + [[ -n ${vars[$c\|vg_name]:=$DEFAULT_VG} ]] || \ die "$0: DEFAULT_VG is unset and no 'vg_name' was passed" - [[ -n ${vars[size]:=$DEFAULT_VOLUME_SIZE} ]] || \ + [[ -n ${vars[$c\|size]:=$DEFAULT_VOLUME_SIZE} ]] || \ die "$0: DEFAULT_VOLUME_SIZE is unset and no 'size' was passed" - [[ -n ${vars[lv_name]} ]] || \ + [[ -n ${vars[$c\|lv_name]} ]] || \ die "$0: no 'lv_name' was passed" - vars[device]=/dev/mapper/${DEFAULT_VG}-$1 - - do_command=( - lvcreate - --name ${vars[lv_name]} - --size ${vars[size]} - ${vars[vg_name]} - ) - - [[ -b ${vars[device]} ]] -} - - -# create filesystem on block device -confz_filesystem_check() { - [[ -n ${vars[device]} ]] || \ + vars[$c\|device]=/dev/mapper/${DEFAULT_VG}-$1 + [[ -b ${vars[$c\|device]} ]] +} + +confz_lv_do() { + lvcreate \ + --name ${vars[$c\|lv_name]} \ + --size ${vars[$c\|size]} \ + ${vars[$c\|vg_name]} +} + + +confz_mkfs_check() { + [[ -n ${vars[$c\|device]} ]] || \ die "$0: no 'device' was passed" - [[ -n ${vars[filesystem]:=$DEFAULT_FS} ]] || \ + [[ -n ${vars[$c\|filesystem]:=$DEFAULT_FS} ]] || \ die "$0: DEFAULT_FS is unset and no 'filesystem' was passed" - [[ -n ${vars[label]} ]] || \ + [[ -n ${vars[$c\|label]} ]] || \ die "$0: no 'label' was passed" - [[ -b ${vars[device]} ]] || \ - die "$0: not a block device: ${(qqq)vars[device]}" - - do_command=( - mkfs -t ${vars[filesystem]} -L ${vars[label]} ${vars[device]} - ) + [[ -b ${vars[$c\|device]} ]] || \ + die "$0: not a block device: ${(qqq)vars[$c\|device]}" local tries blk_out DEVNAME LABEL UUID TYPE tries=10 while $((tries)); do - blk_out=$(blkid -o export ${vars[device]}) + blk_out=$(blkid -o export ${vars[$c\|device]}) case $? in (0) break;; (2) ;; @@ -62,51 +50,49 @@ [[ -z $blk_out ]] && return 1 # nothing found on the device eval $blk_out - [[ $LABEL == ${vars[label]} && $TYPE == xfs ]] && return 0 - die "$0: filesystem already present on ${(qqq)vars[device]}!" -} - - -# put mountpoint for device into /etc/fstab + [[ $LABEL == ${vars[$c\|label]} && $TYPE == xfs ]] && return 0 + die "$0: filesystem already present on ${(qqq)vars[$c\|device]}!" +} + +confz_mkfs_do() { + mkfs -t ${vars[$c\|filesystem]} -L ${vars[$c\|label]} ${vars[$c\|device]} +} + + confz_fstab_check() { - [[ -n ${vars[device]} ]] || \ + [[ -n ${vars[$c\|device]} ]] || \ die "$0: no 'device' was passed" - [[ -n ${vars[mountpoint]} ]] || \ + [[ -n ${vars[$c\|mountpoint]} ]] || \ die "$0: no 'mountpoint' was passed" - [[ -n ${vars[filesystem]} ]] || \ + [[ -n ${vars[$c\|filesystem]} ]] || \ die "$0: no 'filesystem' was passed" - [[ -n ${vars[opts]} ]] || \ + [[ -n ${vars[$c\|opts]} ]] || \ die "$0: no 'opts' was passed" - : ${vars[dump]:=0} - : ${vars[pass]:=2} + : ${vars[$c\|dump]:=0} + : ${vars[$c\|pass]:=2} local device mountpoint filesystem opts dump pass sed '/^[ \t]*#/d;s/#.*//;s/[ \t]\+/ /g' /etc/fstab | \ while read device mountpoint filesystem opts dump pass; do - if [[ $mountpoint == ${vars[mountpoint]} ]]; then - [[ $device == ${vars[device]} ]] || \ - die "$0: $mountpoint already present" \ - "with different device than ${(qqq)vars[device]}" - - [[ $filesystem == ${vars[filesystem]} ]] || \ - die "$0: $mountpoint already present" \ - "with different filesystem than ${(qqq)vars[filesystem]}" - - [[ $opts == ${vars[opts]} ]] || \ - die "$0: $mountpoint already present" \ - "with different opts than ${(qqq)vars[opts]}" - - [[ $dump == ${vars[dump]} ]] || \ - die "$0: $mountpoint already present" \ - "with different dump than ${(qqq)vars[dump]}" - - [[ $pass == ${vars[pass]} ]] || \ - die "$0: $mountpoint already present" \ - "with different pass than ${(qqq)vars[pass]}" + if [[ $mountpoint == ${vars[$c\|mountpoint]} ]]; then + [[ $device == ${vars[$c\|device]} ]] || \ + die "$0: $mountpoint already present with different device" + + [[ $filesystem == ${vars[$c\|filesystem]} ]] || \ + die "$0: $mountpoint already present with different filesystem" + + [[ $opts == ${vars[$c\|opts]} ]] || \ + die "$0: $mountpoint already present with different opts" + + [[ $dump == ${vars[$c\|dump]} ]] || \ + die "$0: $mountpoint already present with different dump" + + [[ $pass == ${vars[$c\|pass]} ]] || \ + die "$0: $mountpoint already present with different pass" return 0 # found matching entry fi @@ -115,46 +101,41 @@ } confz_fstab_do() { - print -r - >>/etc/fstab "${vars[device]} ${vars[mountpoint]} ${vars[filesystem]} ${vars[opts]} ${vars[dump]} ${vars[pass]}" + print -r - >>/etc/fstab "${vars[$c\|device]} ${vars[$c\|mountpoint]} ${vars[$c\|filesystem]} ${vars[$c\|opts]} ${vars[$c\|dump]} ${vars[$c\|pass]}" } -# make device mounted on mountpoint confz_mounted_check() { - [[ -n ${vars[device]} ]] || \ + [[ -n ${vars[$c\|device]} ]] || \ die "$0: no 'device' was passed" - [[ -n ${vars[mountpoint]} ]] || \ + [[ -n ${vars[$c\|mountpoint]} ]] || \ die "$0: no 'mountpoint' was passed" - grep -q "^${vars[device]} ${vars[mountpoint]} " /proc/mounts -} - -confz_mounted_check() { - mkdir -p ${vars[mountpoint]} || return $? - mount "$@" ${vars[device]} ${vars[mountpoint]} -} - - -# create LVM2 logical volume, and make sure it's in fstab and mounted + grep -q "^${vars[$c\|device]} ${vars[$c\|mountpoint]} " /proc/mounts +} + +confz_mounted_do() { + mount ${vars[$c\|device]} ${vars[$c\|mountpoint]} +} + + confz_mounted_volume_check() { - [[ -n ${vars[lv_name]} ]] || \ + [[ -n ${vars[$c\|lv_name]} ]] || \ die "$0: no 'lv_name' was passed" - [[ -n ${vars[mountpoint]} ]] || \ + [[ -n ${vars[$c\|mountpoint]} ]] || \ die "$0: no 'mountpoint' was passed" - [[ -n ${vars[size]} ]] || \ + [[ -n ${vars[$c\|size]} ]] || \ die "$0: no 'size' was passed" - : ${vars[filesystem]:=xfs} - : ${vars[opts]:=noatime} - : ${vars[label]:=${vars[lv_name]}} + : ${vars[$c\|filesystem]:=xfs} + : ${vars[$c\|opts]:=noatime} + : ${vars[$c\|label]:=${vars[$c\|lv_name]}} - require logical_volume %device :vg_name :size :lv_name - require filesystem :device :label :filesystem + require lv %device :vg_name :size :lv_name + require mkfs :device :label :filesystem require fstab :device :mountpoint :filesystem :opts :dump :pass require mounted :device :mountpoint - - do_command=( true ) } === removed file 'zsh-functions/confz_vserver_init' --- zsh-functions/confz_vserver_init 2014-06-19 14:42:02 +0000 +++ zsh-functions/confz_vserver_init 1970-01-01 00:00:00 +0000 @@ -1,75 +0,0 @@ -# vim: ft=zsh noet ts=4 sts=4 sw=4 - -# -# confz functions for deploying vservers -# - - -# deploy filesystem image from directory, rsync or tarball -confz_deployed_system_check() { - [[ -n ${vars[path]} ]] || \ - die "$0: no 'path' was passed" - - [[ -n ${vars[source]} ]] || \ - die "$0: no 'source' was passed" - - if [[ ${vars[source]} == */ ]]; then - do_command=( rsync -aAH ${vars[source]} ${vars[path]}/ ) - else - do_command=( tar -pC ${vars[path]} -f ${vars[source]} ) - fi - - [[ -e ${vars[path]}/bin ]] -} - - - -# configure and deploy vserver -confz_vserver_check() { - [[ -n ${vars[name]} ]] || \ - die "$0: no 'name' was passed" - - [[ -n ${vars[size]} ]] || \ - die "$0: no 'size' was passed" - - [[ -n ${vars[context_id]} ]] || \ - die "$0: no 'context_id' was passed" - - [[ -n ${vars[source]} ]] || \ - die "$0: no 'source' was passed" - - vars[etcdir]=/etc/vservers/${vars[name]} - vars[vdir]=/vservers/${vars[name]} - - local ctx run - run=1 - - if [[ -e ${vars[etcdir]}/context ]]; then - if [[ $(<${vars[etcdir]}/context) == ${vars[context_id]} ]]; then - run=0 - else - die "$0: vserver ${(qqq)vars[name]} " \ - "has context different from ${(qqq)vars[context_id]}" - fi - for ctx in /etc/vservers/*/context; do - if [[ $(<$ctx) == ${vars[context_id]} ]]; then - die "$0: context id already used by $ctx" - fi - done - fi - [[ -l ${vars[etcdir]}/vdir ]] || run=1 - - require mounted_volume :name :size :filesystem mountpoint=${vars[vdir]} - require deployed_system :source path=${vars[vdir]} - - return $run -} - -confz_vserver_do() { - mkdir -p ${vars[etcdir]} || return $? - if [[ -l ${vars[etcdir]}/vdir ]]; then - rm ${vars[etcdir]}/vdir || return $? - ln -s $vars[vdir] ${vars[etcdir]}/vdir || return $? - fi - print -r - ${vars[context_id]} >${vars[etcdir]}/context -}