Skip to content
Snippets Groups Projects
Commit 1008ddf9 authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

Sqlite Handle profiles; restore into existing db file; restore file owner and perms

parent 96823fd0
Branches
No related tags found
1 merge request!129Db Profiles
...@@ -66,22 +66,32 @@ ...@@ -66,22 +66,32 @@
# ---------- GETTER # ---------- GETTER
# write debug output if DBD_DEBUG is enabled
# param string text to show
function dbdetect._wd(){ function dbdetect._wd(){
test "$DBD_DEBUG" -eq "1" && echo "DEBUG: $*" >&2 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(){ function dbdetect.getConfigs(){
find ${DBD_BASEDIR} -type f -name "*.ini" find ${DBD_BASEDIR} -type f -name "*.ini"
} }
# get type from given ini file
# param string full path of ini file
function dbdetect.getType(){ function dbdetect.getType(){
basename "$1" | cut -d "_" -f 1 | sed "s,\.ini$,," 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(){ function dbdetect.getProfile(){
basename "$1" | cut -d "_" -f 1- | sed "s,\.ini$,," 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(){ function dbdetect.exists(){
local _config="$1" local _config="$1"
...@@ -93,14 +103,17 @@ function dbdetect.exists(){ ...@@ -93,14 +103,17 @@ function dbdetect.exists(){
ini.set "$_config" "detect" ini.set "$_config" "detect"
# --- check tcp # --- check tcp
local tcpport; tcpport=$( ini.value "tcp" ) local tcpport; tcpport=$( ini.value "tcp" )
local tcptarget; tcptarget=$( ini.value "tcp-target" ) if [ -n "$tcpport" ]; then
if { ! >/dev/tcp/$tcptarget/$tcpport; } > /dev/null 2>&1; then local tcptarget; tcptarget=$( ini.value "tcp-target" )
# echo "No port tcp $tcpport available" tcptarget=${tcptarget:-localhost}
dbdetect._wd "... No port tcp $tcpport available on $tcptarget" if { ! >/dev/tcp/$tcptarget/$tcpport; } > /dev/null 2>&1; then
return 1 # 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 fi
dbdetect._wd "... Found tcp $tcpport on $tcptarget."
# --- check tcp process # --- check tcp process
local tcpprocess; tcpprocess=$( ini.value "tcp-process" ) local tcpprocess; tcpprocess=$( ini.value "tcp-process" )
...@@ -139,21 +152,45 @@ function dbdetect.exists(){ ...@@ -139,21 +152,45 @@ function dbdetect.exists(){
dbdetect._wd "... Process ${process} was found" dbdetect._wd "... Process ${process} was found"
fi 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" ini.set "$_config" "set"
local value local value
local dbuser=$( ini.value "dbuser" ) local dbuser=$( ini.value "dbuser" )
local dbpassword=$( ini.value "dbpassword" ) local dbpassword=$( ini.value "dbpassword" )
for mykey in $( ini.keys )
for mykey in su env params
do do
# params = '--port={{tcp}} --password={{dbpassword}} --user={{dbuser}} --host={{tcp-target}}'
value="$( ini.value "$mykey" )" value="$( ini.value "$mykey" )"
value="${value//\{\{tcp\}\}/$tcpport}" value="${value//\{\{tcp\}\}/$tcpport}"
value="${value//\{\{tcp-target\}\}/$tcptarget}" value="${value//\{\{tcp-target\}\}/$tcptarget}"
value="${value//\{\{dbuser\}\}/$dbuser}" value="${value//\{\{dbuser\}\}/$dbuser}"
value="${value//\{\{dbpassword\}\}/$dbpassword}" value="${value//\{\{dbpassword\}\}/$dbpassword}"
value="${value//\{\{file\[\]\}\}/$myfiles}"
DBD_PARAMS[$mykey]="$value" DBD_PARAMS[$mykey]="$value"
dbdetect._wd ">>> $mykey = $value"
done done
dbdetect._wd ">>> files = $myfiles"
DBD_PARAMS[files]="$myfiles"
return 0 return 0
} }
...@@ -167,6 +204,13 @@ function dbdetect.getParams(){ ...@@ -167,6 +204,13 @@ function dbdetect.getParams(){
echo "${DBD_PARAMS['params']}" 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 = ... # set variables in [set] -> env = ...
# USAGE: # USAGE:
# eval $( dbdetect.setenv ) # eval $( dbdetect.setenv )
...@@ -189,26 +233,6 @@ function dbdetect.runas(){ ...@@ -189,26 +233,6 @@ function dbdetect.runas(){
# FUNCTIONS 4 DB-WRAPPER # FUNCTIONS 4 DB-WRAPPER
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
function db.init(){
BACKUP_BASEDIR=$(_j_getvar ${JOBFILE} "dir-localdumps")
# check
if [ -z "$BACKUP_BASEDIR" ]; then
color error
echo ERROR: missing config for backup target.
echo There must be an entry dir-localdumps in ${JOBFILE}
color reset
exit 1
fi
BACKUP_PLUGINDIR=$(dirname $0)/plugins/localdump
BACKUP_KEEP_DAYS=$(_j_getvar ${JOBFILE} "keep-days")
if [ $BACKUP_KEEP_DAYS -eq 0 ]; then
BACKUP_KEEP_DAYS=7
fi
BACKUP_DATE=$(/bin/date +%Y%m%d-%H%M)
}
# helpfer function for SERVICENAME.backup # helpfer function for SERVICENAME.backup
# it is called after the service specific dump was done. # it is called after the service specific dump was done.
...@@ -346,7 +370,7 @@ function dbdetect.runas(){ ...@@ -346,7 +370,7 @@ function dbdetect.runas(){
if [ -z $1 ]; then if [ -z $1 ]; then
find -type f | sed "s#__[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9].*##g" | grep -v "\.meta" | sort -ud| sed "s#^\./##g" find -type f | sed "s#__[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9].*##g" | grep -v "\.meta" | sort -ud| sed "s#^\./##g"
else else
ls -ltr "$*__"* | sed "s#^\./##g" ls -ltr "$*__"* | sed "s#^\./##g" | grep -v "\.meta"
fi fi
cd - >/dev/null cd - >/dev/null
else else
...@@ -376,7 +400,7 @@ function dbdetect.runas(){ ...@@ -376,7 +400,7 @@ function dbdetect.runas(){
# the metafile is written in sqlite backup to store full path # the metafile is written in sqlite backup to store full path
metafile=${BACKUP_TARGETDIR}/${dumpfile}.meta metafile=${BACKUP_TARGETDIR}/${dumpfile}.meta
if [ -f $metafile ]; then if [ -f $metafile ]; then
cat $metafile grep "^/" "$metafile" || grep "^ File: " "$metafile" | cut -c 9-
else else
sBasename=$(basename $1) sBasename=$(basename $1)
sDb=$(echo ${sBasename} | sed "s#__[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9].*##g") sDb=$(echo ${sBasename} | sed "s#__[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9].*##g")
...@@ -391,6 +415,29 @@ function dbdetect.runas(){ ...@@ -391,6 +415,29 @@ function dbdetect.runas(){
} }
# read .meta file (that contains output of stats) and restore last owner and file permissions
# param string filename of db dump
# param string restored database file
function restorePermissions(){
local sMyMeta="${1}.meta"
local sTargetfile="$2"
if [ -f "${sMyMeta}" ]; then
# Access: (0674/-rw-rwxr--) Uid: ( 1000/ axel) Gid: ( 1000/ axel)
# ^ ^ ^
# _sPerm _sUser _sGroup
local _sPerm=$( grep "^Access: (" "${sMyMeta}" | cut -f 2 -d '(' | cut -f 1 -d '/')
if [ -n "$_sPerm" ]; then
local _sUser=$( grep "^Access: (" "${sMyMeta}" | cut -f 3 -d '/' | cut -f 1 -d ')' | tr -d ' ')
local _sGroup=$( grep "^Access: (" "${sMyMeta}" | cut -f 4 -d '/' | cut -f 1 -d ')' | tr -d ' ')
echo -n "Restoring file owner $_sUser:$_sGroup and permissions $_sPerm ... "
chown "$_sUser:$_sGroup" "${sTargetfile}" && chmod "$_sPerm" "${sTargetfile}"
fetchrc
fi
fi
}
# ------------------------------------------------------------ # ------------------------------------------------------------
# show help # show help
# ------------------------------------------------------------ # ------------------------------------------------------------
...@@ -419,7 +466,26 @@ function dbdetect.runas(){ ...@@ -419,7 +466,26 @@ function dbdetect.runas(){
# INIT # INIT
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
db.init # ----- db init
BACKUP_BASEDIR=$(_j_getvar ${JOBFILE} "dir-localdumps")
# check
if [ -z "$BACKUP_BASEDIR" ]; then
color error
echo ERROR: missing config for backup target.
echo There must be an entry dir-localdumps in ${JOBFILE}
color reset
exit 1
fi
BACKUP_PLUGINDIR=$(dirname $0)/plugins/localdump
DBD_BASEDIR=$BACKUP_PLUGINDIR/profiles
BACKUP_KEEP_DAYS=$(_j_getvar ${JOBFILE} "keep-days")
if [ $BACKUP_KEEP_DAYS -eq 0 ]; then
BACKUP_KEEP_DAYS=7
fi
BACKUP_DATE=$(/bin/date +%Y%m%d-%H%M)
# ----- checks # ----- checks
...@@ -455,7 +521,14 @@ function dbdetect.runas(){ ...@@ -455,7 +521,14 @@ function dbdetect.runas(){
case "$mode" in case "$mode" in
# ------------------------------------------------------------ # ------------------------------------------------------------
check) check)
. $BACKUP_SCRIPT $mode DBD_DEBUG=1
for PROFILENAME in $(dbdetect.getConfigs)
do
echo "----- $PROFILENAME"
dbdetect.exists "${PROFILENAME}"
echo
done
# . $BACKUP_SCRIPT $mode
;; ;;
# ------------------------------------------------------------ # ------------------------------------------------------------
backup) backup)
...@@ -469,23 +542,6 @@ function dbdetect.runas(){ ...@@ -469,23 +542,6 @@ function dbdetect.runas(){
services=$* services=$*
fi fi
# ----- check all params
for SERVICENAME in $services
do
BACKUP_SCRIPT=$( get_service_script ${SERVICENAME} )
if [ ! -f $BACKUP_SCRIPT ]; then
color error
echo ERROR: parameter $SERVICENAME seems to be wrong.
echo The backup script does not exist: $BACKUP_SCRIPT
color reset
echo
echo services in this folder are:
get_services
exit 2
fi
done
# ----- GO # ----- GO
# PROFILENAME mysql_localhost_13306 # PROFILENAME mysql_localhost_13306
# SERVICENAME mysql # SERVICENAME mysql
...@@ -505,23 +561,25 @@ function dbdetect.runas(){ ...@@ -505,23 +561,25 @@ function dbdetect.runas(){
h2 "START SCRIPT FOR [${PROFILENAME}] -> ${SERVICENAME}" h2 "START SCRIPT FOR [${PROFILENAME}] -> ${SERVICENAME}"
# ------ set env # ------ set env
# echo "BACKUP_PARAMS = $BACKUP_PARAMS"
# dbdetect.setenv # dbdetect.setenv
eval $( dbdetect.setenv ) eval $( dbdetect.setenv )
# echo "BACKUP_PARAMS = $BACKUP_PARAMS"
_j_runHooks "200-before-db-service" _j_runHooks "200-before-db-service"
. $BACKUP_SCRIPT $mode
h3 "BACKUP [${PROFILENAME}] -> ${SERVICENAME}"
. $BACKUP_SCRIPT $mode
test $rc -gt 0 && j_notify "db ${SERVICENAME}" "$BACKUP_SCRIPT $mode was finished with rc=$rc" $rc test $rc -gt 0 && j_notify "db ${SERVICENAME}" "$BACKUP_SCRIPT $mode was finished with rc=$rc" $rc
_j_runHooks "230-after-db-service" "$rc" _j_runHooks "230-after-db-service" "$rc"
# ------ unset env
eval $( dbdetect.unssetenv )
# ----- post jobs: cleanup # ----- post jobs: cleanup
cleanup_backup_target cleanup_backup_target
show_info_backup_target show_info_backup_target
# ------ unset env
eval $( dbdetect.unssetenv )
else else
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
# 2018-02-02 ah,ds v1.0 first lines # 2018-02-02 ah,ds v1.0 first lines
# 2018-02-09 ah,ds v1.1 write a .meta file after successful backup # 2018-02-09 ah,ds v1.1 write a .meta file after successful backup
# 2022-03-17 v1.2 WIP: add lines with prefix __DB__ # 2022-03-17 v1.2 WIP: add lines with prefix __DB__
# 2024-02-20 ah v1.3 Handle profiles; restore into existing db file; restore file owner and perms
# ================================================================================ # ================================================================================
if [ -z "$BACKUP_TARGETDIR" ]; then if [ -z "$BACKUP_TARGETDIR" ]; then
...@@ -23,22 +24,17 @@ fi ...@@ -23,22 +24,17 @@ fi
# CONFIG # CONFIG
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
FILEDEFS=${DIR_JOBS}/backup-dbfiles.job
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# FUNCTIONS # FUNCTIONS
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# make sqlite3 backups of all sqlite = ... in backup-dbfiles.job # start multiple sqlite3 backups
# files are taken from loaded profiles/sqlite*.ini - section [detect] -> files[]
function doSqliteBackup(){ function doSqliteBackup(){
if ! _j_getvar ${FILEDEFS} "sqlite" | grep . ; then
echo "__DB__$SERVICENAME SKIP: no entries found for sqlite."
return 0
fi
create_targetdir create_targetdir
for DATABASE_FILE in $(_j_getvar ${FILEDEFS} "sqlite") for DATABASE_FILE in $( dbdetect.getFiles )
do do
echo -n "__DB__${SERVICENAME} backup $DATABASE_FILE " echo -n "__DB__${SERVICENAME} backup $DATABASE_FILE "
if [ ! -f "$DATABASE_FILE" ]; then if [ ! -f "$DATABASE_FILE" ]; then
...@@ -47,24 +43,17 @@ function doSqliteBackup(){ ...@@ -47,24 +43,17 @@ function doSqliteBackup(){
color reset color reset
rc=$rc+1 rc=$rc+1
else else
file "$DATABASE_FILE" | cut -f 2 -d ":" | grep -i "sqlite" >/dev/null
if [ $? -ne 0 ]; then TARGET=$(get_outfile ${DATABASE_FILE})
color error TARGET=${BACKUP_TARGETDIR}/$(echo ${TARGET} | sed "s#/#_#g").sql
echo "ERROR: given database file is not a sqlite database" META=${TARGET}.gz.meta
color reset # echo -n " to $TARGET "
rc=$rc+1 sqlite3 "$DATABASE_FILE" .dump >"${TARGET}"
else fetchrc >/dev/null
TARGET=$(get_outfile ${DATABASE_FILE}) db._compressDumpfile "${TARGET}" && stat "$DATABASE_FILE" >"${META}"
TARGET=${BACKUP_TARGETDIR}/$(echo ${TARGET} | sed "s#/#_#g").sql
META=${TARGET}.gz.meta ls -l ${TARGET}*
# echo -n " to $TARGET "
sqlite3 "$DATABASE_FILE" .dump >"${TARGET}"
fetchrc >/dev/null
db._compressDumpfile "${TARGET}" && echo "$DATABASE_FILE" >"${META}"
ls -l ${TARGET}*
fi
fi fi
done done
} }
...@@ -73,29 +62,27 @@ function doSqliteBackup(){ ...@@ -73,29 +62,27 @@ function doSqliteBackup(){
# param string database dump file (gzipped) # param string database dump file (gzipped)
# param string optional: database to import; default: database is parsed from file # param string optional: database to import; default: database is parsed from file
function restoreByFile(){ function restoreByFile(){
sMyfile=$1 local sMyfile=$1
sMyDb=$2 local sMyDb=$2
if [ -f "${sMyDb}" ]; then if [ -f "${sMyDb}" ]; then
color error # echo -n "" > "${sMyDb}"
echo ERROR: target file already exists. Remove or rename it first. echo "Deleting ${sMyDb} before restore..."
rm -f "${sMyDb}"
fi
echo -n "Restore ${sMyfile} ... "
color cmd
zcat "${sMyfile}" | sqlite3 "${sMyDb}"
fetchrc
if [ $myrc -eq 0 ]; then
restorePermissions "${sMyfile}" "${sMyDb}"
ls -l "${sMyDb}" ls -l "${sMyDb}"
color reset echo
rc=$rc+1
else else
color cmd color error
zcat "${sMyfile}" | sqlite3 "${sMyDb}" echo ERROR while restoring backup.
fetchrc color reset
if [ $myrc -eq 0 ]; then
color ok
echo OK, restore was successful
color reset
ls -l "${sMyDb}"
else
color error
echo ERROR while restoring backup.
color reset
fi
fi fi
} }
...@@ -108,12 +95,6 @@ function restoreByFile(){ ...@@ -108,12 +95,6 @@ function restoreByFile(){
# ----- check requirements # ----- check requirements
j_requireBinary "sqlite3" 1 j_requireBinary "sqlite3" 1
if [ ! -f "$FILEDEFS" ]; then
echo "INFO: file definitions $FILEDEFS do not exist."
rc=$rc+1
fi
if [ $rc -ne 0 ]; then if [ $rc -ne 0 ]; then
rc=0 rc=0
echo "SKIP: sqlite seems not to be here" echo "SKIP: sqlite seems not to be here"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment