confz

git mirror of https://ccx.te2000.cz/bzr/confz
git clone https://ccx.te2000.cz/git/confz
Log | Files | Refs

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 }