From: Thomas Markwalder Date: Thu, 11 Jun 2015 10:17:49 +0000 (-0400) Subject: [master] Merge branch 'trac3802' X-Git-Tag: trac3732a_base~8^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ffddc0bfd72f1b3aab8a9b28e5d80ee91a24138e;p=thirdparty%2Fkea.git [master] Merge branch 'trac3802' Adds lease-dump to kea-admin. While merging, additonal changes were needed: src/bin/admin/tests/mysql_tests.sh.in mysql_wipe() - functio was failing referential integrity checks due to new tables added in schema 3.0. Was deleting all tables except "hosts". This has been fixed. Added src/bin/admin/scripts/mysql/lease_dump_3.0.sh --- ffddc0bfd72f1b3aab8a9b28e5d80ee91a24138e diff --cc src/bin/admin/admin-utils.sh index 58e6c74f4e,624691ce8c..6edc7392ac --- a/src/bin/admin/admin-utils.sh +++ b/src/bin/admin/admin-utils.sh @@@ -22,64 -22,26 +22,65 @@@ # more convenient to use if the script didn't parse db_user db_password # and db_name. # - # @todo: Catch mysql return code. I tried to use PIPESTATUS[X], but it doesn't - # seem to work (or at least I don't know how to use it). + # It saves mysql command exit status both to the env variable _ADMIN_STATUS + # as well as returning it as $? to the caller. + mysql_execute() { if [ $# -gt 1 ]; then - QUERY=$1 + QUERY="$1" shift - _RESULT=`echo $QUERY | mysql -N -B $@` + mysql -N -B $* -e "${QUERY}" + retcode=$? else - _RESULT=$(mysql -N -B --user=$db_user --password=$db_password -e "${1}" $db_name) + mysql -N -B --user=$db_user --password=$db_password -e "${1}" $db_name + retcode="$?" fi + + return $retcode } - mysql_version() { mysql_execute "SELECT CONCAT(version,\".\",minor) FROM schema_version" "$@" - } - - mysql_version_print() { - mysql_version "$@" - printf "%s" $_RESULT + return $? } +pgsql_execute() { + QUERY=$1 + shift + if [ $# -gt 0 ]; then + _RESULT=$(echo $QUERY | psql --set ON_ERROR_STOP=1 -A -t -q $*) + retcode=$? + else + export PGPASSWORD=$db_password + _RESULT=$(echo $QUERY | psql --set ON_ERROR_STOP=1 -A -t -q -U $db_user -d $db_name) + retcode=$? + fi + return $retcode +} + +pgsql_execute_script() { + file=$1 + shift + if [ $# -gt 0 ]; then + _RESULT=$(psql --set ON_ERROR_STOP=1 -A -t -q -f $file $*) + retcode=$? + else + export PGPASSWORD=$db_password + _RESULT=$(psql --set ON_ERROR_STOP=1 -A -t -q -U $db_user -d $db_name -f $file) + retcode=$? + fi + return $retcode +} + + +pgsql_version() { + pgsql_execute "SELECT version || '.' || minor FROM schema_version" "$@" + return $? +} + +pgsql_version_print() { + pgsql_version "$@" + retcode=$? + printf "%s" $_RESULT + return $? +} diff --cc src/bin/admin/kea-admin.in index 0c5c9c0046,e871b10d25..5b964101b7 --- a/src/bin/admin/kea-admin.in +++ b/src/bin/admin/kea-admin.in @@@ -236,36 -236,168 +254,195 @@@ mysql_upgrade() } pgsql_upgrade() { - log_error "NOT IMPLEMENTED" + # @todo - When PostgreSQL has a schema greater than 1.0, this will need + # to be implemented. See ticket #3600 + pgsql_version_print + printf "\n" + + # Check if the scripts directory exists at all. + if [ ! -d ${scripts_dir}/pgsql ]; then + log_error "Invalid scripts directory: ${scripts_dir}/pgsql" + exit 1 + fi + + # Check if there are any files in it + num_files=$(find ${scripts_dir}/pgsql/upgrade*.sh -type f | wc -l) + if [ $num_files -eq 0 ]; then + log_error "No scripts in ${scripts_dir}/pgsql or the directory is not readable or does not have any upgrade* scripts." + exit 1 + fi + + for script in ${scripts_dir}/pgsql/upgrade*.sh + do + echo "Processing $script file..." + sh ${script} --user=${db_user} --password=${db_password} ${db_name} + done + + printf "Lease DB version reported after upgrade: " + pgsql_version_print + printf "\n" + exit 0 } + # Utility function which tests if the given file exists and + # if so notifies the user and provides them the opportunity + # to abort the current command. + check_file_overwrite () { + local file=$1 + if [ -e ${file} ] + then + echo "Output file, $file, exists and will be overwritten." + echo "Do you wish to continue? (y/n)" + read ans + if [ ${ans} != "y" ] + then + echo "$command aborted by user." + exit 1 + fi + fi + } + + ### Functions used for dump + + # Sets the global variable, dump_qry, to the schema-version specific + # SQL text needed to dump the lease data for the current backend + # and protocol + get_dump_query() { + local version=$1 + + dump_qry="" + dump_sql_file="$scripts_dir/${backend}/lease_dump_$version.sh" + if [ ! -e $dump_sql_file ] + then + log_error "lease-dump: cannot access dump_sql_file: $dump_sql_file" + exit 1; + fi + + # source in the dump file which defines the sql text we'll need + . $dump_sql_file + if [ $? -ne 0 ] + then + log_error "lease-dump: error sourcing dump_sql_file: $dump_sql_file" + exit 1 + fi + + # Construct the SQL text to dump the leases based on protocol type + case ${dump_type} in + 4) + dump_qry="$lease4_dump_sql"; + ;; + 6) + dump_qry="$lease6_dump_sql"; + ;; + *) + log_error "you must specify -4 or -6 for lease-dump" + usage + exit 1 + ;; + esac + + if [ "$dump_qry" = "" ] + then + log_error "lease-dump: dump query appears to be undefined" + exit 1 + fi + } + + memfile_dump() { + log_error "lease-dump is not supported for memfile" + exit 1 + } + + mysql_dump() { + + # get the correct dump query + version=`mysql_version` + retcode=$? + if [ $retcode -ne 0 ] + then + log_error "lease-dump: mysql_version failed, exit code $retcode" + exit 1; + fi + + # Fetch the correct SQL text. Note this function will exit + # if it fails. + get_dump_query $version + + # Make sure they specified a file + if [ "$dump_file" = "" ]; then + log_error "you must specify an output file for lease-dump" + usage + exit 1 + + fi + + # If output file exists, notify user, allow them a chance to bail + check_file_overwrite $dump_file + + # Check the temp file too + tmp_file="$dump_file.tmp" + check_file_overwrite $tmp_file + + # Run the sql to output tab-delimited lease data to a temp file. + # By using a temp file we can check for MySQL errors before using + # 'tr' to translate tabs to commas. We do not use MySQL's output + # to file as that requires linux superuser privileges to execute + # the select. + mysql_execute "${dump_qry}" > $tmp_file + retcode=$? + if [ $retcode -ne 0 ]; then + log_error "lease-dump: mysql_execute failed, exit code $retcode"; + exit 1 + fi + + # Now translate tabs to commas. + cat $tmp_file | tr '\t' ',' >$dump_file + if [ $? -ne 0 ]; then + log_error "lease-dump: reformatting failed"; + exit 1 + fi + + # delete the tmp file on success + rm $tmp_file + echo lease$dump_type successfully dumped to $dump_file + exit 0 + } + + ### Functions used for dump + pgsql_dump() { + + # @todo use pgsql_version once implemented. See #3883 + version='1.0' + get_dump_query $version + + # Make sure they specified a file + if [ "$dump_file" = "" ]; then + log_error "you must specify an output file for lease-dump" + usage + exit 1 + + fi + + # If output file exists, notify user, allow them a chance to bail + check_file_overwrite $dump_file + + # psql does not accept password as a parameter but will look in the environment + export PGPASSWORD=$db_password + + # Call psql and redirect output to the dump file. We don't use psql "to csv" + # as it can only be run as db superuser. + echo "$dump_qry" | psql --set ON_ERROR_STOP=1 -t -q --user=$db_user --dbname=$db_name -w --no-align --field-separator=',' >$dump_file + retcode=$? + + # Check for errors. + if [ $retcode -ne 0 ]; then + log_error "lease-dump: psql call failed, exit code: $retcode"; + exit 1 + fi + + echo lease$dump_type successfully dumped to $dump_file + exit 0 + } ### Script starts here ### diff --cc src/bin/admin/scripts/mysql/Makefile.am index 419474510f,cfac0cd4d2..e91622b88f --- a/src/bin/admin/scripts/mysql/Makefile.am +++ b/src/bin/admin/scripts/mysql/Makefile.am @@@ -1,6 -1,6 +1,6 @@@ SUBDIRS = . sqlscriptsdir = ${datarootdir}/${PACKAGE_NAME}/scripts/mysql - sqlscripts_DATA = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh -sqlscripts_DATA = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh lease_dump_1.0.sh lease_dump_2.0.sh ++sqlscripts_DATA = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh lease_dump_1.0.sh lease_dump_2.0.sh lease_dump_3.0.sh - EXTRA_DIST = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh -EXTRA_DIST = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh lease_dump_1.0.sh lease_dump_2.0.sh ++EXTRA_DIST = dhcpdb_create.mysql upgrade_1.0_to_2.0.sh upgrade_2.0_to_3.0.sh lease_dump_1.0.sh lease_dump_2.0.sh lease_dump_3.0.sh diff --cc src/bin/admin/scripts/mysql/lease_dump_3.0.sh index 0000000000,0000000000..80256b273b new file mode 100644 --- /dev/null +++ b/src/bin/admin/scripts/mysql/lease_dump_3.0.sh @@@ -1,0 -1,0 +1,38 @@@ ++#!/bin/sh ++# Copyright (C) 2015 Internet Systems Consortium. ++# ++# Permission to use, copy, modify, and distribute this software for any ++# purpose with or without fee is hereby granted, provided that the above ++# copyright notice and this permission notice appear in all copies. ++# ++# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM ++# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL ++# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ++# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, ++# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING ++# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, ++# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION ++# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++# Specifies the MySQL sql for schema-version 3.0 required to produce ++# lease output that includes a header row containing column names, ++# followed by the lease data. The text is used in a single call ++# to the mysql command line tool. ++ ++# SQL for DHCPv4 leases ++lease4_dump_sql="\ ++SELECT 'address', 'hwaddr', 'client_id', 'valid_lifetime', 'expire',\ ++'subnet_id', 'fqdn_fwd', 'fqdn_rev', 'hostname';\ ++SELECT INET_NTOA(address), IFNULL(HEX(hwaddr), ''), IFNULL(HEX(client_id), ''),\ ++valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname from lease4" ++ ++# SQL for DHCPv6 leases ++lease6_dump_sql="\ ++SELECT 'address', 'duid', 'valid_lifetime', 'expire',\ ++'subnet_id', 'pref_lifetime', 'lease_type', 'iaid', 'prefix_len', 'fqdn_fwd',\ ++'fqdn_rev', 'hostname', 'hwaddr', 'hwtype', 'hwaddr_source';\ ++SELECT a.address, IFNULL(HEX(a.duid), ''), a.valid_lifetime,\ ++a.expire, a.subnet_id, a.pref_lifetime, IFNULL(b.name, ''), a.iaid, a.prefix_len,\ ++a.fqdn_fwd, a.fqdn_rev, hostname, IFNULL(HEX(hwaddr), ''), IFNULL(hwtype, ''),\ ++IFNULL(hwaddr_source, '') \ ++FROM lease6 a left outer join lease6_types b on (a.lease_type = b.lease_type)" diff --cc src/bin/admin/scripts/mysql/upgrade_2.0_to_3.0.sh.in index 9d275ef1b2,0000000000..cc85d40934 mode 100755,000000..100755 --- a/src/bin/admin/scripts/mysql/upgrade_2.0_to_3.0.sh.in +++ b/src/bin/admin/scripts/mysql/upgrade_2.0_to_3.0.sh.in @@@ -1,101 -1,0 +1,100 @@@ +#!/bin/sh + +# Include utilities. Use installed version if available and +# use build version if it isn't. +if [ -e @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh ]; then + . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh +else + . @abs_top_builddir@/src/bin/admin/admin-utils.sh +fi + - mysql_version "$@" - VERSION=$_RESULT ++VERSION=`mysql_version "$@"` + +if [ "$VERSION" != "2.0" ]; then + printf "This script upgrades 2.0 to 3.0. Reported version is $VERSION. Skipping upgrade.\n" + exit 0 +fi + +mysql "$@" </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 </dev/null 2>&1 < 2.0) - mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 </dev/null 2>&1 < 2.0) - mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 </dev/null 2>&1 < 3.0) - mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 </dev/null 2>&1 < 3.0) - mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 </dev/null 2>&1 < 3.0) - mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 </dev/null 2>&1 < 3.0) - mysql -u$db_user -p$db_pass $db_name >/dev/null 2>&1 </dev/null 2>&1 <