The cloud-init service failed to start automatically under the openEuler system
Bug report
The cloud-init service failed to start automatically under the openeuler system.
Steps to reproduce the problem
- systemctl enable cloud-init-local cloud-init
- reboot
- systemctl status cloud-init
Environment details
- Cloud-init version: 24.1.4
- Operating System Distribution: openEuler 2203
- Cloud provider, platform or installer type: VM on Proxmox
logs
[root@openeuler-2203-cloud-init ~]# systemctl status cloud-init ○ cloud-init.service - Initial cloud-init job (metadata service crawler) Loaded: loaded (/usr/lib/systemd/system/cloud-init.service; enabled; vendor preset: disabled) Active: inactive (dead)
[root@openeuler-2203-cloud-init ~]# dmesg | grep cloud [ 7.946722] systemd[1]: Hostname set to <openeuler-2203-cloud-init>. [ 8.060676] (sd-executor)[600]: /usr/lib/systemd/system-generators/cloud-init-generator failed with exit status 3.
[root@openeuler-2203-cloud-init ~]# /usr/lib/systemd/system-generators/cloud-init-generator /usr/lib/systemd/system-generators/cloud-init-generator: line 51: /usr/libexec/cloud-init/ds-identify: No such file or directory
I found that the main branch also has this problem!
Problem location
[root@openeuler-2203-cloud-init ~]# dmesg | grep cloud-init [ 7.946722] systemd[1]: Hostname set to <openeuler-2203-cloud-init>. [ 8.060676] (sd-executor)[600]: /usr/lib/systemd/system-generators/cloud-init-generator failed with exit status 3.
[root@openeuler-2203-cloud-init ~]# /usr/lib/systemd/system-generators/cloud-init-generator /usr/lib/systemd/system-generators/cloud-init-generator: line 51: /usr/libexec/cloud-init/ds-identify: No such file or directory
cat /usr/lib/systemd/system-generators/cloud-init-generator
1 #!/bin/sh
2 set -f
3
4 LOG=""
5 DEBUG_LEVEL=1
6 LOG_D="/run/cloud-init"
7 LOG_F="/run/cloud-init/cloud-init-generator.log"
8 ENABLE="enabled"
9 DISABLE="disabled"
10 RUN_ENABLED_FILE="$LOG_D/$ENABLE"
11 RUN_DISABLED_FILE="$LOG_D/$DISABLE"
12 CLOUD_TARGET_NAME="cloud-init.target"
13 # lxc sets 'container', but lets make that explicitly a global
14 CONTAINER="${container}"
15
16 # start: template section
17 CLOUD_SYSTEM_TARGET="/lib/systemd/system/cloud-init.target"
18 dsidentify="/usr/libexec/cloud-init/ds-identify"
19 # end: template section
20
21 debug() {
22 local lvl="$1"
23 shift
24 [ "$lvl" -gt "$DEBUG_LEVEL" ] && return
25 if [ -z "$LOG" ]; then
26 { [ -d "$LOG_D" ] || mkdir -p "$LOG_D"; } &&
27 { : > "$LOG_F"; } >/dev/null 2>&1 && LOG="$LOG_F" ||
28 LOG="/dev/kmsg"
29 fi
30 echo "$@" >> "$LOG"
31 }
32
33 main() {
34 local normal_d="$1" early_d="$2" late_d="$3"
35 local target_name="multi-user.target" gen_d="$early_d"
36 local link_path="$gen_d/${target_name}.wants/${CLOUD_TARGET_NAME}"
37 local ds="" ret=""
38
39 debug 1 "$0 normal=$normal_d early=$early_d late=$late_d"
40 debug 2 "$0 $*"
41
42 # ds=found => enable
43 # ds=notfound => disable
44 # <any> => disable
45 debug 1 "checking for datasource"
46
47 if [ ! -x "$dsidentify" ]; then
48 debug 1 "no ds-identify in $dsidentify"
49 ds=0
50 fi
51 $dsidentify
52 ds=$?
53 debug 1 "ds-identify rc=$ds"
54
.......
101 }
102
103 main "$@"
According to log: /usr/libexec/cloud-init/ds-identify: No such file or directory. Make sure the /usr/libexec/cloud-init directory does not exist.
View 24.1.x source code
1. cloud-init-generator.tmpl
The script cloud-init-generator is generated by cloud-init-generator.tmpl https://github.com/canonical/cloud-init/blob/2d20f8b33f0f3e11f947e8e36d037605b1ff5d76/systemd/cloud-init-generator.tmpl#L16-L32
The existence of the openeuler element causes dsidentify to be assigned to /usr/libexec/cloud-init/ds-identify on line 25
2. setup.py
ds-identify is installed to the specified path through setup.py.
In the openeuler system, the default USR_LIB_EXEC path is usr/lib
https://github.com/canonical/cloud-init/blob/2d20f8b33f0f3e11f947e8e36d037605b1ff5d76/setup.py#L181-L201
The installation path of ds-identify is /USR_LIB_EXEC/cloud-init
https://github.com/canonical/cloud-init/blob/2d20f8b33f0f3e11f947e8e36d037605b1ff5d76/setup.py#L272
https://github.com/canonical/cloud-init/blob/2d20f8b33f0f3e11f947e8e36d037605b1ff5d76/setup.py#L277-L290
so ds-identify installed to /usr/lib/cloud-init directory, don't installed to /usr/libexec/cloud-init directory.
Solution
delete "openeuler" on line 24 in the file cloud-init-generate.tmpl https://github.com/canonical/cloud-init/blob/2d20f8b33f0f3e11f947e8e36d037605b1ff5d76/systemd/cloud-init-generator.tmpl#L24
Good analysis @qingshanxiao292311 thank you!
I agree with your approach and your note here about openeuler using /usr/lib/cloud-init instead of /usr/libexec/cloud-init will also inform our ongoing work to shift upstream cloud-init away from setuptools via setup.py to meson build system https://github.com/canonical/cloud-init/pull/6326.
If you are able to open a PR with this proposed solution, we can get that into the next cloud-init 25.2 release.
openEuler 22.03-LTS cloud-init version is 21.4 and ds-identify script is /usr/libexec/cloud-init/ds-identify. it is ok.
[root@openEuler ~]# uname -r
5.10.0-245.0.0.144.oe2203sp4.aarch64
[root@openEuler ~]#
[root@openEuler ~]# rpm -qa cloud-init
cloud-init-21.4-36.oe2203sp4.noarch
[root@openEuler ~]# rpm -ql cloud-init |grep ds-identify
/usr/libexec/cloud-init/ds-identify
[root@openEuler ~]#
openEuler has not selected cloud-ini-24.1.4, the latest version of cloud-init in openEuler is 25.1. I check cloud-init.rpm in openEuler-25.09 and ds-identify is /usr/libexec/cloud-init/ds-identify, the aforementioned issues still do not exist.
[root@openEuler ~]# rpm -ql cloud-init-25.1-4.oe2509.noarch.rpm |grep ds-identify
/usr/libexec/cloud-init/ds-identify
[root@openEuler ~]#
@xiaoge1001 This is because when making the rpm package, the redhat-release in setup.py was changed to openEuler-release, the installation path is changed to /usr/libexec/cloud-init. https://gitee.com/src-openeuler/cloud-init/blob/openEuler-22.03-LTS-SP3/cloud-init.spec#L125
However, if you compile and install from GitHub source code, it will be installed to the /usr/lib/cloud-init path.
Understood. Then we can modify the setup.py to be compatible with openEuler, or use the spec file provided by openEuler to build the software package.
delete "openeuler" on line 24 in the file cloud-init-generate.tmpl
It is not recommended to do so. Although this approach would also solve the problem, the ds-identify script in the openEuler operating system has always been installed in the /usr/libexec/cloud-init directory. It is advised to keep this location unchanged.
@xiaoge1001 Have you tried building a cloud-init package for openEuler using the meson packaging changes? Meson is capable of taking arguments to set a libexec directory. I haven't looked at the details of this specific issue. Can you please confirm if this is still an issue after the switch to meson?
@xiaoge1001 Have you tried building a cloud-init package for openEuler using the meson packaging changes? Meson is capable of taking arguments to set a libexec directory. I haven't looked at the details of this specific issue. Can you please confirm if this is still an issue after the switch to meson?
I use meson to build cloud-init and it is ok.