diff --git a/CHANGELOG.md b/CHANGELOG.md index f25f7e9..81b2769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.3.0 2020-10-15 + + ### Added + - Microsoft SQL Server support (experimental) + ### Changed + - Compiled Postgresql 13 from source to backup psql/13 hosts + ## 2.2.2 2020-09-22 ### Fixed diff --git a/Dockerfile b/Dockerfile index 34c5291..ccce26a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,111 @@ FROM tiredofit/alpine:edge -LABEL maintainer="Dave Conroy (dave at tiredofit dot ca)" ### Set Environment Variables -ENV ENABLE_CRON=FALSE \ +ENV MSSQL_VERSION=17.5.2.1-1 \ + ENABLE_CRON=FALSE \ ENABLE_SMTP=FALSE \ ENABLE_ZABBIX=TRUE \ ZABBIX_HOSTNAME=db-backup -### Dependencies +ENV LANG=en_US.utf8 \ + PG_MAJOR=13 \ + PG_VERSION=13.0 \ + PGDATA=/var/lib/postgresql/data + + +### Create User Accounts RUN set -ex && \ + addgroup -g 70 postgres && \ + adduser -S -D -H -h /var/lib/postgresql -s /bin/sh -G postgres -u 70 postgres && \ + mkdir -p /var/lib/postgresql && \ + chown -R postgres:postgres /var/lib/postgresql && \ + \ +### Install Dependencies + apk update && \ + apk upgrade && \ + apk add \ + openssl \ + && \ + \ + apk add --no-cache --virtual .postgres-build-deps \ + bison \ + build-base \ + coreutils \ + dpkg-dev \ + dpkg \ + flex \ + gcc \ + icu-dev \ + libc-dev \ + libedit-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ + openssl-dev \ + perl-utils \ + perl-ipc-run \ + util-linux-dev \ + zlib-dev \ + && \ + \ +### Build Postgresql + mkdir -p /usr/src/postgresql && \ + curl -sSL "https://ftp.postgresql.org/pub/source/v$PG_VERSION/postgresql-$PG_VERSION.tar.bz2" | tar xvfj - --strip 1 -C /usr/src/postgresql && \ + cd /usr/src/postgresql && \ +# update "DEFAULT_PGSOCKET_DIR" to "/var/run/postgresql" (matching Debian) +# see https://anonscm.debian.org/git/pkg-postgresql/postgresql.git/tree/debian/patches/51-default-sockets-in-var.patch?id=8b539fcb3e093a521c095e70bdfa76887217b89f + awk '$1 == "#define" && $2 == "DEFAULT_PGSOCKET_DIR" && $3 == "\"/tmp\"" { $3 = "\"/var/run/postgresql\""; print; next } { print }' src/include/pg_config_manual.h > src/include/pg_config_manual.h.new && \ + grep '/var/run/postgresql' src/include/pg_config_manual.h.new && \ + mv src/include/pg_config_manual.h.new src/include/pg_config_manual.h && \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" && \ +# explicitly update autoconf config.guess and config.sub so they support more arches/libcs + wget -O config/config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess?id=7d3d27baf8107b630586c962c057e22149653deb' && \ + wget -O config/config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub?id=7d3d27baf8107b630586c962c057e22149653deb' && \ + ./configure \ + --build="$gnuArch" \ + --enable-integer-datetimes \ + --enable-thread-safety \ + --enable-tap-tests \ + --disable-rpath \ + --with-uuid=e2fs \ + --with-gnu-ld \ + --with-pgport=5432 \ + --with-system-tzdata=/usr/share/zoneinfo \ + --prefix=/usr/local \ + --with-includes=/usr/local/include \ + --with-libraries=/usr/local/lib \ + --with-openssl \ + --with-libxml \ + --with-libxslt \ + --with-icu \ + && \ + \ + make -j "$(nproc)" world && \ + make install-world && \ + make -C contrib install && \ + runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )" && \ + apk add -t .postgres-additional-deps \ + $runDeps \ + && \ + \ +### Cleanup + apk del .postgres-build-deps && \ + cd / && \ + rm -rf \ + /usr/src/postgresql \ + /usr/local/share/doc \ + /usr/local/share/man && \ + find /usr/local -name '*.a' -delete && \ + rm -rf /var/cache/apk/* && \ + \ + ### Dependencies + set -ex && \ echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ apk update && \ apk upgrade && \ @@ -26,8 +123,8 @@ RUN set -ex && \ mongodb-tools \ libressl \ pigz \ - postgresql \ - postgresql-client \ + #postgresql \ + #postgresql-client \ redis \ xz \ zstd \ @@ -37,6 +134,11 @@ RUN set -ex && \ pixz@testing \ && \ \ + cd /usr/src && \ + curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_${MSSQL_VERSION}_amd64.apk && \ + curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/mssql-tools_${MSSQL_VERSION}_amd64.apk && \ + echo y | apk add --allow-untrusted msodbcsql17_${MSSQL_VERSION}_amd64.apk mssql-tools_${MSSQL_VERSION}_amd64.apk && \ + \ mkdir -p /usr/src/pbzip2 && \ curl -ssL https://launchpad.net/pbzip2/1.1/1.1.13/+download/pbzip2-1.1.13.tar.gz | tar xvfz - --strip=1 -C /usr/src/pbzip2 && \ cd /usr/src/pbzip2 && \ diff --git a/install/etc/services.available/10-db-backup/run b/install/etc/services.available/10-db-backup/run index d007b05..b5f7c05 100755 --- a/install/etc/services.available/10-db-backup/run +++ b/install/etc/services.available/10-db-backup/run @@ -41,6 +41,10 @@ case "$dbtype" in dbport=${DB_PORT:-3306} [[ ( -n "${DB_PASS}" ) || ( -n "${DB_PASS_FILE}" ) ]] && file_env 'DB_PASS' ;; + "mssql" | "MSSQL" | "microsoftsql" | "MICROSOFTSQL") + dbtype=mssql + dbport=${DB_PORT:-1433} + ;; "postgres" | "postgresql" | "pgsql" | "POSTGRES" | "POSTGRESQL" | "PGSQL" ) dbtype=pgsql dbport=${DB_PORT:-5432} @@ -128,30 +132,6 @@ backup_couch() { move_backup } -backup_mysql() { - if var_true "$SPLIT_DB" ; then - DATABASES=$(mysql -h ${dbhost} -P $dbport -u$dbuser --batch -e "SHOW DATABASES;" | grep -v Database|grep -v schema) - - for db in $DATABASES; do - if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] ; then - print_notice "Dumping MariaDB database: $db" - target=mysql_${db}_${dbhost}_${now}.sql - compression - mysqldump --max-allowed-packet=512M -h $dbhost -P $dbport -u$dbuser ${EXTRA_OPTS} --databases $db | $dumpoutput > ${tmpdir}/${target} - exit_code=$? - generate_md5 - move_backup - fi - done - else - compression - mysqldump --max-allowed-packet=512M -A -h $dbhost -P $dbport -u$dbuser ${EXTRA_OPTS} | $dumpoutput > ${tmpdir}/${target} - exit_code=$? - generate_md5 - move_backup - fi -} - backup_influx() { if [ "${COMPRESSION}" = "NONE" ] || [ "${COMPRESSION}" = "none" ] || [ "${COMPRESSION}" = "FALSE" ] || [ "${COMPRESSION}" = "false" ] ; then : @@ -182,6 +162,35 @@ backup_mongo() { move_backup } +backup_mssql() { + target=mssql_${dbname}_${dbhost}_${now}.bak + /opt/mssql-tools/bin/sqlcmd -E -C -S ${dbhost}\,${dbport} -U ${dbuser} -P ${dbpass} –Q "BACKUP DATABASE \[${dbname}\] TO DISK = N'${tmpdir}/${target}' WITH NOFORMAT, NOINIT, NAME = '${dbname}-full', SKIP, NOREWIND, NOUNLOAD, STATS = 10" +} + +backup_mysql() { + if var_true "$SPLIT_DB" ; then + DATABASES=$(mysql -h ${dbhost} -P $dbport -u$dbuser --batch -e "SHOW DATABASES;" | grep -v Database|grep -v schema) + + for db in $DATABASES; do + if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] ; then + print_notice "Dumping MariaDB database: $db" + target=mysql_${db}_${dbhost}_${now}.sql + compression + mysqldump --max-allowed-packet=512M -h $dbhost -P $dbport -u$dbuser ${EXTRA_OPTS} --databases $db | $dumpoutput > ${tmpdir}/${target} + exit_code=$? + generate_md5 + move_backup + fi + done + else + compression + mysqldump --max-allowed-packet=512M -A -h $dbhost -P $dbport -u$dbuser ${EXTRA_OPTS} | $dumpoutput > ${tmpdir}/${target} + exit_code=$? + generate_md5 + move_backup + fi +} + backup_pgsql() { if var_true $SPLIT_DB ; then export PGPASSWORD=${dbpass} @@ -268,6 +277,14 @@ check_availability() { (( COUNTER+=5 )) done ;; + "mssql" ) + COUNTER=0 + while ! (nc -z ${dbhost} ${dbport}) ; do + sleep 5 + (( COUNTER+=5 )) + print_warn "MSSQL Host '${dbhost}' is not accessible, retrying.. ($COUNTER seconds so far)" + done + ;; "pgsql" ) COUNTER=0 export PGPASSWORD=${dbpass} @@ -434,6 +451,10 @@ print_debug "Backup routines Initialized on $(date)" check_availability backup_influx ;; + "mssql" ) + check_availability + backup_mssql + ;; "mysql" ) check_availability backup_mysql