# vim: ft=zsh noet ts=4 sts=4 sw=4 # # confz functions for deploying vservers # # load the zstat builtin and keep stat external zmodload -F zsh/stat b:zstat # deploy filesystem image from directory, rsync or tarball confz_deployed_system_check() { checkvars path source defvar ignore_pattern 'lost+found' local existing_entries fail_reason="${vars[path]}/.confz_deployed missing" if [[ -e ${vars[path]}/.confz_deployed ]]; then return 0 else existing_entries=( ${vars[path]}/*~${vars[path]}/${~vars[ignore_pattern]}(DN) ) if (($#existing_entries)); then die "Found $#existing_entries existing entries in ${vars[path]} but no .confz_deployed" else return 1 fi fi } confz_deployed_system_do() { local result result=0 case ${vars[source]} in (*/) rsync -aAH ${vars[source]} ${vars[path]}/ || return $? ;; (scp:*.(tbz|tbz2|bz2)) scp -q ${vars[source]#scp:} /dev/stdout | bzip2 -d | tar -xpC ${vars[path]} result=$[ $pipestatus[1] | $pipestatus[2] | $pipestatus[3] ] ;; (scp:*.(tgz|gz)) scp -q ${vars[source]#scp:} /dev/stdout | gzip -d | tar -xpC ${vars[path]} result=$[ $pipestatus[1] | $pipestatus[2] | $pipestatus[3] ] ;; (scp:*.xz) scp -q ${vars[source]#scp:} /dev/stdout | xz -d | tar -xpC ${vars[path]} result=$[ $pipestatus[1] | $pipestatus[2] | $pipestatus[3] ] ;; (scp:*) scp -q ${vars[source]#scp:} /dev/stdout | tar -xpC ${vars[path]} result=$[ $pipestatus[1] | $pipestatus[2] ] ;; (sftp:*) mkdir -p /root/.tmp || return $? (cd /root/.tmp && sftp ${vars[source]#sftp:}) || return $? tar -xpC ${vars[path]} -f /root/.tmp/${vars[source]:t} result=$? rm -f /root/.tmp/${vars[source]:t} ;; (*) tar -xpC ${vars[path]} -f ${vars[source]} || return $? ;; esac if (($result)); then return $result fi printf '%s\n' ${vars[source]} >${vars[path]}/.confz_deployed } # create required directories confz_vserver_run_dirs_check() { local -a run_dirs local d run_dirs=( /var/run/{vservers,vservers.rev,vshelper} ) do_command=( mkdir -p $run_dirs ) for d in $run_dirs; do fail_reason="missing directory: ${(q)d}" [[ -d $d ]] || return $? done return 0 } # configure and deploy vserver confz_vserver_check() { checkvars name size context_id source defvar root / setvar etcdir ${vars[root]%/}/etc/vservers/${vars[name]} setvar vdir ${vars[root]%/}/vservers/${vars[name]} local ctx ret local -a fails if [[ -e ${vars[etcdir]}/context ]]; then if [[ $(<${vars[etcdir]}/context) != ${vars[context_id]} ]]; then die "$0: vserver ${(qqq)vars[name]} " \ "has context different from ${(qqq)vars[context_id]}" fi else fails+=( "${vars[etcdir]}/context) missing" ) for ctx in ${vars[root]%/}/etc/vservers/*/context(N); do if [[ $(<$ctx) == ${vars[context_id]} ]]; then die "$0: context id already used by $ctx" fi done fi if ! [[ -e ${vars[etcdir]}/vdir ]]; then fails=( "${vars[etcdir]}/vdir missing" ) elif ! [[ -h ${vars[etcdir]}/vdir ]]; then die "${vars[etcdir]}/vdir is not symlink or missing" fi require mounted_volume :size \?filesystem \?mkfs_opts \ lv_name=vs_$vars[name] \ label=${${vars[name]}[0,12]} \ mountpoint=$vars[vdir] require deployed_system :root :source path=${vars[vdir]} fail_reason="${(j:,:)fails}" return $#fails } confz_vserver_do() { mkdir -p ${vars[etcdir]} || return $? if [[ -h ${vars[etcdir]}/vdir ]]; then rm ${vars[etcdir]}/vdir || return $? fi ln -s $vars[vdir] ${vars[etcdir]}/vdir || return $? print -r - ${vars[context_id]} >${vars[etcdir]}/context } confz_vserver_started_check() { checkvars name require vserver_run_dirs do_command=( vserver -- $vars[name] start ) vserver --silent -- $vars[name] running || return $? local context_id context_id=$(