# vim: ft=zsh noet ts=4 sts=4 sw=4 # # confz functions for PostgreSQL # config-protect-mv() { local n dst base if [[ -d $2 ]]; then dst=${2%/}/$1:t else dst=$2 fi if ! [[ -e $dst ]]; then confz_do mv "$1" "$dst" return $? fi n=0 base=$dst:t dst="$dst:h/$(printf "._cfg%04d_%s" $n $base)" while [[ -e $dst ]]; do n=$[ $n + 1 ] dst="$dst:h/$(printf "._cfg%04d_%s" $n $base)" (( $n > 9999 )) && die "can not config-protect $dst:t/$base" done confz_do mv "$1" "$dst" } confz_postgresql_cluster_check() { checkvars data_dir defvar owner postgres defvar pgdata $vars[data_dir] defvar locale en_US.UTF-8 defvar initdb initdb defvar initdb_opts '' [[ -d $vars[data_dir]/base && -e $vars[pgdata]/postgresql.conf ]] } confz_postgresql_cluster_do() { confz_do mkdir -p $vars[data_dir] $vars[pgdata] || return $? confz_do chown -Rf $vars[owner]: $vars[data_dir] || return $? confz_do chmod 0700 $vars[data_dir] || return $? confz_do su $vars[owner] -c "$vars[initdb] --locale=${(qqq)vars[locale]} --pgdata=${(qqq)vars[data_dir]} $vars[initdb_opts]" || return $? local cfg if ! [[ $vars[data_dir] == $vars[pgdata] ]]; then for cfg in $vars[data_dir]/*.conf(N); do confz_do config-protect-mv $cfg $vars[pgdata]/ done fi return 0 } confz_postgresql_cluster_slot_check() { checkvars slot require postgresql_cluster \?owner \?locale \?initdb_opts \ pgdata="/etc/postgresql-$vars[slot]/" \ data_dir="/var/lib/postgresql/$vars[slot]/data" \ initdb="/usr/lib/postgresql-$vars[slot]/bin/initdb" } confz_postgresql_user_check() { checkvars name defvar user postgres defvar psql psql defvar createuser createuser defvar allow_createdb 0 defvar allow_createrole 0 defvar allow_replication 0 defvar allow_login 1 defvar superuser 0 local -a opts opts+=( -U $vars[user] ) (($+vars[host])) && opts+=( --host=$vars[host] ) (($+vars[port])) && opts+=( --port=$vars[port] ) do_command=( $vars[createuser] $opts $vars[name] ) local flag for flag in allow_createdb allow_createrole allow_replication allow_login superuser; do if (($vars[$flag])); then do_command+=( --${flag#allow_} ) else do_command+=( --no-${flag#allow_} ) fi done out=$( confz_do $vars[psql] $opts -AP tuples_only=on -c '\dg' template1 ) || \ die "psql failed" grep -q "^$vars[name]|" <<<$out } confz_postgresql_db_check() { checkvars db owner defvar user postgres defvar psql psql defvar createdb createdb local -a opts opts+=( -U $vars[user] ) (($+vars[host])) && opts+=( --host=$vars[host] ) (($+vars[port])) && opts+=( --port=$vars[port] ) do_command=( $vars[createdb] $opts $vars[db] -O $vars[owner] ) if (($+vars[encoding])); then do_command+=( -E $vars[encoding] ) fi local out name owner encoding rest out=$( confz_do $vars[psql] $opts -lAP tuples_only=on template1 ) || \ die "psql failed" while IFS='|' read name owner encoding rest; do if [[ $name == $vars[db] ]]; then [[ $owner == $vars[owner] ]] || \ die "database $name has owner $owner, want $vars[owner]" if (($+vars[encoding])); then [[ $encoding == $vars[encoding] ]] || \ die "database $name has encoding $encoding, want $vars[encoding]" fi return 0 fi done <<<$out fail_reason="database ${(qqq)vars[db]} was not found" return 1 } confz_postgresql_schema_check() { checkvars db owner schema_name defvar user postgres defvar psql psql local -a opts opts+=( -U $vars[user] ) (($+vars[host])) && opts+=( --host=$vars[host] ) (($+vars[port])) && opts+=( --port=$vars[port] ) do_command=( $vars[psql] $opts $vars[db] -1 -c "CREATE SCHEMA $vars[schema_name]; ALTER SCHEMA $vars[schema_name] OWNER TO $vars[owner]" ) local out schema owner out=$( confz_do $vars[psql] $opts -AP tuples_only=on -c '\dn' $vars[db] ) || die "psql failed" while IFS='|' read schema owner; do if [[ $schema == $vars[schema_name] ]]; then [[ $owner == $vars[owner] ]] || \ die "schema $schema has owner $owner, want $vars[owner]" return 0 fi done <<<$out fail_reason="schema ${(qqq)vars[schema_name]} was not found in database ${(qqq)vars[db]}" return 1 } confz_postgresql_extension_check() { checkvars db extension schema_name defvar user postgres defvar psql psql local -a opts opts+=( -U $vars[user] ) (($+vars[host])) && opts+=( --host=$vars[host] ) (($+vars[port])) && opts+=( --port=$vars[port] ) do_command=( $vars[psql] $opts $vars[db] -1 -c "CREATE EXTENSION $vars[extension] SCHEMA $vars[schema_name]" ) local out extension version schema comment out=$( confz_do $vars[psql] $opts -AP tuples_only=on -c '\dx' $vars[db] ) || die "psql failed" while IFS='|' read extension version schema comment; do if [[ $extension == $vars[extension] ]]; then [[ $schema == $vars[schema_name] ]] || \ die "extension $extension has schema $schema, want $vars[schema_name]" return 0 fi done <<<$out fail_reason="extension ${(qqq)vars[extension]} was not found in database ${(qqq)vars[db]}" return 1 } confz_postgresql_content_check() { checkvars db schema psql_input defvar user postgres defvar psql psql local out local -a opts opts+=( -U $vars[user] ) (($+vars[host])) && opts+=( --host=$vars[host] ) (($+vars[port])) && opts+=( --port=$vars[port] ) out=$( confz_do $vars[psql] $opts -AP tuples_only=on -c '\d' $vars[db] ) || die "psql failed" if [[ -z $out || $out == 'No relations found.' ]]; then fail_reason="the schema for ${(qqq)vars[db]} is empty" return 1 elif [[ $out != $vars[schema] ]]; then die "the schema for ${(qqq)vars[db]} differs:"$'\n'"$( \ diff -u <(print -r - $vars[schema]) <(print -r - $out) )" fi return 0 } confz_postgresql_content_do() { local -a opts opts+=( -U $vars[user] ) (($+vars[host])) && opts+=( --host=$vars[host] ) (($+vars[port])) && opts+=( --port=$vars[port] ) confz_do $vars[psql] $opts -1 $vars[db] -f - <<<$vars[psql_input] }