Commit 51f32515 authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

Add configuration task overwriting mechanism

Add a mechanism were scripts from within the image can be executed
instead of the original Configuration Tasks.
parent f29bd833
......@@ -220,8 +220,8 @@ Configuration Tasks Enviroment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When an *snf-image-helper* configuration task runs, it expects to find the
required information in its enviroment. In the table below we describe the
enviroment variables that are present when the configuration tasks run.
required information in its environment. In the table below we describe the
environment variables that are present when the configuration tasks run.
+---------------------+-------------------------------------------------------+
......@@ -254,7 +254,7 @@ enviroment variables that are present when the configuration tasks run.
|NIC_COUNT |The number of network interface controllers of the |
| |instance. |
+---------------------+-------------------------------------------------------+
|NIC_%N_* |The ganeti provided environment variable for the Nth |
|NIC_%N_* |The Ganeti provided environment variable for the Nth |
| |network interface controller. Check |
| |`here <http://docs.ganeti.org/ganeti/current/man/ganeti|
| |-os-interface.html>`_ |
......@@ -278,6 +278,37 @@ enviroment variables that are present when the configuration tasks run.
.. [#] all environment variable names are prefixed with *SNF_IMAGE_*
.. _overwriting-configuration-tasks:
Overwriting Configuration Tasks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
One way to extend snf-image to work on images that are not directly supported
by it, is the overwriting mechanism for the :ref:`configuration tasks
<image-configuration-tasks>`. If the ``ALLOW_MOUNTED_TASK_OVERWRITING`` image
property is defined with yes, then the presence of an executable under the path
``/root/snf-image/helper/overwrite_task_<TASK>`` inside the image's file system
will make *snf-image-helper* interrupt the execution of the actual
configuration task and the image's file will be executed instead. This
executable should make use of the :ref:`Configuration Tasks Environment
<configuration-tasks-environment>`. Also keep in mind that this only works for
configuration tasks that run while the image is mounted (have a priority
between 31 and 79).
Return Code and post execution
++++++++++++++++++++++++++++++
If the return code of the execution of the image-defined executable is
non-zero, *snf-image* will translate this as a failure of the configuration
task. The only exception to this is the return code **101**, which will make
*snf-image* execute the original configuration task and then the image's
executable once again. The first time the image's executable will be called
with **pre-exec** as its first argument and the second with **post-exec**. This
way the executable itself can decide if it is going to be executed in
conjunction with the original configuration task and in which order (before,
after or in both cases).
.. rubric:: Footnotes
.. [#f1] http://technet.microsoft.com/en-us/library/hh824938.aspx
......@@ -170,6 +170,13 @@ All image formats properties
exists in the above-mentioned location. For more information on "answer
files" please refer to :ref:`windows-deployment`.
* **ALLOW_MOUNTED_TASK_OVERWRITING=yes**
If this property is defined with yes, then the presence of an executable
file under */root/snf-image/helper/overwrite_task_<TASK>* inside the image
will make *snf-image* execute the code hosted there instead of the default
one. See :ref:`Overwriting Configuration Tasks<overwriting-configuration-tasks>`
for more info.
* **PASSWD_HASHING_METHOD=md5|sha1|blowfish|sha256|sha512**
This property can be used on Unix instances to specify the method to be used
to hash the users password. By default this is determined by the type of the
......
......@@ -917,6 +917,45 @@ check_if_mounted_excluded() {
return 0
}
check_if_overwritten() {
local script ret
if ! check_yes_no SNF_IMAGE_PROPERTY_ALLOW_MOUNTED_TASK_OVERWRITING; then
return 0
fi
script=$(find -L $SNF_IMAGE_TARGET/root/snf-image/helper \
-iname "overwrite_task_${PROGNAME:2}" -type f 2>/dev/null) || true
if [ -x "$script" ]; then
warn "Task ${PROGNAME:2} was overwritten by file: \`${script:${#SNF_IMAGE_TARGET}}'"
export OVERWRITTEN_TASK="$script"
set +e
$OVERWRITTEN_TASK "pre-exec"
ret=$?
set -e
if [ $ret -eq 101 ]; then
# Reserve 101 for the case where the original task should be
# executed after the task that overwrote it has finished
warn "Running task ${PROGNAME:2} after \`${script:${#SNF_IMAGE_TARGET}}' returned 101"
# Overwrite exit to make sure the script is executed again at the
# end. This is error-prone, since you'll always have to use exit on
# normal termination (which we actually did before this) but I
# couldn't think of a better way. Adding it in the task_cleanup()
# is not an option because you can't control the failures well.
exit() {
local rc=$1
if [ $rc -eq 0 ]; then
warn "Running \`${OVERWRITTEN_TASK:${#SNF_IMAGE_TARGET}}' again after task ${PROGNAME:2}"
$OVERWRITTEN_TASK "post-exec"
fi
builtin exit $rc
}
else
exit $ret
fi
fi
}
return_success() {
send_result_${HYPERVISOR} "SUCCESS"
}
......
......@@ -38,6 +38,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing."
fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" != "linux" ]; then
exit 0
fi
......
......@@ -38,6 +38,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing."
fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
exit 0
fi
......
......@@ -45,6 +45,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target directory \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" != "windows" ]; then
exit 0
fi
......
......@@ -37,6 +37,9 @@ if [ -z "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" != "windows" ]; then
exit 0
fi
......
......@@ -40,6 +40,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "linux" ]; then
distro=$(get_base_distro $SNF_IMAGE_TARGET)
......
......@@ -34,6 +34,13 @@ report_task_start
check_if_excluded
check_if_mounted_excluded
if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
windows_hostname() {
local target hostname unattend tmp_unattend namespace
target="$1"
......
......@@ -34,6 +34,13 @@ report_task_start
check_if_excluded
check_if_mounted_excluded
if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
linux_shadow="/etc/shadow"
freebsd_shadow="/etc/master.passwd"
openbsd_shadow="/etc/master.passwd"
......@@ -154,10 +161,6 @@ unix_password() {
done
}
if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
if [ -z "${SNF_IMAGE_PASSWD+dummy}" -a -z "${SNF_IMAGE_PASSWD_HASH+dummy}" ]; then
warn "Task ${PROGNAME:2} will not run. Password is not set"
exit 0
......
......@@ -39,6 +39,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
distro=$(get_base_distro "$SNF_IMAGE_TARGET")
if [ ! -f "@networkingdir@/$distro.sh" ]; then
......
......@@ -34,14 +34,17 @@ report_task_start
check_if_excluded
check_if_mounted_excluded
if [ ! -b "$SNF_IMAGE_DEV" ]; then
log_error "Device file:\`${SNF_IMAGE_DEV}' is not a block device"
fi
if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target directory \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
if [ ! -b "$SNF_IMAGE_DEV" ]; then
log_error "Device file:\`${SNF_IMAGE_DEV}' is not a block device"
fi
if [ -z "$SNF_IMAGE_RESIZE_PART" ]; then
warn "No partition chosen for resize"
exit 0
......
......@@ -42,6 +42,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
if [ -z "$SNF_IMAGE_PERSONALITY" ]; then
warn "This image has no personality (0 files to inject)"
exit 0
......
......@@ -39,6 +39,9 @@ if [ ! -d "$SNF_IMAGE_TARGET" ]; then
log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
fi
# Check if the image overwrites the task
check_if_overwritten
if [ -z "$SNF_IMAGE_PROPERTY_CUSTOM_TASK" ]; then
warn "No custom task specified to run"
exit 0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment