* [bug#74389] [PATCH] services: add cloud-init service
@ 2024-11-17 6:26 Alexander Joss
0 siblings, 0 replies; only message in thread
From: Alexander Joss @ 2024-11-17 6:26 UTC (permalink / raw)
To: 74389; +Cc: Alexander Joss
* gnu/services/cloud-init.scm: add cloud-init service
* gnu/system/examples: add cloud-init-image.tmpl
Change-Id: I28fe295c1dbbab7ea7df65f6b764c7d795e58d77
---
gnu/services/cloud-init.scm | 137 ++++++++++++++++++++++
gnu/system/examples/cloud-init-image.tmpl | 63 ++++++++++
2 files changed, 200 insertions(+)
create mode 100644 gnu/services/cloud-init.scm
create mode 100644 gnu/system/examples/cloud-init-image.tmpl
diff --git a/gnu/services/cloud-init.scm b/gnu/services/cloud-init.scm
new file mode 100644
index 0000000000..d6362f70a7
--- /dev/null
+++ b/gnu/services/cloud-init.scm
@@ -0,0 +1,137 @@
+(define-module (gnu services cloud-init)
+ #:use-module (gnu packages bash)
+ #:use-module (gnu packages python-web)
+ #:use-module (gnu services)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:export (cloud-init-configuration cloud-init-service
+ cloud-init-service-type))
+
+(define-record-type* <cloud-init-configuration> cloud-init-configuration
+ make-cloud-init-configuration
+ cloud-init-configuration?
+
+ (cloud-init cloud-init-configuration-cloud-init ;file-like
+ (default python-cloud-init))
+ (init-modules cloud-init-configuration-init-modules ;list of symbols
+ (default '(seed_random growpart
+ resizefs
+ disk_setup
+ mounts
+ set_hostname
+ update_hostname
+ users_groups
+ ssh
+ set_passwords)))
+ (config-modules cloud-init-configuration-config-modules ;list of symbols
+ (default '()))
+ (final-modules cloud-init-configuration-final-modules ;list of symbols
+ (default '(ssh_authkey_fingerprints)))
+ (extra-configuration-files
+ cloud-init-configuration-extra-configuration-files ;list of file-likes
+ (default '())))
+
+(define %cloud-dir
+ "/etc/cloud")
+
+(define %cloud-cfg
+ (string-append %cloud-dir "/cloud.cfg"))
+
+(define %cloud-run
+ (mixed-text-file "run.sh"
+ "#!"
+ (file-append bash "/bin/bash")
+ "\n\nset -euo pipefail\n\n"
+ (file-append python-cloud-init "/bin/cloud-init")
+ " init --local\n"
+ (file-append python-cloud-init "/bin/cloud-init")
+ " init\n"
+ (file-append python-cloud-init "/bin/cloud-init")
+ " modules --mode config\n"
+ (file-append python-cloud-init "/bin/cloud-init")
+ " modules --mode final\n"))
+
+(define %cloud-cfg-d
+ (string-append %cloud-dir "/cloud.cfg.d"))
+
+(define (cloud-init-initialization init-modules config-modules final-modules
+ extra)
+ "Return the gexp to initialize the cloud-init configuration files"
+ #~(begin
+ (use-modules (srfi srfi-1)
+ (srfi srfi-2)
+ (guix build utils))
+
+ (define reduce-modules
+ (lambda (mods)
+ (string-join (map (lambda (mod)
+ (string-append "\n - "
+ (symbol->string mod))) mods))))
+
+ (mkdir-p #$%cloud-cfg-d)
+
+ (copy-file #$%cloud-run
+ (string-append #$%cloud-dir "/run.sh"))
+ (chmod (string-append #$%cloud-dir "/run.sh") #o755)
+
+ (unless (null? '(#$@extra))
+ (for-each (lambda (file)
+ (symlink (cadr file)
+ (string-append #$%cloud-cfg-d "/"
+ (car file))))
+ '(#$@extra)))
+
+ (call-with-output-file #$%cloud-cfg
+ (lambda (p)
+ (unless (null? '(#$@init-modules))
+ (display (string-append "cloud_init_modules:"
+ (reduce-modules '(#$@init-modules)) "\n\n")
+ p))
+ (unless (null? '(#$@config-modules))
+ (display (string-append "cloud_config_modules:"
+ (reduce-modules '(#$@config-modules))
+ "\n\n") p))
+ (unless (null? '(#$@final-modules))
+ (display (string-append "cloud_final_modules:"
+ (reduce-modules '(#$@final-modules))
+ "\n\n") p))))))
+
+(define (cloud-init-activation config)
+ "Return the activation gexp for CONFIG."
+ #~(begin
+ (use-modules (guix build utils))
+ #$(cloud-init-initialization (cloud-init-configuration-init-modules
+ config)
+ (cloud-init-configuration-config-modules
+ config)
+ (cloud-init-configuration-final-modules
+ config)
+ (cloud-init-configuration-extra-configuration-files
+ config))))
+
+(define (cloud-init-service config)
+ "Return a <cloud-init-service> for cloud-init with CONFIG."
+ (define cloud-init
+ (cloud-init-configuration-cloud-init config))
+
+ (list (shepherd-service (documentation "cloud-init service")
+ (provision '(cloud-init))
+ (requirement '(networking))
+ (one-shot? #t)
+ (start #~(fork+exec-command (list (string-append #$%cloud-dir
+ "/run.sh"))
+ #:log-file (string-append
+ "/var/log/cloud-init.log")
+ #:environment-variables '
+ ("PATH=/run/current-system/profile/bin:/run/current-system/profile/sbin:"))))))
+
+(define cloud-init-service-type
+ (service-type (name 'cloud-init)
+ (default-value (cloud-init-configuration))
+ (description "cloud init")
+ (extensions (list (service-extension
+ shepherd-root-service-type
+ cloud-init-service)
+ (service-extension activation-service-type
+ cloud-init-activation)))))
diff --git a/gnu/system/examples/cloud-init-image.tmpl b/gnu/system/examples/cloud-init-image.tmpl
new file mode 100644
index 0000000000..e2e69e8691
--- /dev/null
+++ b/gnu/system/examples/cloud-init-image.tmpl
@@ -0,0 +1,63 @@
+;; This vm image is meant to be used as an image template
+;; to be deployed on cloud providers that use cloud-init.
+
+(use-modules (gnu)
+ (guix)
+ (guix gexp)
+ (srfi srfi-1))
+(use-service-modules cloud-init base networking ssh)
+(use-package-modules admin bootloaders package-management python-web ssh)
+
+(operating-system
+ (host-name "gnu")
+ (timezone "Etc/UTC")
+ (locale "en_US.utf8")
+ (keyboard-layout (keyboard-layout "us"))
+
+ (firmware '())
+
+ ;; Below we assume /dev/vda is the VM's hard disk.
+ ;; Adjust as needed.
+ (bootloader (bootloader-configuration
+ (bootloader grub-bootloader)
+ (targets '("/dev/vda"))
+ (terminal-outputs '(console))))
+ (file-systems (cons (file-system
+ (mount-point "/")
+ (device "/dev/vda1")
+ (type "ext4")) %base-file-systems))
+
+ ;; The cloud-utils packages provides some utilities to allow
+ ;; us to piggyback off ubuntu's cloud-init modules/integrations
+ ;; without having to write guix specific functionality.
+ ;;
+ ;; The python-cloud-init package is not strictly required to be
+ ;; in system-wide packages.
+ (packages (append (list cloud-utils python-cloud-init) %base-packages))
+
+ (services
+ (append (list (service cloud-init-service-type)
+ ;; An example of extra configuration files. This specific
+ ;; file is required for properly running cloud-init on DigitalOcean
+ ;; (cloud-init-configuration (extra-configuration-files `
+ ;; (("99-digitalocean.cfg" ,
+ ;; (plain-file
+ ;; "99-digitalocean.cfg"
+ ;; "datasource_list: [ ConfigDrive, DigitalOcean, NoCloud, None ]"))))))
+
+ (service network-manager-service-type)
+ (service wpa-supplicant-service-type)
+ (service openssh-service-type
+ (openssh-configuration (openssh openssh-sans-x)
+ (permit-root-login #t))))
+ %base-services
+ ;; Uncomment the following and replace the above to automatically add your guix
+ ;; signing key to the vm for easy reconfiguration.
+ ;; (modify-services %base-services
+ ;; (guix-service-type config =>
+ ;; (guix-configuration (inherit config)
+ ;; (authorized-keys (append
+ ;; (list (local-file
+ ;; "/etc/guix/signing-key.pub"))
+ ;; %default-authorized-guix-keys)))))))
+ )))
base-commit: 0e1ffbc7f5f060f89c890472377a6102f27f6e9b
--
2.46.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2024-11-17 13:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-17 6:26 [bug#74389] [PATCH] services: add cloud-init service Alexander Joss
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.