From 09dcecf37628c5809ae21d7785693cb7358ca94c Mon Sep 17 00:00:00 2001 From: Robert Schweikert Date: Mon, 28 Jan 2019 17:51:57 +0000 Subject: systemd: Render generator from template to account for system differences. The systemd generator used had a hard coded path for the location target file to create. This path does not apply to all distributions. Make the generator and template to have the path set during build time. --- setup.py | 13 ++- systemd/cloud-init-generator | 170 ------------------------------------ systemd/cloud-init-generator.tmpl | 175 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 173 deletions(-) delete mode 100755 systemd/cloud-init-generator create mode 100755 systemd/cloud-init-generator.tmpl diff --git a/setup.py b/setup.py index ea37efc3..186e215f 100755 --- a/setup.py +++ b/setup.py @@ -30,6 +30,8 @@ VARIANT = None def is_f(p): return os.path.isfile(p) +def is_generator(p): + return '-generator' in p def tiny_p(cmd, capture=True): # Darn python 2.6 doesn't have check_output (argggg) @@ -90,7 +92,7 @@ def read_requires(): return str(deps).splitlines() -def render_tmpl(template): +def render_tmpl(template, mode=None): """render template into a tmpdir under same dir as setup.py This is rendered to a temporary directory under the top level @@ -119,6 +121,8 @@ def render_tmpl(template): VARIANT, template, fpath]) else: tiny_p([sys.executable, './tools/render-cloudcfg', template, fpath]) + if mode: + os.chmod(fpath, mode) # return path relative to setup.py return os.path.join(os.path.basename(tmpd), bname) @@ -138,8 +142,11 @@ INITSYS_FILES = { 'systemd': [render_tmpl(f) for f in (glob('systemd/*.tmpl') + glob('systemd/*.service') + - glob('systemd/*.target')) if is_f(f)], - 'systemd.generators': [f for f in glob('systemd/*-generator') if is_f(f)], + glob('systemd/*.target')) + if (is_f(f) and not is_generator(f))], + 'systemd.generators': [ + render_tmpl(f, mode=0o755) + for f in glob('systemd/*') if is_f(f) and is_generator(f)], 'upstart': [f for f in glob('upstart/*') if is_f(f)], } INITSYS_ROOTS = { diff --git a/systemd/cloud-init-generator b/systemd/cloud-init-generator deleted file mode 100755 index bd9f2678..00000000 --- a/systemd/cloud-init-generator +++ /dev/null @@ -1,170 +0,0 @@ -#!/bin/sh -set -f - -LOG="" -DEBUG_LEVEL=1 -LOG_D="/run/cloud-init" -ENABLE="enabled" -DISABLE="disabled" -FOUND="found" -NOTFOUND="notfound" -RUN_ENABLED_FILE="$LOG_D/$ENABLE" -CLOUD_SYSTEM_TARGET="/lib/systemd/system/cloud-init.target" -CLOUD_TARGET_NAME="cloud-init.target" -# lxc sets 'container', but lets make that explicitly a global -CONTAINER="${container}" - -debug() { - local lvl="$1" - shift - [ "$lvl" -gt "$DEBUG_LEVEL" ] && return - if [ -z "$LOG" ]; then - local log="$LOG_D/${0##*/}.log" - { [ -d "$LOG_D" ] || mkdir -p "$LOG_D"; } && - { : > "$log"; } >/dev/null 2>&1 && LOG="$log" || - LOG="/dev/kmsg" - fi - echo "$@" >> "$LOG" -} - -etc_file() { - local pprefix="${1:-/etc/cloud/cloud-init.}" - _RET="unset" - [ -f "${pprefix}$ENABLE" ] && _RET="$ENABLE" && return 0 - [ -f "${pprefix}$DISABLE" ] && _RET="$DISABLE" && return 0 - return 0 -} - -read_proc_cmdline() { - # return /proc/cmdline for non-container, and /proc/1/cmdline for container - local ctname="systemd" - if [ -n "$CONTAINER" ] && ctname=$CONTAINER || - systemd-detect-virt --container --quiet; then - if { _RET=$(tr '\0' ' ' < /proc/1/cmdline); } 2>/dev/null; then - _RET_MSG="container[$ctname]: pid 1 cmdline" - return - fi - _RET="" - _RET_MSG="container[$ctname]: pid 1 cmdline not available" - return 0 - fi - - _RET_MSG="/proc/cmdline" - read _RET < /proc/cmdline -} - -kernel_cmdline() { - local cmdline="" tok="" - if [ -n "${KERNEL_CMDLINE+x}" ]; then - # use KERNEL_CMDLINE if present in environment even if empty - cmdline=${KERNEL_CMDLINE} - debug 1 "kernel command line from env KERNEL_CMDLINE: $cmdline" - elif read_proc_cmdline; then - read_proc_cmdline && cmdline="$_RET" - debug 1 "kernel command line ($_RET_MSG): $cmdline" - fi - _RET="unset" - cmdline=" $cmdline " - tok=${cmdline##* cloud-init=} - [ "$tok" = "$cmdline" ] && _RET="unset" - tok=${tok%% *} - [ "$tok" = "$ENABLE" -o "$tok" = "$DISABLE" ] && _RET="$tok" - return 0 -} - -default() { - _RET="$ENABLE" -} - -check_for_datasource() { - local ds_rc="" dsidentify="/usr/lib/cloud-init/ds-identify" - if [ ! -x "$dsidentify" ]; then - debug 1 "no ds-identify in $dsidentify. _RET=$FOUND" - return 0 - fi - $dsidentify - ds_rc=$? - debug 1 "ds-identify rc=$ds_rc" - if [ "$ds_rc" = "0" ]; then - _RET="$FOUND" - debug 1 "ds-identify _RET=$_RET" - return 0 - fi - _RET="$NOTFOUND" - debug 1 "ds-identify _RET=$_RET" - return 1 -} - -main() { - local normal_d="$1" early_d="$2" late_d="$3" - local target_name="multi-user.target" gen_d="$early_d" - local link_path="$gen_d/${target_name}.wants/${CLOUD_TARGET_NAME}" - local ds="$NOTFOUND" - - debug 1 "$0 normal=$normal_d early=$early_d late=$late_d" - debug 2 "$0 $*" - - local search result="error" ret="" - for search in kernel_cmdline etc_file default; do - if $search; then - debug 1 "$search found $_RET" - [ "$_RET" = "$ENABLE" -o "$_RET" = "$DISABLE" ] && - result=$_RET && break - else - ret=$? - debug 0 "search $search returned $ret" - fi - done - - # enable AND ds=found == enable - # enable AND ds=notfound == disable - # disable || == disabled - if [ "$result" = "$ENABLE" ]; then - debug 1 "checking for datasource" - check_for_datasource - ds=$_RET - if [ "$ds" = "$NOTFOUND" ]; then - debug 1 "cloud-init is enabled but no datasource found, disabling" - result="$DISABLE" - fi - fi - - if [ "$result" = "$ENABLE" ]; then - if [ -e "$link_path" ]; then - debug 1 "already enabled: no change needed" - else - [ -d "${link_path%/*}" ] || mkdir -p "${link_path%/*}" || - debug 0 "failed to make dir $link_path" - if ln -snf "$CLOUD_SYSTEM_TARGET" "$link_path"; then - debug 1 "enabled via $link_path -> $CLOUD_SYSTEM_TARGET" - else - ret=$? - debug 0 "[$ret] enable failed:" \ - "ln $CLOUD_SYSTEM_TARGET $link_path" - fi - fi - : > "$RUN_ENABLED_FILE" - elif [ "$result" = "$DISABLE" ]; then - if [ -f "$link_path" ]; then - if rm -f "$link_path"; then - debug 1 "disabled. removed existing $link_path" - else - ret=$? - debug 0 "[$ret] disable failed, remove $link_path" - fi - else - debug 1 "already disabled: no change needed [no $link_path]" - fi - if [ -e "$RUN_ENABLED_FILE" ]; then - rm -f "$RUN_ENABLED_FILE" - fi - else - debug 0 "unexpected result '$result' 'ds=$ds'" - ret=3 - fi - return $ret -} - -main "$@" - -# vi: ts=4 expandtab diff --git a/systemd/cloud-init-generator.tmpl b/systemd/cloud-init-generator.tmpl new file mode 100755 index 00000000..cfa5eb53 --- /dev/null +++ b/systemd/cloud-init-generator.tmpl @@ -0,0 +1,175 @@ +## template:jinja +#!/bin/sh +set -f + +LOG="" +DEBUG_LEVEL=1 +LOG_D="/run/cloud-init" +ENABLE="enabled" +DISABLE="disabled" +FOUND="found" +NOTFOUND="notfound" +RUN_ENABLED_FILE="$LOG_D/$ENABLE" +{% if variant in ["suse"] %} +CLOUD_SYSTEM_TARGET="/usr/lib/systemd/system/cloud-init.target" +{% else %} +CLOUD_SYSTEM_TARGET="/lib/systemd/system/cloud-init.target" +{% endif %} +CLOUD_TARGET_NAME="cloud-init.target" +# lxc sets 'container', but lets make that explicitly a global +CONTAINER="${container}" + +debug() { + local lvl="$1" + shift + [ "$lvl" -gt "$DEBUG_LEVEL" ] && return + if [ -z "$LOG" ]; then + local log="$LOG_D/${0##*/}.log" + { [ -d "$LOG_D" ] || mkdir -p "$LOG_D"; } && + { : > "$log"; } >/dev/null 2>&1 && LOG="$log" || + LOG="/dev/kmsg" + fi + echo "$@" >> "$LOG" +} + +etc_file() { + local pprefix="${1:-/etc/cloud/cloud-init.}" + _RET="unset" + [ -f "${pprefix}$ENABLE" ] && _RET="$ENABLE" && return 0 + [ -f "${pprefix}$DISABLE" ] && _RET="$DISABLE" && return 0 + return 0 +} + +read_proc_cmdline() { + # return /proc/cmdline for non-container, and /proc/1/cmdline for container + local ctname="systemd" + if [ -n "$CONTAINER" ] && ctname=$CONTAINER || + systemd-detect-virt --container --quiet; then + if { _RET=$(tr '\0' ' ' < /proc/1/cmdline); } 2>/dev/null; then + _RET_MSG="container[$ctname]: pid 1 cmdline" + return + fi + _RET="" + _RET_MSG="container[$ctname]: pid 1 cmdline not available" + return 0 + fi + + _RET_MSG="/proc/cmdline" + read _RET < /proc/cmdline +} + +kernel_cmdline() { + local cmdline="" tok="" + if [ -n "${KERNEL_CMDLINE+x}" ]; then + # use KERNEL_CMDLINE if present in environment even if empty + cmdline=${KERNEL_CMDLINE} + debug 1 "kernel command line from env KERNEL_CMDLINE: $cmdline" + elif read_proc_cmdline; then + read_proc_cmdline && cmdline="$_RET" + debug 1 "kernel command line ($_RET_MSG): $cmdline" + fi + _RET="unset" + cmdline=" $cmdline " + tok=${cmdline##* cloud-init=} + [ "$tok" = "$cmdline" ] && _RET="unset" + tok=${tok%% *} + [ "$tok" = "$ENABLE" -o "$tok" = "$DISABLE" ] && _RET="$tok" + return 0 +} + +default() { + _RET="$ENABLE" +} + +check_for_datasource() { + local ds_rc="" dsidentify="/usr/lib/cloud-init/ds-identify" + if [ ! -x "$dsidentify" ]; then + debug 1 "no ds-identify in $dsidentify. _RET=$FOUND" + return 0 + fi + $dsidentify + ds_rc=$? + debug 1 "ds-identify rc=$ds_rc" + if [ "$ds_rc" = "0" ]; then + _RET="$FOUND" + debug 1 "ds-identify _RET=$_RET" + return 0 + fi + _RET="$NOTFOUND" + debug 1 "ds-identify _RET=$_RET" + return 1 +} + +main() { + local normal_d="$1" early_d="$2" late_d="$3" + local target_name="multi-user.target" gen_d="$early_d" + local link_path="$gen_d/${target_name}.wants/${CLOUD_TARGET_NAME}" + local ds="$NOTFOUND" + + debug 1 "$0 normal=$normal_d early=$early_d late=$late_d" + debug 2 "$0 $*" + + local search result="error" ret="" + for search in kernel_cmdline etc_file default; do + if $search; then + debug 1 "$search found $_RET" + [ "$_RET" = "$ENABLE" -o "$_RET" = "$DISABLE" ] && + result=$_RET && break + else + ret=$? + debug 0 "search $search returned $ret" + fi + done + + # enable AND ds=found == enable + # enable AND ds=notfound == disable + # disable || == disabled + if [ "$result" = "$ENABLE" ]; then + debug 1 "checking for datasource" + check_for_datasource + ds=$_RET + if [ "$ds" = "$NOTFOUND" ]; then + debug 1 "cloud-init is enabled but no datasource found, disabling" + result="$DISABLE" + fi + fi + + if [ "$result" = "$ENABLE" ]; then + if [ -e "$link_path" ]; then + debug 1 "already enabled: no change needed" + else + [ -d "${link_path%/*}" ] || mkdir -p "${link_path%/*}" || + debug 0 "failed to make dir $link_path" + if ln -snf "$CLOUD_SYSTEM_TARGET" "$link_path"; then + debug 1 "enabled via $link_path -> $CLOUD_SYSTEM_TARGET" + else + ret=$? + debug 0 "[$ret] enable failed:" \ + "ln $CLOUD_SYSTEM_TARGET $link_path" + fi + fi + : > "$RUN_ENABLED_FILE" + elif [ "$result" = "$DISABLE" ]; then + if [ -f "$link_path" ]; then + if rm -f "$link_path"; then + debug 1 "disabled. removed existing $link_path" + else + ret=$? + debug 0 "[$ret] disable failed, remove $link_path" + fi + else + debug 1 "already disabled: no change needed [no $link_path]" + fi + if [ -e "$RUN_ENABLED_FILE" ]; then + rm -f "$RUN_ENABLED_FILE" + fi + else + debug 0 "unexpected result '$result' 'ds=$ds'" + ret=3 + fi + return $ret +} + +main "$@" + +# vi: ts=4 expandtab -- cgit v1.2.3