diff --git a/includes/dbdetect.class.sh b/includes/dbdetect.class.sh new file mode 100644 index 0000000000000000000000000000000000000000..2cdd781669aff0d45f4f2e5ac41d983eccfed4c9 --- /dev/null +++ b/includes/dbdetect.class.sh @@ -0,0 +1,187 @@ +# ====================================================================== +# +# Database detector functions +# used in localdump.se and detector.sh +# +# it analyzes all ini files with database profiles and sets +# variables / environment to perform database backup/ restore +# +# ---------------------------------------------------------------------- +# ====================================================================== + +# ---------------------------------------------------------------------- +# CONFIG +# ---------------------------------------------------------------------- + +DBD_BASEDIR=plugins/localdump/profiles +declare -A DBD_PARAMS + + +# ---------------------------------------------------------------------- +# FUNCTIONS +# ---------------------------------------------------------------------- + +# write debug output if DBD_DEBUG is enabled +# param string text to show +function dbdetect._wd(){ + test "$DBD_DEBUG" -eq "1" && echo "DEBUG: $*" >&2 +} + +# get a list of all config files +# param string full path of ini file +function dbdetect.getConfigs(){ + find ${DBD_BASEDIR} -type f -name "*.ini" +} + +# get type from given ini file +# param string full path of ini file +function dbdetect.getType(){ + basename "$1" | cut -d "_" -f 1 | sed "s,\.ini$,," +} + +# get profile from given ini file +# param string full path of ini file +function dbdetect.getProfile(){ + basename "$1" | cut -d "_" -f 1- | sed "s,\.ini$,," +} + +# check if the requirements for a database match +# param string full path of ini file to check +function dbdetect.exists(){ + local _config="$1" + + DBD_PARAMS= + + local _found=0 + + # set file and inisection we read values from + ini.set "$_config" "detect" + + # --- check tcp + local tcpport; tcpport=$( ini.value "tcp" ) + if [ -n "$tcpport" ]; then + local tcptarget; tcptarget=$( ini.value "tcp-target" ) + tcptarget=${tcptarget:-localhost} + if { ! >/dev/tcp/$tcptarget/$tcpport; } > /dev/null 2>&1; then + # echo "No port tcp $tcpport available" + dbdetect._wd "... No port tcp $tcpport available on $tcptarget" + return 1 + fi + dbdetect._wd "... Found tcp $tcpport on $tcptarget." + fi + + # --- check tcp process + local tcpprocess; tcpprocess=$( ini.value "tcp-process" ) + if [ -n "$tcpprocess" ]; then + if ! netstat -tulpen 2>/dev/null | grep "^tcp.*:${tcpport} .*/${tcpprocess}" >/dev/null; then + # echo "No port tcp $tcpport available" + dbdetect._wd "... $tcpprocess not found for tcp ${tcpport}" + return 1 + fi + dbdetect._wd "... tcp $tcpport is used by $tcpprocess." + fi + + # --- check binaries + local binary; binary=$( ini.value "binary" ) + if [ -n "${binary}" ]; then + for mybinary in $( echo "${binary}" | tr "," " " ); do + if ! j_requireBinary "$mybinary" 1 >/dev/null 2>&1; then + dbdetect._wd "... Missing binary: ${mybinary}" + return 1 + fi + dbdetect._wd "... Binary: ${mybinary} was found" + done + fi + + # --- check process + local process; process=$( ini.value "process" ) + if [ -n "${process}" ]; then + if ! j_requireProcess "${process}" 1 >/dev/null; then + dbdetect._wd "... Missing process: ${process}" + return 1 + fi + # if ! ps -eo command | grep -E "${process}" >/dev/null 2>&1; then + # dbdetect._wd "... Process ${process} was not found" + # return 1 + # fi + dbdetect._wd "... Process ${process} was found" + fi + + # --- check db files + local filetype; filetype=$( ini.value "type" ) + + if [ -n "${filetype}" ]; then + local myfiles; declare -a myfiles + for myfile in $( ini.value "file[]" ) + do + if ! file -b "${myfile}" | grep -i "$filetype" >/dev/null; then + dbdetect._wd "... File ${myfile} is no type $filetype" + return 1 + fi + dbdetect._wd "... File ${myfile} is type $filetype" + myfiles+="${myfile}|" + done + fi + + # --- OK, everything was found ... we initialize it + dbdetect._wd "OK, match: $_config" + + ini.set "$_config" "set" + local value + local dbuser=$( ini.value "dbuser" ) + local dbpassword=$( ini.value "dbpassword" ) + + + for mykey in su env params + do + value="$( ini.value "$mykey" )" + value="${value//\{\{tcp\}\}/$tcpport}" + value="${value//\{\{tcp-target\}\}/$tcptarget}" + value="${value//\{\{dbuser\}\}/$dbuser}" + value="${value//\{\{dbpassword\}\}/$dbpassword}" + value="${value//\{\{file\[\]\}\}/$myfiles}" + + DBD_PARAMS[$mykey]="$value" + dbdetect._wd ">>> $mykey = $value" + done + dbdetect._wd ">>> files = $myfiles" + DBD_PARAMS[files]="$myfiles" + + return 0 +} + +# set a profile name +function dbdetect.setProfile(){ + dbdetect.exists "${DBD_BASEDIR}/${PROFILENAME}.ini" +} + +function dbdetect.getParams(){ + echo "${DBD_PARAMS['params']}" +} + + +# for backup scripts: get checked files from [detect] -> file[] +# +function dbdetect.getFiles(){ + echo "${DBD_PARAMS['files']}" | tr "|" "\n" +} + +# set variables in [set] -> env = ... +# USAGE: +# eval $( dbdetect.setenv ) +function dbdetect.setenv(){ + echo "${DBD_PARAMS['env']}" +} + +# unset variables from [set] -> env = ... +# USAGE: +# eval $( dbdetect.unsetenv ) +function dbdetect.unssetenv(){ + echo "${DBD_PARAMS['env']}" | grep -o '[a-z0-9]*=' | tr -d '=' | sed "s,^,unset ," +} + +function dbdetect.runas(){ + echo "${DBD_PARAMS['su']}" +} + +# ---------------------------------------------------------------------- diff --git a/plugins/localdump/profiles/pgsql.ini b/plugins/localdump/profiles/pgsql.ini new file mode 100644 index 0000000000000000000000000000000000000000..07fc641f2484dbf787770b3c02ba2a5b652ea533 --- /dev/null +++ b/plugins/localdump/profiles/pgsql.ini @@ -0,0 +1,36 @@ +# ====================================================================== +# +# LOCAL PGSQL INSTANCE +# +# ====================================================================== + +[detect] + +process = 'postgres|postmaster' +tcp = 5432 +tcp-target = localhost +tcp-process = 'postgres|postmaster' + + +[set] + +su = 'postgres' +dbuser = '' +dbpassword = '' + +# --- from pgsql help: +; Connection options: +; -h, --host=HOSTNAME database server host or socket directory (default: "/var/run/postgresql") +; -p, --port=PORT database server port (default: "5432") +; -U, --username=USERNAME database user name (default: "postgres") +; -w, --no-password never prompt for password +; -W, --password force password prompt (should happen automatically) +; +# params = '--host= {{tcp-target}} --port={tcp}} --username={{dbuser}} --no-password' +# https://www.postgresql.org/docs/current/libpq-envars.html + + +params = '' +env = '' + +# ----------------------------------------------------------------------