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)))))