summaryrefslogtreecommitdiff
path: root/systemd/cloud-init-generator
blob: 2d31969568f9016e8629cdeeabad242d43c18919 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/sh
set -f

LOG=""
DEBUG_LEVEL=1
LOG_D="/run/cloud-init"
ENABLE="enabled"
DISABLE="disabled"
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"
}

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}"

    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
    
    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
    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
    else
        debug 0 "unexpected result '$result'"
        ret=3
    fi
    return $ret
}

main "$@"

# vi: ts=4 expandtab