Package: guix-patches;
Reported by: Alexander Joss <alex <at> infiniteadaptability.org>
Date: Sun, 17 Nov 2024 08:06:02 UTC
Severity: normal
Tags: patch
View this message in rfc822 format
From: Alexander Joss <alex <at> infiniteadaptability.org> To: 74389 <at> debbugs.gnu.org Cc: Alexander Joss <alex <at> infiniteadaptability.org> Subject: [bug#74389] [PATCH] services: add cloud-init service Date: Sun, 17 Nov 2024 06:26:05 +0000
* 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
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.