diff --git a/unix/defs.lisp b/unix/defs.lisp
index ee07370..e3d4815 100644
--- a/unix/defs.lisp
+++ b/unix/defs.lisp
@@ -85,9 +85,12 @@
(push `(,(sym 'probe-file-cksum- algorithm)
:properties (,algorithm))
algorithms))
- (nreverse algorithms))))
+ (nreverse algorithms)))
+ ((op-file-ensure :properties (:ensure)))
+ ((:op-properties (:ensure :mode :uid :gid :owner :group))))
(defgeneric probe-file-content (resource os))
+(defgeneric op-file-ensure (resource os &key ensure))
;; Directory
diff --git a/unix/operations.lisp b/unix/operations.lisp
index 5d882aa..931fcf5 100644
--- a/unix/operations.lisp
+++ b/unix/operations.lisp
@@ -82,4 +82,26 @@
(defmethod op-chmod ((res vnode) (os os-unix) &key mode
&allow-other-keys)
- (run "chmod " (octal (mode-permissions mode)) " " (sh-quote (resource-id res))))
+ (run "chmod " (octal (mode-permissions mode)) " "
+ (sh-quote (resource-id res))))
+
+;; File
+
+(defmethod op-file-ensure ((res file) (os os-unix) &key ensure)
+ (let* ((id (resource-id res))
+ (sh-id (sh-quote id)))
+ (ecase ensure
+ ((:absent) (run "rm " sh-id))
+ ((:present) (run "touch " sh-id))
+ ((nil)))))
+
+;; Directory
+
+(defmethod op-directory-ensure ((res directory) (os os-unix)
+ &key ensure)
+ (let* ((id (resource-id res))
+ (sh-id (sh-quote id)))
+ (ecase ensure
+ ((:absent) (run "rmdir " sh-id))
+ ((:present) (run "mkdir " sh-id))
+ ((nil)))))
diff --git a/unix/probes.lisp b/unix/probes.lisp
index 9d7badf..e271418 100644
--- a/unix/probes.lisp
+++ b/unix/probes.lisp
@@ -78,27 +78,30 @@
;; VNode (filesystem node)
(defmethod probe-vnode-using-ls ((vnode vnode) (os os-unix))
- (let ((id (resource-id vnode)))
+ (let ((id (resource-id vnode))
+ (ensure :absent))
(multiple-value-bind #1=(mode links owner group size mtime)
(with-ls<1>-lT #.(cons 'name '#1#)
(ls "-ldT" id)
(when (string= id name)
(setq mode (mode (mode-permissions mode))
owner (resource 'user owner)
- group (resource 'group group))
+ group (resource 'group group)
+ ensure :present)
(return (values* #1#))))
- (properties* #1#))))
+ (properties* (ensure . #1#)))))
(defmethod probe-vnode-using-stat ((vnode vnode) (os os-unix))
- (let ((id (resource-id vnode)))
+ (let ((id (resource-id vnode))
+ (ensure :absent))
(multiple-value-bind #1=(dev ino mode links uid gid rdev size
atime mtime ctime blksize blocks flags)
- (with-stat<1>-r #.(cons 'name '#1#)
- (stat "-r" id)
- (when (string= id name)
- (setq mode (mode (mode-permissions mode)))
+ (with-stat<1>-r (name . #1#) (stat "-r" id)
+ (when (and name (string= id (the string name)))
+ (setq mode (mode (mode-permissions mode))
+ ensure :present)
(return (values* #1#))))
- (properties* #1#))))
+ (properties* (ensure . #1#)))))
;; Regular file