cloud-init icon indicating copy to clipboard operation
cloud-init copied to clipboard

The cloud-init service failed to start automatically under the openEuler system

Open qingshanxiao292311 opened this issue 5 months ago • 8 comments

Bug report

The cloud-init service failed to start automatically under the openeuler system.

Steps to reproduce the problem

  1. systemctl enable cloud-init-local cloud-init
  2. reboot
  3. 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!

qingshanxiao292311 avatar Jul 24 '25 09:07 qingshanxiao292311

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

qingshanxiao292311 avatar Jul 24 '25 09:07 qingshanxiao292311

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.

blackboxsw avatar Jul 24 '25 16:07 blackboxsw

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 avatar Aug 20 '25 07:08 xiaoge1001

@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

Image

However, if you compile and install from GitHub source code, it will be installed to the /usr/lib/cloud-init path.

qingshanxiao292311 avatar Aug 20 '25 08:08 qingshanxiao292311

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.

xiaoge1001 avatar Aug 20 '25 08:08 xiaoge1001

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 avatar Aug 20 '25 08:08 xiaoge1001

@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?

holmanb avatar Sep 23 '25 15:09 holmanb

@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.

xiaoge1001 avatar Sep 28 '25 07:09 xiaoge1001