Sketching a New Tool for Declarative Systems

News

Let's Sketch Out a Declarative System Configurtion Tool

Let's see if we can start making a tool like Guix but not as complex as Guix, still using Scheme via Sigil:

The Code:

src/sigil-conf/main.sgl

;;; (sigil-conf main) - Application entry point

(define-library (sigil-conf main)
  (import (sigil-conf system)
          (sigil ansi)
          (sigil string)
          (sigil process))

  (export main)

  (begin

    (define (read-all-lines filename)
      (call-with-input-file filename
        (lambda (port)
          (let loop ((lines '()))
            (let ((line (read-line port)))
              (if (eof-object? line)
                  (reverse lines)
                  (loop (cons line lines))))))))

    (define (get-hostname)
      (process-output->string "hostname"))

    (define (apply-system-users system)
      (for-each
       (lambda (user)
         (if (eq? (process-run "id" "-u" (user-name user)) 0)
             (println "User ~a exists!" (user-name user))
             (println "User ~a must be created!" (user-name user))))
       (operating-system-users system)))

    (define (apply-system system)
      ;; Fail if user is not superuser
      (unless (string=? (process-output->string "whoami") "root")
        (error "Must be root to apply system configurations!"))

      ;; Follow a set of steps to determine if the system is in the
      ;; desired state
      (let ((old-hostname (get-hostname))
            (new-hostname (operating-system-hostname system)))
        (when (not (string=? new-hostname
                             old-hostname))
          ;; Change the hostname!
          ;; TODO: Update /etc/hosts and possibly /etc/hostname
          (process-run "hostname" new-hostname)
          (println (str "hostname: "
                        (a:dim old-hostname)
                        (a:green " -> ")
                        new-hostname))))

      (apply-system-users system))

    (define config
      (operating-system
       (hostname "zerocool")
       (timezone "Europe/Athens")
       (users
        (user (name "daviwil")
              (comment "David Wilson")
              (home-directory "/home/daviwil")))))

      (define (main)
        (println "Hello, ~a!"
                 (user-name (car (operating-system-users config))))

        (apply-system config)
        0)))

src/sigil-conf/system.sgl

(define-library (sigil-conf system)
  (export
    operating-system
    operating-system-hostname
    operating-system-users

    user
    user-name
    user-group
    user-comment
    user-home-directory)

  (begin
    (define-record <user>
      (name (type string))
      (comment (type string))
      (group (type string))
      (home-directory (type string)))

    (define-record <operating-system>
      (hostname (type string))
      (timezone (type string))
      (users (default '())
             (variadic)))))

Enjoyed this stream? Explore our hands-on courses for deeper, structured learning on Guile Scheme and more.

Get the System Crafters Newsletter
Updates on open source tools, tutorials, and community projects. We'll also occasionally let you know about new courses and resources.
Name (optional)
Email Address