confz_vserver_init (5854B)
1 # vim: ft=zsh noet ts=4 sts=4 sw=4 2 3 # 4 # confz functions for deploying vservers 5 # 6 7 # load the zstat builtin and keep stat external 8 zmodload -F zsh/stat b:zstat 9 10 # deploy filesystem image from directory, rsync or tarball 11 confz_deployed_system_check() { 12 checkvars path source 13 defvar ignore_pattern 'lost+found' 14 local existing_entries 15 16 fail_reason="${vars[path]}/.confz_deployed missing" 17 if [[ -e ${vars[path]}/.confz_deployed ]]; then 18 return 0 19 else 20 existing_entries=( ${vars[path]}/*~${vars[path]}/${~vars[ignore_pattern]}(DN) ) 21 if (($#existing_entries)); then 22 die "Found $#existing_entries existing entries in ${vars[path]} but no .confz_deployed" 23 else 24 return 1 25 fi 26 fi 27 } 28 29 confz_deployed_system_do() { 30 local result 31 result=0 32 case ${vars[source]} in 33 (*/) 34 rsync -aAH ${vars[source]} ${vars[path]}/ || return $? 35 ;; 36 (scp:*.(tbz|tbz2|bz2)) 37 scp -q ${vars[source]#scp:} /dev/stdout | bzip2 -d | tar -xpC ${vars[path]} 38 result=$[ $pipestatus[1] | $pipestatus[2] | $pipestatus[3] ] 39 ;; 40 (scp:*.(tgz|gz)) 41 scp -q ${vars[source]#scp:} /dev/stdout | gzip -d | tar -xpC ${vars[path]} 42 result=$[ $pipestatus[1] | $pipestatus[2] | $pipestatus[3] ] 43 ;; 44 (scp:*.xz) 45 scp -q ${vars[source]#scp:} /dev/stdout | xz -d | tar -xpC ${vars[path]} 46 result=$[ $pipestatus[1] | $pipestatus[2] | $pipestatus[3] ] 47 ;; 48 (scp:*) 49 scp -q ${vars[source]#scp:} /dev/stdout | tar -xpC ${vars[path]} 50 result=$[ $pipestatus[1] | $pipestatus[2] ] 51 ;; 52 (sftp:*) 53 mkdir -p /root/.tmp || return $? 54 (cd /root/.tmp && sftp ${vars[source]#sftp:}) || return $? 55 tar -xpC ${vars[path]} -f /root/.tmp/${vars[source]:t} 56 result=$? 57 rm -f /root/.tmp/${vars[source]:t} 58 ;; 59 (*) 60 tar -xpC ${vars[path]} -f ${vars[source]} || return $? 61 ;; 62 esac 63 if (($result)); then 64 return $result 65 fi 66 printf '%s\n' ${vars[source]} >${vars[path]}/.confz_deployed 67 } 68 69 # create required directories 70 confz_vserver_run_dirs_check() { 71 local -a run_dirs 72 local d 73 run_dirs=( /var/run/{vservers,vservers.rev,vshelper} ) 74 do_command=( mkdir -p $run_dirs ) 75 76 for d in $run_dirs; do 77 fail_reason="missing directory: ${(q)d}" 78 [[ -d $d ]] || return $? 79 done 80 return 0 81 } 82 83 # configure and deploy vserver 84 confz_vserver_check() { 85 checkvars name size context_id source 86 defvar root / 87 88 setvar etcdir ${vars[root]%/}/etc/vservers/${vars[name]} 89 setvar vdir ${vars[root]%/}/vservers/${vars[name]} 90 91 local ctx ret 92 local -a fails 93 94 if [[ -e ${vars[etcdir]}/context ]]; then 95 if [[ $(<${vars[etcdir]}/context) != ${vars[context_id]} ]]; then 96 die "$0: vserver ${(qqq)vars[name]} " \ 97 "has context different from ${(qqq)vars[context_id]}" 98 fi 99 else 100 fails+=( "${vars[etcdir]}/context) missing" ) 101 for ctx in ${vars[root]%/}/etc/vservers/*/context(N); do 102 if [[ $(<$ctx) == ${vars[context_id]} ]]; then 103 die "$0: context id already used by $ctx" 104 fi 105 done 106 fi 107 if ! [[ -e ${vars[etcdir]}/vdir ]]; then 108 fails=( "${vars[etcdir]}/vdir missing" ) 109 elif ! [[ -h ${vars[etcdir]}/vdir ]]; then 110 die "${vars[etcdir]}/vdir is not symlink or missing" 111 fi 112 113 require mounted_volume :size \?filesystem \?mkfs_opts \ 114 lv_name=vs_$vars[name] \ 115 label=${${vars[name]}[0,12]} \ 116 mountpoint=$vars[vdir] 117 118 require deployed_system :root :source path=${vars[vdir]} 119 120 fail_reason="${(j:,:)fails}" 121 return $#fails 122 } 123 124 confz_vserver_do() { 125 mkdir -p ${vars[etcdir]} || return $? 126 if [[ -h ${vars[etcdir]}/vdir ]]; then 127 rm ${vars[etcdir]}/vdir || return $? 128 fi 129 ln -s $vars[vdir] ${vars[etcdir]}/vdir || return $? 130 print -r - ${vars[context_id]} >${vars[etcdir]}/context 131 } 132 133 confz_vserver_started_check() { 134 checkvars name 135 require vserver_run_dirs 136 do_command=( vserver -- $vars[name] start ) 137 vserver --silent -- $vars[name] running || return $? 138 local context_id 139 context_id=$(</etc/vservers/$vars[name]/run) 140 if ! (($+vars[context_id])); then 141 vars[context_id]=$context_id 142 elif (( $vars[context_id] != $context_id )); then 143 die "vserver ${(qqq)name} running under context id $context_id, expected $vars[context_id]" 144 fi 145 } 146 147 confz_vserver_stopped_check() { 148 checkvars name 149 do_command=( vserver -- $vars[name] stop ) 150 vserver --silent -- $vars[name] running 151 (( $? == 1 )) 152 } 153 154 confz_vserver_listconfigs_hook_check() { 155 checkvars name 156 157 (($+commands[vserver-listconfigs])) || \ 158 die "can't find vserver-listconfigs in \$PATH" 159 160 [[ -x /etc/vservers/$vars[name]/scripts/post-start.d/vserver-listconfigs ]] 161 } 162 163 confz_vserver_listconfigs_hook_do() { 164 local lnk 165 lnk=/etc/vservers/$vars[name]/scripts/post-start.d/vserver-listconfigs 166 mkdir -p $lnk:h || return $? 167 ln -s $commands[vserver-listconfigs] $lnk || return $? 168 } 169 170 171 confz_vserver_autorestart_check() { 172 checkvars name 173 174 require vserver_listconfigs_hook :name 175 require vserver_started :name %context_id 176 177 do_command=( vserver -- $vars[name] condrestart ) 178 179 local -a files mtab vdir failures 180 local fname mtab_list files_list 181 182 vdir=/etc/vservers/$vars[name]/vdir 183 vdir=$vdir:A 184 mtab_list=/var/run/vservers/$vars[name].mtab 185 files_list=/var/run/vservers/$vars[name].files 186 187 if ! [[ -f $mtab_list ]]; then 188 fail_reason="file $mtab_list not found" 189 return 1 190 fi 191 192 if ! [[ -f $files_list ]]; then 193 fail_reason="file $files_list not found" 194 return 1 195 fi 196 197 mtab="$(grep '^[^ ]* '$vdir'[/ ]' /etc/mtab)" 198 [[ $mtab == "$(</var/run/vservers/$vars[name].mtab)" ]] || \ 199 failures+=( "changes in mountpoints detected over ${(qqq)vdir}" ) 200 201 while IFS= read fname; do 202 [[ -e $fname ]] || failures+=( "missing file: ${(qqq)fname}" ) 203 [[ $files_list -nt $fname ]] || failures+=( 204 "${(qqq)fname} changed since vserver start" 205 ) 206 done <$files_list 207 208 fail_reason=${(j:, :)failures} 209 return $#failures 210 } 211 212 213 confz_vserver_autorestart_default_check() { 214 local mark 215 216 for mark in /etc/vservers/*/apps/init/mark(N); do 217 if [[ $(<$mark) == default ]]; then 218 require vserver_autorestart name=$mark:h:h:h:t 219 fi 220 done 221 }