Commit 6afa5d757394d47703b61a60a6bdafce540caa1c

Thomas de Grivel 2019-10-26T18:53:16

install packages on OpenBSD

diff --git a/test.lisp b/test.lisp
index 71ec163..9349e13 100644
--- a/test.lisp
+++ b/test.lisp
@@ -30,6 +30,7 @@
 (assert (string= (machine-instance) (first (run "hostname"))))
 
 (adams:clear-resources)
+(adams:clear-probed)
 
 (resource 'host "ams.kmx.io"
           :user "root"
diff --git a/unix/openbsd.lisp b/unix/openbsd.lisp
index d420a7b..7abf3cb 100644
--- a/unix/openbsd.lisp
+++ b/unix/openbsd.lisp
@@ -25,29 +25,37 @@
 
 (define-resource-class openbsd-pkg (pkg)
   ()
-  ((probe-openbsd-pkg :properties (:ensure :flavor :version))))
+  ((probe-openbsd-pkg :properties (:ensure :flavor :version)))
+  ((op-openbsd-pkg :properties (:ensure))))
 
 (define-syntax pkg_info<1> (name version flavor installed)
   #~|\s*([^-\s]+(?:-[^-0-9\s][^-\s]+)*)-([0-9][^-\s]*)(?:-([^-\s]+))?( \(installed\))?|
   "Syntax for pkg_info(1) on OpenBSD"
   (values name version flavor (and installed t)))
 
+(define-syntax openbsd-pkg-id (name flavor)
+  #~|^([^:]+)(?::(.+)$)?|
+  "Syntax for openbsd-pkg id")
+
 (defgeneric probe-openbsd-pkg (resource os))
 
 (defmethod probe-openbsd-pkg ((pkg openbsd-pkg) (os os-openbsd))
   (let ((id (resource-id pkg))
         (ensure :absent))
-    (re-bind #~|^([^:]+)(?::(.+)$)?| (id-name id-flavor) id
+    (with-openbsd-pkg-id (id-name id-flavor) (list id)
+      ;(format t "~&id-name ~S id-flavor ~S~%" id-name id-flavor)
       (multiple-value-bind (version flavor)
           (with-pkg_info<1> (name version flavor installed)
               (run "pkg_info -Q " (sh-quote id-name))
+            ;(format t "~&name ~S version ~S flavor ~S installed ~S~%" name version flavor installed)
             (when (and (string= id-name name)
-                       (or (null id-flavor)
-                           (string= id-flavor flavor)))
+                       (or (and (null id-flavor) (null flavor))
+                           (and id-flavor flavor
+                                (string= id-flavor flavor))))
               (when installed
                 (setf ensure :installed))
               (return (values version flavor))))
-        (properties* ensure version flavor)))))
+        (return (properties* ensure version flavor))))))
 
 (defmethod merge-property-values ((pkg openbsd-pkg)
                                   (property (eql :versions))
@@ -56,18 +64,41 @@
   (sort (remove-duplicates (append old new))
         #'string<))
 
+(defmethod op-openbsd-pkg ((pkg openbsd-pkg) (os os-openbsd) &key ensure)
+  (with-openbsd-pkg-id (id-name id-flavor) (list (resource-id pkg))
+    (when id-flavor
+      (probe pkg :version))
+    (let ((pkg-string (str id-name
+                           (when id-flavor
+                             `(#\- ,(get-probed pkg :version)
+                               #\- ,id-flavor)))))
+      (cond
+        ((eq ensure :absent)
+         (run "pkg_delete " (sh-quote pkg-string)))
+        ((eq ensure :installed)
+         (run "pkg_add " (sh-quote pkg-string)))
+        (t
+         (error "unknown ensure value: ~S" ensure))))))
+
 (defmethod probe-host-packages ((host host) (os os-openbsd))
   (with-host host
-    (let ((packages))
-      (with-pkg_info<1> (name version flavor) (run "pkg_info")
+    (let ((packages)
+          (ensure :installed))
+      (with-pkg_info<1> (name version flavor installed) (run "pkg_info")
         (when (and name version)
           (when flavor
             (setq name (str name #\: flavor)))
           (let ((pkg (resource 'openbsd-pkg name)))
-            (add-probed-properties pkg (properties* name version flavor))
+            (add-probed-properties pkg (properties* name version flavor ensure))
             (push pkg packages))))
       (list :packages (nreverse packages)))))
 
+(defmethod op-host-packages ((host host) (os os-openbsd) &key packages)
+  (with-host host
+    (dolist (id packages)
+      (let ((pkg (resource 'openbsd-pkg id :ensure :installed)))
+        (sync pkg)))))
+
 #+nil
 (clear-resources)