Introduce support for persistent state in /mnt.

Since instances that have ephemeral volumes, which we plan to use for
persistent state (yes the name is confusing) start with the volume
empty, we need some support to aid in placing state files (and
configuration files we want to generate dynamically) on that partition
- we can't just move stuff there during build, or it will be mounted
over by cloud-init.

Change-Id: Iff9e329ba6217e5f7290b7ab65b1808f4a8d8f9a
This commit is contained in:
Robert Collins 2013-10-14 21:45:13 +13:00
parent f2af795ac1
commit 66cc593886
4 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,49 @@
Provides tools to aid in relocating state to /mnt/state
In a cloud instance /mnt/state is on the cloud ephemeral device when one
exists, or the root when one doesn't.
The pattern for having state on /mnt/state is:
- The service/daemon can make its own state files on startup (as /mnt
is always empty on first-boot).
- Alternatively os-refresh-config can be used to populate any initial state so
that the daemon/service works (so until the first os-refresh-config run that
daemon/service will be broken).
- If the state needs migrating (e.g. PostgreSQL 9.1 to 9.2) then a migration
script should be added to os-refresh-config's migrations.d tree to perform
that migration that state (if the migration can be done after the service
starts) or to configure.d if the service cannot start without the migration
being done).
- state should live in /mnt/state/original-path e.g.
/mnt/state/etc/ssh/ssh\_host\_dsa\_key.
- where there are hardcoded specific paths, we leave symlinks in that path
pointing into /mnt/state - e.g. /etc/ssh/ss\_host\_dsa\_key will be a symlink
to /mnt/state/etc/ssh/ssh\_host\_dsa\_key.
To factor out common code elements can invoke register-state-path during
install.d to request that a particular path be registered as a stateful path.
- If there is content at the path at registration time, it will be moved to
/var/lib/use-ephemeral/original-path.
- If --leave-symlink is passed, a symlink will be created at that path pointing
to /mnt/state/original-path.
- Stateful paths are listed in /var/lib/use-ephemeral/stateful-paths, one path
per line - e.g. /etc/ssh/ssh\_host\_dsa\_key.
Once registered:
- During pre-configure.d the parent directories leading up to the path will be
asserted on startup.
- If there is a content at /var/lib/use-ephemeral/original-path during
pre-configure.d, and the new path does not exist in /mnt/state then an
rsync -a will be made into /mnt/state/original-path reinstating a pristine
copy of what was preserved. This is only done when the path does not exist
to avoid corrupting evolved or migrated state.

View File

@ -0,0 +1,74 @@
#!/bin/bash
#
# Copyright 2013 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
set -eux
set -o pipefail
SCRIPT_NAME=$(basename $0)
SCRIPT_HOME=$(dirname $0)
function show_options () {
echo "Usage: $SCRIPT_NAME [options] <path>"
echo
echo "Register <path> as a state path."
echo
echo "This will register path as being part of the state of the machine."
echo "If there is content at <path> it will be moved to "
echo "/var/lib/use-ephemeral/<path>."
echo
echo "Paths are recorded in /var/lib/use-ephemeral/stateful-paths."
echo
echo "Options:"
echo " --leave-symlink -- create a symlink from <path> to /mnt/state/<path>."
echo
exit $1
}
LEAVE_SYMLINK=""
TEMP=`getopt -o h -l help,leave-symlink -n $SCRIPT_NAME -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
while true ; do
case "$1" in
--leave-symlink) LEAVE_SYMLINK="true"; shift 1 ;;
-h | --help) show_options 0;;
--) shift ; break ;;
*) echo "Error: unsupported option $1." ; exit 1 ;;
esac
done
STATE_PATH=${1:-""}
EXTRA=${2:-""}
if [ -z "$STATE_PATH" -o -n "$EXTRA" ]; then
show_options 1
fi
mkdir -p /var/lib/use-ephemeral
echo $STATE_PATH >> /var/lib/use-ephemeral/stateful-paths
if [ -e "$STATE_PATH" -o -L "$STATE_PATH" ]; then
backup_dir=/var/lib/use-ephemeral/$(dirname "$STATE_PATH")
mkdir -p "$backup_dir"
mv "$STATE_PATH" "$backup_dir"
fi
if [ -n "$LEAVE_SYMLINK" ]; then
ln -s "/mnt/state/$STATE_PATH" "$STATE_PATH"
fi

View File

@ -0,0 +1 @@
os-refresh-config

View File

@ -0,0 +1,33 @@
#!/bin/bash
#
# Copyright 2013 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
set -eux
set -o pipefail
if [ ! -e "/var/lib/use-ephemeral/stateful-paths" ]; then
exit 0
fi
while read -r; do
state_path="/mnt/state/$REPLY"
state_dir=$(dirname "$state_path")
reference_path="/var/lib/use-ephemeral/$REPLY"
mkdir -p "$state_dir"
if [ -e "$reference_path" -a ! -L "$state_path" -a ! -e "$state_path" ]; then
rsync -av "$reference_path" "$state_path"
fi
done < "/var/lib/use-ephemeral/stateful-paths"