# -*- mode: sh -*-
###
### config hook
###
dbc_go(){
local f db host newhost port oldhosts do_config _preconf_list _s _t STATE iformat ifile install_question migrating userdb_prio _dbc_dbadmin_set_to_default _dbc_dbuser_set_to_default _dbc_basepath_set_to_default
. /usr/share/dbconfig-common/dpkg/common
_dbc_debug "(config) dbc_go() $@"
## With dbconfig-no-thanks installed we don't need to do anything.
if dbc_no_thanks ; then
return 0
fi
dbc_config "$@"
db_capb backup
# only do this on install/reconfigure
if [ "$dbc_command" != "configure" ] && [ "$dbc_command" != "reconfigure" ];
then
return 0
fi
##
## register all the dbconfig-common questions
##
## note that this can fail in the case that dbconfig-common is being
## installed at the same time as the dependant package and the latter
## is preconfigured before we are (no way to avoid this without being
## in base). in this case we gracefully exit and defer to the second
## time the config script is run by dpkg in the postinst. note if that
## "hack" in dpkg ever goes away we can still work around the issue so
## i think it's fair to avoid over-complicating things in the dependency
## chain.
##
if ! dbc_register_debconf; then
_dbc_debug "dbconfig-common not yet setup, deferring configuration."
return 0
fi
# make sure debconf is up to date with on-disk configuration
dbc_read_package_config
dbc_preseed_package_debconf
# Migrate some debconf answers prior to dbc 1.8.50 to the new
# choices of the templates (can be removed after Debian Stretch)
if [ "$dbc_dbtype" = "mysql" ] ; then
db_get $dbc_package/mysql/method
if [ "$RET" = "unix socket" ] ; then
db_set $dbc_package/mysql/method "Unix socket"
elif [ "$RET" = "tcp/ip" ] ; then
db_set $dbc_package/mysql/method "TCP/IP"
fi
fi
if [ "$dbc_dbtype" = "pgsql" ] ; then
db_get $dbc_package/pgsql/method
if [ "$RET" = "unix socket" ] ; then
db_set $dbc_package/pgsql/method "Unix socket"
elif [ "$RET" = "tcp/ip" ] ; then
db_set $dbc_package/pgsql/method "TCP/IP"
elif [ "$RET" = "tcp/ip + ssl" ] ; then
db_set $dbc_package/pgsql/method "TCP/IP + SSL"
fi
fi
# Find out whether the database has been purged on a previous occasion. If
# so, we'll have to give the user a chance to re-install it.
#
# We need some check if the package is removed, but not purged.
# An alternative over using this is to add a new internal template.
# The drawback of this solution is that preseeding the answer to
# the purge question is ignored (reset) during package installation
# so if required this needs to be preseeded when removing the package.
db_get $dbc_package/purge
if [ "$RET" = true ]; then
dbc_command=reconfigure
fi
# if we are here due to an error, raising question priorities
if [ "$dbc_retry_after_error" ] ;then
dbc_remote_questions_priority="$dbc_prio_high"
dbc_prio_low="$dbc_prio_high"
dbc_prio_medium="$dbc_prio_high"
dbc_prio_high="$dbc_prio_critical"
# And make sure that whatever the package that calls us sets it to,
# after one iteration we should be high enough for something to happen,
# else we may be caught in a loop.
dbc_prio_critical="critical"
fi
# check out if they're migrating from a non-dbc version
if [ "$dbc_oldversion" ] && [ "$dbc_first_version" ] && \
dpkg --compare-versions "$dbc_first_version" gt "$dbc_oldversion"; then
migrating="yes"
fi
# if this is a frontend app, then the user/db type questions get
# a raised priority
if [ "$dbc_frontend" ]; then
userdb_prio="$dbc_prio_medium"
else
userdb_prio="$dbc_prio_low"
fi
# the first question we ask will differ depending on how we're invoked
if [ "$migrating" ] || [ "$dbc_retry_after_error" = "upgrade" ] ; then
install_question="$dbc_package/dbconfig-upgrade"
elif [ "$dbc_command" = "configure" ]; then
install_question="$dbc_package/dbconfig-install"
else
install_question="$dbc_package/dbconfig-reinstall"
# if we are reconfiguring (via dpkg-reconfigure), also leave a hint
# for our future postinst selves so we know we *should* run the code
# that would otherwise think we were upgrading
db_set $dbc_package/internal/reconfiguring true
fi
##
## start new dbc upgrade section
##
# if there is a previously existing version already installed
# *and* the maintainer has provided the first version that used
# dbconfig-common *and* this version is newer than the
# previously installed version... do the dbc import stuff.
if [ "$migrating" ]; then
dbc_migrate
fi
# and start our beautiful state-machine
# we start in STATE=1 (install_question) in all but one situation:
# - we're installing a frontend/readonly app
if [ ! "$dbc_frontend" ]; then
STATE=1
else
STATE=2
fi
dbc_statefull=true # Make sure that we can also backup from password questions
while true; do
case "$STATE" in
# state 1 - ask if they want our help at all
1)
db_input $dbc_prio_high $install_question || true
;;
# state 2 - check to see if they do.
# - see if this is an upgrade newly supporting dbc
# - multidb support step 1
2)
db_get $install_question
if [ "$RET" != "true" ]; then
db_set $dbc_package/internal/skip-preseed true
return 0;
fi
db_set $dbc_package/dbconfig-install true
##
## start multidb section
##
# if the dbtype is hardcoded (using config.mysql, etc), use that
if [ "$dbc_hardcoded_dbtype" ]; then
dbc_dbtype=$dbc_hardcoded_dbtype
# else if the package supports multiple dbtypes, help them pick one
elif [ "$dbc_dbtypes" ]; then
# If $dbc_dbtypes only contains one element, we don't really need
# to choose But let's inform the administrator with updated
# template text.
# If dbc_dbtype isn't already set (from conf file) then use the
# default as our first guess.
if [ ! "$dbc_dbtype" ]; then
dbc_dbtype="$dbc_default_dbtype"
else
# If $dbc_dbtype not in $dbc_dbtypes we have a weird
# situation. This can happen during dpkg-reconfigure or
# upgrades where the original cmd-line $dbc_dbtype package got
# removed in the mean time (let's hope it is on purpose). This
# could also happen when a package dropped support (it should
# handle that itself) for the previously selected dbtype.
# Note: if this happens during reconfigure, we warned the user
# already. Idea: we check if we are reconfiguring, then just
# continue if not, we raise an error. But if we are recovering
# from the error in the "retry" mode, we should just
# continue. Hmm, there is no other error raised during config.
if ! echo "$dbc_dbtypes" | grep -q "$dbc_dbtype"; then
dbc_logline "The originally selected database type is currently not installed, assuming this is on purpose."
dbc_dbtype="$dbc_default_dbtype"
fi
fi
db_set $dbc_package/database-type "$dbc_dbtype"
db_input $dbc_prio_high $dbc_package/database-type || true
fi
;;
# state 3 - multidb support part 2, pre-seeding, get conn. method
3)
if [ "$dbc_dbtypes" ]; then
db_get $dbc_package/database-type && dbc_dbtype="$RET"
# now that we have a dbtype, reload common to set other defaults
dbc_config "$@"
# Also re-register the templates, as otherwise $dbvendor will
# not be replaced in the following questions
dbc_register_debconf
fi
# there's a bit more to do with rdbms that support authentication
if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
# If these haven't been specified, use defaults. Track that
# we did that, so we can do it again when the admin backed
# up the debconf questions and choose an other dbtype.
# See bts #663234
if [ ! "$dbc_dbadmin" ] || [ "$_dbc_dbadmin_set_to_default" = true ]; then
_dbc_dbadmin_set_to_default=true
dbc_dbadmin="$dbc_default_admin"
fi
if [ ! "$dbc_dbuser" ] || [ "$_dbc_dbuser_set_to_default" = true ]; then
_dbc_dbuser_set_to_default=true
dbc_dbuser="$dbc_default_dbuser"
fi
fi
if echo "$dbc_fs_dbtypes" | grep -q "$dbc_dbtype"; then
# if these haven't been specified, use defaults
if [ ! "$dbc_basepath" ] || [ "$_dbc_basepath_set_to_default" = true ]; then
_dbc_basepath_set_to_default=true
dbc_basepath="$dbc_default_basepath";
fi
fi
# same code in dpkg/common
if [ ! "$dbc_dbname" ]; then
dbc_dbname=$(echo $dbc_package | tr -d +-.);
fi
# pre-seed any already defined values into debconf as defaults
db_set $dbc_package/db/dbname "$dbc_dbname"
if [ "$dbc_upgrade" ]; then
db_set $dbc_package/dbconfig-upgrade "$dbc_upgrade"
fi
if [ "$dbc_remove" ]; then
db_set $dbc_package/dbconfig-remove "$dbc_remove"
fi
if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
db_set $dbc_package/db/app-user "$dbc_dbuser""@""$dbc_dballow"
if [ "$dbc_dbpass" ]; then
db_set $dbc_package/$dbc_dbtype/app-pass "$dbc_dbpass"
db_set $dbc_package/app-password-confirm "$dbc_dbpass"
# Not sure if the above actually has any effect if the
# passwords aren't "seen", but during error handling
# and reconfiguring we need to allow changing the
# password.
if [ "$dbc_command" != "reconfigure" ] && [ ! "$dbc_retry_after_error" ]; then
db_fset $dbc_package/$dbc_dbtype/app-pass seen true
db_fset $dbc_package/app-password-confirm seen true
fi
fi
# This "if" itself should be redundant, as it is filled above.
if [ "$dbc_dbadmin" ]; then
# This may be overruled by MySQL/MariaDB localhost settings
db_set $dbc_package/$dbc_dbtype/admin-user "$dbc_dbadmin"
fi
fi
if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
if [ "$dbc_dbserver" ]; then
db_set $dbc_package/remote/host "$dbc_dbserver"
fi
if [ "$dbc_dbport" ]; then
db_set $dbc_package/remote/port "$dbc_dbport"
fi
if [ "$dbc_ssl" = "true" ] && [ "$dbc_dbtype" = "pgsql" ]; then
db_set $dbc_package/pgsql/method "TCP/IP + SSL"
fi
db_input $dbc_remote_questions_priority $dbc_package/$dbc_dbtype/method || true
fi
if echo "$dbc_fs_dbtypes" | grep -q "$dbc_dbtype"; then
# if these haven't been specified, use defaults
if [ "$dbc_basepath" ]; then
db_set $dbc_package/db/basepath "$dbc_basepath"
fi
fi
;;
# state 4 - do stuff based on the connection method
4)
db_get $dbc_package/$dbc_dbtype/method && dbc_method="$RET"
if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
# if package/method == tcp/ip or tcp/ip + ssl
if [ "$dbc_method" != "Unix socket" ]; then
# look at the hosts used in any other dbconfig-using
# package, and create a list of hosts.
_preconf_list=$( (
for f in /etc/dbconfig-common/*.conf; do
test -f $f || continue
eval $(dbconfig-generate-include --dbserver=_s $f | grep -v '^#')
[ "$_s" ] && echo $_s
done
echo localhost
) | sort | uniq)
# turn the list into a comma separated list if it exists
# and then substitute it into the list of available hosts
_preconf_list=$(echo $_preconf_list | sed -e 's/ /, /g')
_preconf_list="new host, $_preconf_list"
db_subst $dbc_package/remote/host hosts "$_preconf_list"
# and then ask them for one
db_input $dbc_prio_high $dbc_package/remote/host || true
# but if it is unix socket, forget all the host stuff
else
db_reset $dbc_package/remote/host || true
db_reset $dbc_package/remote/newhost || true
db_reset $dbc_package/remote/port || true
fi
fi
;;
# state 5 - get host / port info if necessary
5)
if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
if [ "$dbc_method" != "Unix socket" ]; then
if [ "$_preconf_list" ]; then
db_get $dbc_package/remote/host
host=$RET
fi
# if they've chosen "new host" or the host list was empty
if [ ! "$host" ] || [ "$host" = "new host" ]; then
# prompt them for a new hostname
db_input $dbc_prio_high $dbc_package/remote/newhost || true
fi
fi
fi
;;
# state 6 - do stuff based on host/port selection
6)
if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
if [ "$dbc_method" != "Unix socket" ]; then
if [ ! "$host" ] || [ "$host" = "new host" ]; then
db_get $dbc_package/remote/newhost
newhost="$RET"
# add the new host to the existing list of hosts
db_metaget $dbc_package/remote/host choices
oldhosts="$RET"
db_subst $dbc_package/remote/host hosts "$oldhosts, $newhost"
db_set $dbc_package/remote/host "$newhost"
db_fset $dbc_package/remote/host seen true
dbc_dbserver="$newhost"
else
# set the "newhost" to the selected host, because
# the second time through the configure script we'll
# need this set
db_set $dbc_package/remote/newhost "$host"
dbc_dbserver="$host"
fi
# on what port?
db_input $dbc_remote_questions_priority $dbc_package/remote/port || true
fi
fi
;;
# state 7 - pgsql specific auth stuff, part 1
7)
if [ "$dbc_dbtype" = "pgsql" ] && [ ! "$dbc_frontend" ]; then
# postgresql provides multiple auth types, and ssl
# get the admin auth method
db_input $dbc_prio_low $dbc_package/pgsql/authmethod-admin || true
fi
;;
# state 8 - pgsql auth stuff, part 2
8)
if [ "$dbc_dbtype" = "pgsql" ] && [ ! "$dbc_frontend" ]; then
db_get $dbc_package/pgsql/authmethod-admin && authmethod_admin="$RET"
db_input $dbc_prio_medium $dbc_package/pgsql/authmethod-user || true
fi
;;
# state 9 - admin/app user/pass, dbname
9)
# get the name of the database to use
db_input $userdb_prio $dbc_package/db/dbname || true
if echo "$dbc_fs_dbtypes" | grep -q "$dbc_dbtype"; then
# check the path / permissions to install to
db_input $dbc_prio_low $dbc_package/db/basepath || true
fi
if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
db_input $userdb_prio $dbc_package/db/app-user || true
if ! dbc_get_app_pass ; then
# Make sure that we can also backup from password questions
STATE=$(($STATE - 1))
continue
fi
# who's the admin user
if [ ! "$dbc_frontend" ]; then
# Note: dpkg/prerm has the same code
if [ $dbc_dbtype = mysql ] && _dbc_mysql_get_debian_sys_maint ; then
db_set $dbc_package/$dbc_dbtype/admin-user "$dbc_dbadmin"
db_fset $dbc_package/$dbc_dbtype/admin-user seen true
db_set $dbc_package/$dbc_dbtype/admin-pass "$dbc_dbadmpass"
db_fset $dbc_package/$dbc_dbtype/admin-pass seen true
fi
db_input $userdb_prio $dbc_package/$dbc_dbtype/admin-user || true
fi
fi
;;
# * - end state
*)
break
;;
esac
if db_go; then
STATE=$(($STATE + 1))
else
STATE=$(($STATE - 1))
fi
if [ $STATE -lt 1 ]; then
if [ "$dbc_config_allow_backup" ]; then
return 30
fi
exit 10
fi
done
dbc_statefull=""
db_set $dbc_package/internal/skip-preseed true
}
dbc_migrate() {
# if dbc_load_include is set, determine the format
# and location of the old config file
if [ "$dbc_load_include" ]; then
iformat=$(echo $dbc_load_include | cut -d: -f1)
ifile=$(echo $dbc_load_include | cut -d: -f2-)
fi
##
## if they want to import settings from a previous
## non-dbc version, do that and mark the questions
## skipped
##
if [ -z "$ifile" ] || [ ! -f "$ifile" ]; then
return
fi
dbc_logpart "migrating old settings into dbconfig-common: "
if [ "$dbc_debug" ]; then
_dbc_debug "dbconfig-load-include $dbc_load_include_args -f $iformat $ifile"
dbconfig-load-include $dbc_load_include_args -f $iformat $ifile
fi
eval $(dbconfig-load-include $dbc_load_include_args -f $iformat $ifile)
if [ "$?" != "0" ]; then
dbc_logline "failed"
return
fi
# the load script needs to return at least a database type, if it's
# not a single-dbtype package
dbc_dbtype=${dbc_dbtype:-${dbc_hardcoded_dbtype:-}}
if [ -z "$dbc_dbtype" ]; then
dbc_logline "failed"
return
fi
# if the dbtype is hardcoded, reset it no matter what
# dbconfig-load-include tells us
if [ "$dbc_hardcoded_dbtype" ]; then
dbc_dbtype="$dbc_hardcoded_dbtype"
fi
for f in database-type $dbc_dbtype/method db/dbname; do
db_fset $dbc_package/$f seen true || true
done
if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
for f in pgsql/authmethod-admin pgsql/authmethod-user $dbc_dbtype/admin-user db/app-user; do
db_fset $dbc_package/$f seen true || true
done
db_set $dbc_package/db/app-user "$dbc_dbuser"
db_set $dbc_package/$dbc_dbtype/app-pass "$dbc_dbpass"
db_set $dbc_package/app-password-confirm "$dbc_dbpass"
fi
if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
for f in remote/host remote/newhost remote/port ; do
db_fset $dbc_package/$f seen true || true
done
db_set $dbc_package/remote/host "$dbc_dbserver"
db_set $dbc_package/remote/newhost "$dbc_dbserver"
db_set $dbc_package/remote/port "$dbc_dbport"
if [ "$dbc_dbserver" ]; then
if [ "$dbc_ssl" ]; then
db_set $dbc_package/$dbc_dbtype/method "TCP/IP + SSL"
else
db_set $dbc_package/$dbc_dbtype/method "TCP/IP"
fi
fi
fi
db_set $dbc_package/database-type $dbc_dbtype
db_set $dbc_package/db/dbname "$dbc_dbname"
dbc_logline "done"
}