From patchwork Sun Nov 17 06:26:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Joss X-Patchwork-Id: 70471 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id AC47427BBE9; Sun, 17 Nov 2024 13:53:17 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 7E47127BBE2 for ; Sun, 17 Nov 2024 13:53:14 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCfhx-00089T-Ir; Sun, 17 Nov 2024 08:52:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCaIF-0006DW-3x for guix-patches@gnu.org; Sun, 17 Nov 2024 03:06:03 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCaIE-0008R1-RH for guix-patches@gnu.org; Sun, 17 Nov 2024 03:06:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:From:Date:To:Subject; bh=20HvoMqWlqwl72T5sf6bLaRwv4RGdbUNgZh0nkFlgWk=; b=sryTfxWwh13nWhemlKC8PXOolXkPPBPtsV08ZuVapB0IrwZ6OWpDKQ+CHm9CHeWSNC0ZWSB2I68neHMGas74OCHNHrVjFbLA/L3XCXT5OJ40wqBWpdvHf6BPBoLEsz52GzYWihyGE/k0+dIMI4uK38TdHtMke++F0uXyUoqPlnkKqzd9crD0p4OfqHeSbN90LSbNvDhufxUoUTPWeIkd/gR1FLIiclEOWKrNCZaLGL8U5Mlmd+WomZLiQIiD71TBGmQo52Kdu4GhcBXimjQOTfLy+Ul/P3t+e18aFIliFlnXCWSbctVQg52zTBav3oRtlhXKfFk/VNlTXRlsaMlprQ==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tCaIE-0004BZ-AZ for guix-patches@gnu.org; Sun, 17 Nov 2024 03:06:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#74389] [PATCH] services: add cloud-init service Resent-From: Alexander Joss Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sun, 17 Nov 2024 08:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 74389 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 74389@debbugs.gnu.org Cc: Alexander Joss X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.173183073016035 (code B ref -1); Sun, 17 Nov 2024 08:06:02 +0000 Received: (at submit) by debbugs.gnu.org; 17 Nov 2024 08:05:30 +0000 Received: from localhost ([127.0.0.1]:55815 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tCaHh-0004AY-2A for submit@debbugs.gnu.org; Sun, 17 Nov 2024 03:05:30 -0500 Received: from lists.gnu.org ([209.51.188.17]:40862) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tCYjt-0007p9-CV for submit@debbugs.gnu.org; Sun, 17 Nov 2024 01:26:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCYjq-0003LO-G1 for guix-patches@gnu.org; Sun, 17 Nov 2024 01:26:28 -0500 Received: from mail-4022.proton.ch ([185.70.40.22]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCYjm-0007yM-Re for guix-patches@gnu.org; Sun, 17 Nov 2024 01:26:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=infiniteadaptability.org; s=protonmail3; t=1731824772; x=1732083972; bh=20HvoMqWlqwl72T5sf6bLaRwv4RGdbUNgZh0nkFlgWk=; h=Date:To:From:Cc:Subject:Message-ID:Feedback-ID:From:To:Cc:Date: Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector: List-Unsubscribe:List-Unsubscribe-Post; b=Y/Tx8VwFamZPx0osB5EfNqUbqN3AnmAQnhmYTgmZly6F9jA0CD2KZ+BiINWDqZVBu UNj+LsZcMm+VT5+dDULX+M5NG80sAEHho73WyADrz58hIH6UIL2pS5yz/DGkh7OHqS gKl317XzW7am0R+zQrfbgCYp5P5LBVyT3yBubBgJ0qSc16FpoorKprx+NnyXzzIzjr pnTDMSRRei8Pdky15d059AKAaURc2diPSBtrlnXjOHcVCTCe+LoQsRKm2fvX+S+nr6 v1q3PFo3M5Fmdv/y4AgjLVb4LxuN1yeQKEcPg5nHhRe7l01VXFfKUiS9to2QnuEg/V 4Q1nk5IaqlzsQ== Date: Sun, 17 Nov 2024 06:26:05 +0000 From: Alexander Joss Message-ID: Feedback-ID: 41959981:user:proton X-Pm-Message-ID: 2e02c1fe6ad664ec07d71d843f994c5c8555458c MIME-Version: 1.0 Received-SPF: pass client-ip=185.70.40.22; envelope-from=alex@infiniteadaptability.org; helo=mail-4022.proton.ch X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 03:05:27 -0500 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Mailman-Approved-At: Sun, 17 Nov 2024 08:52:55 -0500 X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * 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 base-commit: 0e1ffbc7f5f060f89c890472377a6102f27f6e9b 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 + 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 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))))))) + )))