Browse Source

new: [postgres,odoo-tecnativa] rewrite to avoid any host direct contact

This allows ``compose`` to be run from a docker.
framadate
Valentin Lab 6 years ago
parent
commit
5a3b8d5b41
  1. 37
      odoo-tecnativa/actions/load
  2. 40
      odoo-tecnativa/actions/save
  3. 10
      postgres/actions/save
  4. 52
      postgres/hooks/init
  5. 54
      postgres/hooks/postgres_database-relation-joined
  6. 31
      postgres/lib/common

37
odoo-tecnativa/actions/load

@ -9,7 +9,6 @@ if [ -z "$SERVICE_DATASTORE" ]; then
exit 1
fi
depends curl
usage="$exname [-h|--help] SRC_FILE DBNAME"
@ -55,6 +54,13 @@ if ! [ -e "$source" ]; then
exit 1
fi
realpath=$(realpath "$source") || exit 1
dirname="$(dirname "$realpath")" || exit 1
basename=$(basename "$realpath") || exit 1
host_path="$(get_host_path "$dirname")" || {
die "Failed to find host path for local directory: $dirname"
}
set -e
@ -78,13 +84,28 @@ fi
container="$(echo "$containers" | head -n 1)"
## XXXvlab: taking first ip is probably not a good idea
container_ip="$(get_docker_ips "$container" | head -n 1 | cut -f 2 -d ":")"
curl -X POST \
-F "master_pwd=${ADMIN_PASSWORD}" \
-F "backup_file=@${source}" \
-F "name=${dbname}" \
http://${container_ip}:8069/web/database/restore >/dev/null 2>&1 || {
read-0 container_network container_ip < <(get_container_network_ip "$container")
DEFAULT_CURL_IMAGE=${DEFAULT_CURL_IMAGE:-docker.0k.io/curl}
debug docker run --network "$container_network" \
"-v" "$host_path:/tmp/work" \
"$DEFAULT_CURL_IMAGE" \
-sS \
-X POST \
-F "master_pwd=<hidden>" \
-F "backup_file=@/tmp/work/${source}" \
-F "name=${dbname}" \
http://${container_ip}:8069/web/database/restore
docker run --network "$container_network" \
"-v" "$host_path:/tmp/work" \
"$DEFAULT_CURL_IMAGE" \
-sS \
-X POST \
-F "master_pwd=${ADMIN_PASSWORD}" \
-F "backup_file=@/tmp/work/${basename}" \
-F "name=${dbname}" \
http://${container_ip}:8069/web/database/restore >/dev/null || {
die "Querying odoo through curl was unsuccessfull."
}

40
odoo-tecnativa/actions/save

@ -9,7 +9,6 @@ if [ -z "$SERVICE_DATASTORE" ]; then
exit 1
fi
depends curl
usage="$exname [-h|--help] [--force|-f] DBNAME DEST_FILENAME"
@ -59,6 +58,12 @@ if [ -e "$output" -a -z "$force" ]; then
exit 1
fi
realpath=$(realpath "$output") || exit 1
dirname="$(dirname "$realpath")" || exit 1
basename=$(basename "$realpath") || exit 1
host_path="$(get_host_path "$dirname")" || {
die "Failed to find host path for local directory: $dirname"
}
set -e
@ -82,14 +87,31 @@ fi
container="$(echo "$containers" | head -n 1)"
## XXXvlab: taking first ip is probably not a good idea
container_ip="$(get_docker_ips "$container" | head -n 1 | cut -f 2 -d ":")"
curl -X POST \
-F "master_pwd=${ADMIN_PASSWORD}" \
-F "name=${dbname}" \
-F "backup_format=zip" \
-o "$output" \
http://${container_ip}:8069/web/database/backup >/dev/null 2>&1 || {
read-0 container_network container_ip < <(get_container_network_ip "$container")
DEFAULT_CURL_IMAGE=${DEFAULT_CURL_IMAGE:-docker.0k.io/curl}
debug docker run --network "$container_network" \
"-v" "$host_path:/tmp/work" \
"$DEFAULT_CURL_IMAGE" \
-X POST \
-F "master_pwd=<hidden>" \
-F "name=${dbname}" \
-F "backup_format=zip" \
-o "/tmp/work/$basename" \
http://${container_ip}:8069/web/database/backup
docker run --network "$container_network" \
"-v" "$host_path:/tmp/work" \
"$DEFAULT_CURL_IMAGE" \
-sS \
-X POST \
-F "master_pwd=${ADMIN_PASSWORD}" \
-F "name=${dbname}" \
-F "backup_format=zip" \
-o "/tmp/work/$basename" \
http://${container_ip}:8069/web/database/backup || {
die "Querying odoo through curl was unsuccessfull."
}

