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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
## 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=""
{% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora",
"openEuler", "rhel", "rocky", "virtuozzo"] %}
local dsidentify="/usr/libexec/cloud-init/ds-identify"
{% else %}
local dsidentify="/usr/lib/cloud-init/ds-identify"
{% endif %}
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 || <any> == 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
|