carbon-config

config submodule of carbon-core-system
git clone https://ccx.te2000.cz/git/carbon-config
Log | Files | Refs

postinstall (5526B)


      1 #!/bin/zsh
      2 setopt no_unset warn_create_global extended_glob
      3 zmodload -F zsh/stat b:zstat || exit $?
      4 zmodload -m -F zsh/files b:zf_\* || exit $?
      5 #zmodload zsh/zutil || exit $?  # for zparseopts
      6 zmodload zsh/datetime || exit $?  # for $EPOCHREALTIME
      7 
      8 die_ret() {
      9 	local ret
     10 	ret=$1
     11 	shift
     12 	printf >&2 '%s\n' "$@"
     13 	exit $ret
     14 }
     15 die() {
     16 	die_ret 1 "$@"
     17 }
     18 die100() {  # 100: wrong usage
     19 	die_ret 100 "$@"
     20 }
     21 die111() {  # 111: system call failed
     22 	die_ret 111 "$@"
     23 }
     24 
     25 ensure_symlink() {
     26 	local target
     27 	if ! [[ -e $1 ]]; then
     28 		s6-ln -s $2 $1 || return $?
     29 	fi
     30 
     31 	if [[ $2 == /* ]]; then
     32 		target=$2:A
     33 	else
     34 		target=$1:h/$2
     35 		target=$target:A
     36 	fi
     37 
     38 	if ! [[ -h $1 ]]; then
     39 		echo >&2 "Error: not a symlink: ${(qqq)1}"
     40 		return 1
     41 	elif [[ $1:A != $target ]]; then
     42 		echo >&2 "Error: ${(qqq)1} points to ${(qqq)1:A} instead of ${(qqq)target}"
     43 		return 1
     44 	fi
     45 }
     46 
     47 symlink_static_file() {
     48 	[[ $1 == /* ]] || die "symlink_static_file: requires absolute path"
     49 	local relative_base up rel1 rel2
     50 	rel1=./conf/static$1
     51 	[[ -f $rel1 ]] || die111 "Cannot symlink: file does not exist: ${(qqq)rel1}"
     52 	relative_base=$1:h
     53 	until [[ ${${:-$relative_base/$up}:P} == / ]] ; do
     54 		up=../$up
     55 	done
     56 	rel2=$relative_base/$up/current/conf/static$1
     57 	[[ $rel1:P == $rel2:P ]] || die "Directory mismatch"
     58 
     59 	if [[ ! -L $1 && -f $1 ]]; then
     60 		mv $1 $1.orig.$EPOCHSECONDS || exit $?
     61 	fi
     62 	ensure_symlink $1 ${up}current/conf/static$1 || return $?
     63 }
     64 
     65 link_changed() {
     66 	local pre post
     67 	if (($+preinstall_current)); then
     68 		pre=${${:-$preinstall_current_p/$1}:P}
     69 	else
     70 		pre=
     71 	fi
     72 	post=${${:-/current/$1}:P}
     73 	[[ "$pre" != "$post" ]]
     74 }
     75 
     76 setup_static_symlinks() {
     77 	symlink_static_file /etc/hostname || return $?
     78 	symlink_static_file /etc/fstab || return $?
     79 	symlink_static_file /etc/profile.d/slashcommand.sh || return $?
     80 	symlink_static_file /etc/mkinitfs/mkinitfs.conf || return $?
     81 	symlink_static_file /etc/ssh/sshd_config || return $?
     82 	symlink_static_file /etc/update-extlinux.conf || return $?
     83 	symlink_static_file /etc/zsh/zshrc.d/90_warn_deploy_ssh_key.zsh || return $?
     84 
     85 	# Not static, generated in ./install
     86 	if [[ ! -L /etc/motd && -f /etc/motd ]]; then
     87 		mv /etc/motd /etc/motd.orig.$EPOCHSECONDS || exit $?
     88 	fi
     89 	ensure_symlink /etc/motd ../current/motd || return $?
     90 }
     91 
     92 setup_skel() {
     93 	./command/link-skel || return $?
     94 }
     95 
     96 setup_storage() {
     97 }
     98 
     99 setup_rc() {
    100 	local diff_ret
    101 	# Check if s6-rc definition changed
    102 	diff --recursive --unified $preinstall_current_p/s6-rc-source ./s6-rc-source; diff_ret=$?
    103 	(( $diff_ret == 0 || $diff_ret == 1 )) || \
    104 		die111 "Could not diff s6-rc-source directories; exitcode $diff_ret"
    105 	if link_changed package; then
    106 		if (( $diff_ret == 1 )); then
    107 			# Both s6-rc DB source and installed software changed.
    108 			# s6-rc-format-upgrade to tmpdir, then s6-rc-update
    109 			local tmp_db=/run/old-s6-rc-db-migration.$EPOCHREALTIME
    110 
    111 			s6-rc-compile $tmp_db $preinstall_current_p/s6-rc-source || return $?
    112 			s6-rc-format-upgrade -v2 $tmp_db || return $?
    113 			s6-rc-update -v2 /current/s6-rc-db/ || return $?
    114 			rm -r $tmp_db || return $?
    115 		else
    116 			# Installed software changed but s6-rc DB source is the same.
    117 			# s6-rc-format-upgrade to new compiled DB directly
    118 			s6-rc-format-upgrade -v2 /current/s6-rc-db/ || return $?
    119 		fi
    120 	elif (( $diff_ret == 1 )); then
    121 		# s6-rc DB source changed while keeping same version of software.
    122 		# s6-rc-update to new compiled DB directly
    123 		s6-rc-update -v2 /current/s6-rc-db/ || return $?
    124 	fi
    125 }
    126 
    127 setup_containers() {
    128 	# Check if we need to regenerate containers or their service directories.
    129 	if link_changed bzr/containers || link_changed bzr/confz; then
    130 		if (( $+confz_verbose )); then
    131 			zsh -lc "verbose=1 confz site_containers" </dev/null 2>&1 | cat -v
    132 			ret=$((${(j.|.)pipestatus}))  # Nonzero iff any of commands in pipeline returned nonzero.
    133 		else
    134 			zsh -lc "quiet=1 confz site_containers" </dev/null 2>&1 | cat -v
    135 			ret=$((${(j.|.)pipestatus}))  # Nonzero iff any of commands in pipeline returned nonzero.
    136 		fi
    137 		if (($ret)); then 
    138 			echo >&2 "Error: command failed ($ret): confz site_containers"
    139 			return $ret
    140 		fi
    141 		s6-svscanctl -a /run/service || return $?
    142 	fi
    143 }
    144 
    145 setup_fileset() {
    146 	local -a rsync=(
    147 		rsync
    148 		-aA
    149 		--delete
    150 		--log-format=$'%i\t%B\t%U:%G\t%M\t%l\t%n'
    151 		--filter='merge conf/postinstall.rsfilter'
    152 		--filter='- *'
    153 	)
    154 	$rsync --delete-excluded --log-file $SETUP_DIR/rsync.log.get / $SETUP_DIR/files.pre/ || return $?
    155 	cp -a --reflink=auto $SETUP_DIR/files.pre $SETUP_DIR/files.post || return $?
    156 	./command/fsapply $SETUP_DIR/files.post $PWD/conf/postinstall.fileset || exit $?
    157 	mkdir $SETUP_DIR/files.bak || return $?
    158 	$rsync --log-file $SETUP_DIR/rsync.log.put $SETUP_DIR/files.post/ / --backup --backup-dir=$SETUP_DIR/files.bak || return $?
    159 }
    160 
    161 postinstall() {
    162 	typeset -g SETUP_DIR=/versions/postinstall/$EPOCHSECONDS.$ALL_DIR:t
    163 	cd $ALL_DIR || exit $?
    164 	mkdir -p $SETUP_DIR
    165 
    166 	ensure_symlink /command current/command || return $?
    167 
    168 	setup_static_symlinks || return $?
    169 
    170 	if [[ -d /run/s6-rc/ ]]; then
    171 		# TODO: determine mountpoint changes
    172 		setup_storage || return $?
    173 		mount -a || return $?
    174 	fi
    175 
    176 	setup_fileset || return $?
    177 
    178 	if [[ -d /run/s6-rc/ ]]; then
    179 		setup_rc || return $?
    180 	fi
    181 
    182 	setup_skel || return $?
    183 	setup_containers || return $?
    184 
    185 	exit 0
    186 }
    187 typeset -ft postinstall
    188 
    189 typeset -g ALL_DIR=$0:h:h
    190 if [[ $ALL_DIR != /versions/all.* ]]; then
    191 	die100 "Fatal: ${(qqq)0}: This script needs to be run from versioned directory as a part of installation procedure."
    192 fi
    193 
    194 path=( $ALL_DIR/command "$path[@]" )
    195 #fpath=( $ALL_DIR/zsh-functions "$fpath[@]" )
    196 postinstall || exit $?