10
postgres/actions/save

@ -42,6 +42,13 @@ if [ -z "$DEST" ]; then
exit 1
fi
realpath=$(realpath "$DEST") || exit 1
dirname="$(dirname "$realpath")" || exit 1
basename=$(basename "$realpath") || exit 1
host_path="$(get_host_path "$dirname")" || {
die "Failed to find host path for local directory: $dirname"
}
if [[ "$dbname" == *"@"* ]]; then
IFS="@" read user dbname < <(echo "$dbname")
fi
@ -55,7 +62,8 @@ if ! db_has_database "$dbname"; then
exit 1
fi
PGM cp "$dbname" "$DEST" || {
db_docker_opts+=("-v" "$host_path:/tmp/work")
PGM cp "$dbname" "/tmp/work/$basename" || {
die "pgm command failed !"
}
info "Saved database '$dbname' into '$DEST'."

52
postgres/hooks/init

@ -11,43 +11,35 @@
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
# Please note that postgres detect on its own if its datadir needs to be populated
[ -e ~/.pgpass ] && exit 0
. lib/common
set -e
POSTGRES_ROOT_PASSWORD="$(gen_password)"
##
## Setting up access from host
##
ddb < <(echo "ALTER USER postgres WITH ENCRYPTED password '$POSTGRES_ROOT_PASSWORD'")
sed -ri 's%^host all all 0\.0\.0\.0/0 trust$%host all all 0.0.0.0/0 md5%g' \
"$SERVICE_DATASTORE/var/lib/postgresql/data/pg_hba.conf"
docker restart "$container_id"
## XXXvlab: this won't help support multiple project running on the
## same host
cat <<EOF > ~/.pgpass
if ! [ -f "$HOST_DB_PASSFILE" ]; then
POSTGRES_ROOT_PASSWORD="$(gen_password)"
ddb < <(echo "ALTER USER postgres WITH ENCRYPTED password '$POSTGRES_ROOT_PASSWORD'")
cat <<EOF > "$HOST_DB_PASSFILE"
*:*:*:postgres:$POSTGRES_ROOT_PASSWORD
EOF
chmod 600 ~/.pgpass
##
## pgm
##
echo 'prefix_pg_local_command=" " ## otherwise, will default to sudo -u postgres ' > /root/.pgm.rc
info "New root password for postgres. "
chmod 600 "$HOST_DB_PASSFILE"
info "New root password for postgres. "
fi
if ! egrep "^host all all (0.0.0.0/0|all) md5\$" "$PG_HBA" >/dev/null 2>&1; then
if egrep "^host all all (0.0.0.0/0|all) trust\$" "$PG_HBA" >/dev/null 2>&1; then
sed -ri 's%^host all all (0\.0\.0\.0/0|all) trust$%host all all \1 md5%g' \
"$PG_HBA"
if is_db_locked; then
ensure_db_docker_running
docker restart "$container_id"
info "Restarted container $container_id"
fi
info "Accepting connection from outside."
else
die "Can't ensure connection from outside. Please update the charm init script."
fi
fi

54
postgres/hooks/postgres_database-relation-joined

@ -7,23 +7,51 @@
## - the target of the link is launched first, and get a chance to ``relation-set``
## - both side of the scripts get to use ``relation-get``.
## could generate this also if not set
DBNAME=$(relation-get dbname)
[ "$(relation-get password 2>/dev/null)" ] && exit 0
DBNAME=$(relation-get dbname) || {
DBNAME="$BASE_SERVICE_NAME"
relation-set dbname "$DBNAME"
}
USER=$(relation-get user) || {
USER="$BASE_SERVICE_NAME"
relation-set user "$USER"
}
. lib/common
set -e
USER=$(relation-get user)
PASSWORD="$(gen_password)"
## YYY: check that password was not already generated/set for the same user
## use session state storage.
## is there a previous password set for user $USER ?
NO_PREVIOUS_PASS=
PREVIOUS_PASSWORD_PATH="$state_tmpdir/$SERVICE_NAME/pwd/$USER"
PREVIOUS_PASSWORD=$(cat "$PREVIOUS_PASSWORD_PATH" 2>/dev/null) || NO_PREVIOUS_PASS=true
if PASSWORD="$(relation-get password 2>/dev/null)"; then
if [ -z "$NO_PREVIOUS_PASS" -a "$PREVIOUS_PASSWORD" != "$PASSWORD" ]; then
die "Inconsistent password specification for user '$USER' on ${DARKYELLOW}$TARGET_SERVICE_NAME$NORMAL."
fi
else
if [ "$PREVIOUS_PASSWORD" ]; then
PASSWORD="${PREVIOUS_PASSWORD}"
else
PASSWORD="$(gen_password)"
info "Generated a new password for use '$USER'."
fi
fi
POSTGIS=$(relation-get postgis 2>/dev/null) || true
UNACCENT=$(relation-get unaccent 2>/dev/null) || true
ensure_db_docker_running
## XXXvlab: should send all these into only one docker...
db_has_database "$DBNAME" || UNACCENT="$UNACCENT" POSTGIS="$POSTGIS" db_create "$DBNAME"
if ! db_has_user "$USER"; then
info "Creating a new user $USER."
@ -32,7 +60,14 @@ else
info "Updating password of user $USER."
db_change_password "$USER" "$PASSWORD"
fi
db_grant_rights "$DBNAME" "$USER"
info "Granted rights on database '$DBNAME' to user '$USER'."
##
## PGPASS
##
pgpass_line="*:*:*:$USER:$PASSWORD"
pgpass_file="$CONFIGSTORE/$BASE_SERVICE_NAME/root/.pgpass"
@ -44,4 +79,11 @@ mkdir -p "$(dirname "$pgpass_file")"
echo "$pgpass_line" >> "$pgpass_file"
chmod 600 "$pgpass_file"
relation-set password "$PASSWORD"
##
## Saving password
##
relation-set password "$PASSWORD"
mkdir -p "$(dirname "$PREVIOUS_PASSWORD_PATH")"
echo "$PASSWORD" > "$PREVIOUS_PASSWORD_PATH"

31
postgres/lib/common

@ -2,9 +2,13 @@
include pretty
export DB_NAME="postgres"
export DB_NAME="$SERVICE_NAME" ## general type of database (ie: postgres/mysql...)
export DB_DATADIR=/var/lib/postgresql/data
export DB_PASSFILE=/root/.pgpass
export DATA_DIR=$SERVICE_DATASTORE$DB_DATADIR
export HOST_DB_PASSFILE="$DATA_DIR/pgpass"
export CLIENT_DB_PASSFILE="/root/.pgpass"
export PG_HBA="$DATA_DIR/pg_hba.conf"
is_db_locked() {
@ -15,8 +19,12 @@ is_db_locked() {
_set_db_params() {
local docker_ip="$1" docker_network="$2"
export db_docker_opts="--network $docker_network -e PGHOST=$docker_ip -e PGUSER=postgres"
export db_cmd_opts=
db_docker_opts+=("--network" "$docker_network"
"-e" PGHOST="$docker_ip"
"-e" PGUSER=postgres
"-e" prefix_pg_local_command=' ')
db_cmd_opts+=()
}
ddb () { dcmd psql -qAt "$@"; }
@ -85,19 +93,8 @@ db_change_password() {
PGM() {
ensure_db_docker_running </dev/null || return 1
## XXXvlab: Here we should have been able to use this, but
## pgm requires the ``prefix_pg_local_command=' '`` hack. As
## soon this is fixed, we can re
#dcmd /bin/sh pgm "$@"
echo docker run -i --rm \
$db_docker_opts -e prefix_pg_local_command=' ' \
--entrypoint pgm "$DOCKER_BASE_IMAGE" $db_cmd_opts "$@" >&2
docker run -i --rm \
$db_docker_opts -e prefix_pg_local_command=' ' \
--entrypoint pgm "$DOCKER_BASE_IMAGE" $db_cmd_opts "$@"
echo "${db_docker_opts[@]}"
dcmd pgm "$@"
}
db_grant_rights () {

Loading…
Cancel
Save