commit c94ce73d34773a007e88bcee9b4f9c2126ec58b5 Author: Jan Pobrislo <ccx@webprojekty.cz> Date: Thu, 19 Jun 2014 15:00:37 +0200 initial commit Diffstat:
| A | bin/confz | | | 88 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | zsh-functions/confz_fs_init | | | 141 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 229 insertions(+), 0 deletions(-)
diff --git a/bin/confz b/bin/confz @@ -0,0 +1,88 @@ +#!/bin/zsh +# vim: ft=zsh noet ts=4 sts=4 sw=4 + +setopt extendedglob warn_create_global + +typeset -gA vars +typeset -g c c_prev + +die() { + print -r - "$@" + exit 1 +} + +confz_load() { + local func + local -a match mbegin mend confz_functions func_files + + func_files=( $^fpath/confz_*(N) ) + + for func in $func_files ; do + if ! [[ -r "$func" ]]; then + print -r >&2 - "$func is not readable" + continue + fi + autoload -Uz $func:t + confz_functions+=$func:t + done + + for func in ${(o)confz_functions}; do + [[ $func == *_init ]] && $func + done +} + +require() { + local name arg c_switch + local -a lift + + c_prev=$c + c=${(j: :)${(q)*}} + + name=$1 + shift + + while $(($#)); do + # TODO: nice regexps here + case $1 in + (:*) vars[$c\|${1#:}]=vars[$c_prev\|${1#:}];; + (%*) lift+=( ${1#%} );; + (*=*) vars[$c\|${1%%=*}]=${1#*=};; + (--) break;; + (*) die "$name: unrecognised argument: ${(qqq)1}";; + esac + shift + done + + if confz_${name}_check "$@"; then + confz_${name}_do "$@" || die "$name: failed with error $?" + fi + confz_${name}_check "$@" || die "$name: check failed with error $?" + + for arg in $lift; do + vars[$c_prev\|$arg]=vars[$c\|$arg] + done + + c_switch=$c + c=$c_prev + c_prev=$c_switch +} + +confz_main_check() { + local arg + local -a args + for arg in $argv; do + if [[ $arg == ';' ]]; then + require $args + args=() + else + args+=( $arg ) + fi + done + $(( $#args )) && require $args +} + +confz_main_do() { + true +} + +require main diff --git a/zsh-functions/confz_fs_init b/zsh-functions/confz_fs_init @@ -0,0 +1,141 @@ +# vim: ft=zsh noet ts=4 sts=4 sw=4 + +confz_lv_check() { + [[ -n ${vars[$c\|vg_name]:=$DEFAULT_VG} ]] || \ + die "$0: DEFAULT_VG is unset and no 'vg_name' was passed" + + [[ -n ${vars[$c\|size]:=$DEFAULT_VOLUME_SIZE} ]] || \ + die "$0: DEFAULT_VOLUME_SIZE is unset and no 'size' was passed" + + [[ -n ${vars[$c\|lv_name]} ]] || \ + die "$0: no 'lv_name' was passed" + + 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[$c\|filesystem]:=$DEFAULT_FS} ]] || \ + die "$0: DEFAULT_FS is unset and no 'filesystem' was passed" + + [[ -n ${vars[$c\|label]} ]] || \ + die "$0: no 'label' was passed" + + [[ -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[$c\|device]}) + case $? in + (0) break;; + (2) ;; + (*) die "$0: error $? from blkid";; + esac + tries=$[$tries - 1] + done + + [[ -z $blk_out ]] && return 1 # nothing found on the device + eval $blk_out + [[ $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[$c\|device]} ]] || \ + die "$0: no 'device' was passed" + + [[ -n ${vars[$c\|mountpoint]} ]] || \ + die "$0: no 'mountpoint' was passed" + + [[ -n ${vars[$c\|filesystem]} ]] || \ + die "$0: no 'filesystem' was passed" + + [[ -n ${vars[$c\|opts]} ]] || \ + die "$0: no 'opts' was passed" + + : ${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[$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 + done + return 1 # did not find matching entry +} + +confz_fstab_do() { + print -r - >>/etc/fstab "${vars[$c\|device]} ${vars[$c\|mountpoint]} ${vars[$c\|filesystem]} ${vars[$c\|opts]} ${vars[$c\|dump]} ${vars[$c\|pass]}" +} + + +confz_mounted_check() { + [[ -n ${vars[$c\|device]} ]] || \ + die "$0: no 'device' was passed" + + [[ -n ${vars[$c\|mountpoint]} ]] || \ + die "$0: no 'mountpoint' was passed" + + 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[$c\|lv_name]} ]] || \ + die "$0: no 'lv_name' was passed" + + [[ -n ${vars[$c\|mountpoint]} ]] || \ + die "$0: no 'mountpoint' was passed" + + [[ -n ${vars[$c\|size]} ]] || \ + die "$0: no 'size' was passed" + + : ${vars[$c\|filesystem]:=xfs} + : ${vars[$c\|opts]:=noatime} + : ${vars[$c\|label]:=${vars[$c\|lv_name]}} + + 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 +}