@@ -16,7 +16,7 @@ Type=oneshot
# process has completed this stage. The output from the return socket is piped
# into a shell so that the process can send a completion message (defaults to
# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/config.sock | sh'
+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/config.sock
RemainAfterExit=yes
TimeoutSec=0
@@ -19,7 +19,7 @@ Type=oneshot
# process has completed this stage. The output from the return socket is piped
# into a shell so that the process can send a completion message (defaults to
# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/final.sock | sh'
+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/final.sock
RemainAfterExit=yes
TimeoutSec=0
TasksMax=infinity
@@ -32,7 +32,7 @@ ExecStartPre=/sbin/restorecon /run/cloud-init
# process has completed this stage. The output from the return socket is piped
# into a shell so that the process can send a completion message (defaults to
# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/local.sock | sh'
+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/local.sock
RemainAfterExit=yes
TimeoutSec=0
@@ -53,7 +53,7 @@ Type=oneshot
# process has completed this stage. The output from the return socket is piped
# into a shell so that the process can send a completion message (defaults to
# "done", otherwise includes an error message) and an exit code to systemd.
-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/network.sock | sh'
+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/network.sock
RemainAfterExit=yes
TimeoutSec=0
new file mode 100644
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+import socket
+import sys
+import subprocess
+
+def main():
+ if len(sys.argv) < 2:
+ print("Usage: cloud-init-trigger <socket_path>")
+ sys.exit(0)
+
+ socket_path = sys.argv[1]
+
+ try:
+ with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
+ client.connect(socket_path)
+ client.sendall(b'start')
+ message = client.recv(4096)
+
+ if message:
+ cmd = message.decode().strip()
+ result = subprocess.run(cmd, shell=True)
+ sys.exit(result.returncode)
+ else:
+ print("Error: Received empty message from cloud-init-main")
+ sys.exit(0)
+
+ except Exception as e:
+ print(f"Trigger error: {e}")
+ sys.exit(0)
+
+if __name__ == "__main__":
+ main()
+