In the online hosted computing lab we now use to provide a hosted solution for module based docker containers, persistent storage is mounted into a launched container at /home/ou/MODULECODE-PRESENTATIONCODE
. For modules that use databases that students might modify, this means we need to move the database data directories into the users home directory somewhere.
Here’s a copy of the script I’ve been dabbling with to try to do that. It runs when the container is started, after the home directory volume has been mounted:
#! /bin/bash
# Location: /etc/ou_local_db_path/local_db_path.sh
LOCAL_HOME=/home/ou/TM351-23J
mkdir -p $LOCAL_HOME/openrefine
chown ou:users $LOCAL_HOME/openrefine
# If required, don't run any more of this script
if [ -f "$LOCAL_HOME/.no_local_db_path" ]; then
echo "Not running local db scripts"
exit 0
fi
## DATABASE MIGRATION
# The Mongo and Postgres data directories can be mounted
# to the persistent storage that is provided by the Open Computing Lab.
#
# Migration happens if:
#
# - /home/ou/MODULE-PRESENTATION/.no_mount does not exist
# - /home/ou/MODULE-PRESENTATION/.local_DBTYPE does not exist (for DBTYPE postgres, mongo)
#
# The .no_mount file will be clobbered if a volume is mounted over /home/ou/MODULE-PRESENTATION/ ;
# this means databases *will* be copied when the container is run in the VCE.
# Databases *will* be copied to host for locally run containers, unless the user
# adds a .no_mount file to the directory they mount onto /home/ou/MODULE-PRESENTATION/
# See for example:
# https://github.com/OpenComputingLab/vce-jupyter-stacks/blob/main/tm351-notebook-jh/start_jh_extras
# Create a db hidden storage dir
mkdir -p $LOCAL_HOME/.db
# Migrate postgres db to local userdir
if [[ ! -f "$LOCAL_HOME/.local_postgres" && ! -f "$LOCAL_HOME/.no_mount" ]] ; then
echo "Copying over postgres database files to $LOCAL_HOME/.db/"
service postgresql stop
# We need to give the postgres user sight into the users...
usermod -aG users postgres
# Recursive copy, preserving permissions
cp -Rp /var/lib/postgresql /home/ou/TM351-23J/.db/
# Manual settings
#chown -R postgres:postgres $LOCAL_HOME/.db/postgresql
#chmod -R 700 $LOCAL_HOME/.db/postgresql/
sed -e "s@[#]\?data_directory = .*@data_directory = '/home/ou/TM351-23J/.db/postgresql/14/main'@g" -i '/etc/postgresql/14/main/postgresql.conf'
touch $LOCAL_HOME/.local_postgres
chown ou:users $LOCAL_HOME/.local_postgres
service postgresql restart
fi
#if [ ! -d "$LOCALMONGO" ]; then
if [[ ! -f "$LOCAL_HOME/.local_mongo" && ! -f "$LOCAL_HOME/.no_mount" ]]; then
echo "Copying over mongo database files to $LOCAL_HOME/.db/"
LOCALMONGO="$LOCAL_HOME/.db/mongo/"
# mongo data directory migration
if [ ! -f "/var/run/mongodb.pid" ]; then
service mongod stop
fi
mkdir -p $LOCALMONGO
# Recursive copy, preserving permissions
cp -Rp /var/db/data/mongo $LOCAL_HOME/.db
sed -e "s@[#]\?dbPath: .*@dbPath: /home/ou/TM351-23J/.db/mongo@g" -i '/etc/mongod.conf'
# Check permissions
#chmod -R u+rw $LOCALMONGO
touch $LOCAL_HOME/.local_mongo
chown ou:users $LOCAL_HOME/.local_mongo
service mongod restart
fi
The script is run using sudo, with permissions set as follows in the image build script:
echo "ou ALL=(ALL:ALL) NOPASSWD: /etc/ou_local_db_path/local_db_path.sh" >> /etc/sudoers
An empty .local_postgres
and.local_mongo
file are used to flag whether or not to copy the files over for each database; a separate .no_mount
file can also be used to disable moving the databases. The .no_mount
file is created as part of the image build:
touch /home/ou/TM351-23J/.no_mount
chown ou:users /home/ou/TM351-23J/.no_mount
If persistent volume is mounted in, the .no_mount
file will be clobbered (unless it is also in the directory that is mounted in); if no volume is mounted in, the data directory is not moved from its default location.
The approach used above is wasteful of space — the original data directories as shipped are copied not moved, but this means we can recover the original seeded database if required.