[PATCH] services: add cloud-init service

  • Open
  • quality assurance status badge
Details
One participant
  • Alexander Joss
Owner
unassigned
Submitted by
Alexander Joss
Severity
normal
A
A
Alexander Joss wrote 4 days ago
(address . guix-patches@gnu.org)(name . Alexander Joss)(address . alex@infiniteadaptability.org)
c907e459d6898df885e3aac67c8446a1c15d62b2.1731824739.git.alex@infiniteadaptability.org
* 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

Toggle diff (216 lines)
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
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send an email to 74389@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 74389
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch