diff --git a/Makefile b/Makefile index 7b3a87e..41d5d2b 100644 --- a/Makefile +++ b/Makefile @@ -61,11 +61,11 @@ dist: build-uberjar ## Build and package Clojure service install: build-jar $(info --------- install library jar ---------) - clojure -T:build install + clojure -T:build/task install deploy: build-jar $(info --------- install library jar ---------) - clojure -T:build deploy + clojure -T:build/task deploy publish: build-jar $(info --------- Build and Package Clojure lib ---------) diff --git a/build.clj b/build.clj index bbcb6a5..96576b8 100644 --- a/build.clj +++ b/build.clj @@ -22,6 +22,7 @@ (ns build (:require [clojure.tools.build.api :as build-api] + [clojure.edn :as edn] [clojure.pprint :as pprint])) ;; --------------------------------------------------------- diff --git a/src/dda/backup/core.clj b/src/dda/backup/core.clj new file mode 100644 index 0000000..9f7b290 --- /dev/null +++ b/src/dda/backup/core.clj @@ -0,0 +1,15 @@ +(ns dda.backup.core + (:require [clojure.spec.alpha :as s] + [orchestra.core :refer [defn-spec]] + )) + +(s/def ::command (s/cat + :app string? + :params (s/* string?))) +(s/def ::commands (s/coll-of ::command)) + +(s/def ::dry-run boolean?) +(s/def ::debug boolean?) + +(def default {:dry-run false + :debug false}) \ No newline at end of file diff --git a/src/dda/backup/infrastructure.clj b/src/dda/backup/infrastructure.clj new file mode 100644 index 0000000..b1f1c38 --- /dev/null +++ b/src/dda/backup/infrastructure.clj @@ -0,0 +1,14 @@ +(ns dda.backup.infrastructure + (:require [orchestra.core :refer [defn-spec]] + [babashka.tasks :as t] + [dda.backup.core :as core])) + +(defn-spec execute! nil? + [commands ::core/command + config any?] + (let [{:keys [dry-run debug]} config] + (doseq [c commands] + (when debug + (println c)) + (when-not dry-run + (apply t/shell c))))) diff --git a/src/dda/backup/management.clj b/src/dda/backup/management.clj index cad04f1..7cde3aa 100644 --- a/src/dda/backup/management.clj +++ b/src/dda/backup/management.clj @@ -2,5 +2,15 @@ (:require [orchestra.core :refer [defn-spec]] [clojure.spec.alpha :as s] - [dda.build.devops.domain :as domain] - [dda.build.infrastructure :as i])) \ No newline at end of file + [dda.backup.core :as core] + [dda.backup.management.domain :as domain] + [dda.backup.infrastructure :as i])) + +(s/def ::config + (s/keys :req-un [::domain/restic-repository ::domain/backup-path] + :opt-un [::domain/certificate-file ::core/debug ::core/dry-run])) + +(defn-spec init! nil? + [config ::config] + (let [config-w-defaults (merge core/default config)] + (i/execute! (domain/init-repo-command config-w-defaults) config-w-defaults))) \ No newline at end of file diff --git a/src/dda/backup/management/domain.clj b/src/dda/backup/management/domain.clj index 5f7015e..b5a4d6a 100644 --- a/src/dda/backup/management/domain.clj +++ b/src/dda/backup/management/domain.clj @@ -1,21 +1,37 @@ (ns dda.backup.management.domain (:require [orchestra.core :refer [defn-spec]] - [clojure.spec.alpha :as s])) + [clojure.spec.alpha :as s] + [dda.backup.core :as core])) -(s/def ::certificate-file string?) (s/def ::restic-repository string?) -(s/def ::backup-file-path string?) +(s/def ::backup-path string?) +(s/def ::certificate-file string?) +(s/def ::password-file string?) (s/def ::config - (s/keys :req-un [::restic-repository ::backup-file-path] - :opt-un [::certificate-file])) + (s/keys :req-un [::restic-repository ::backup-path] + :opt-un [::certificate-file ::password-file])) -; TODO: specify output better -(defn-spec init-repo-command seq? +(defn-spec init-repo-command ::core/commands [config ::config] - (let [{:keys [certificate-file restic-repository backup-file-path]} config] - (if (some? certificate-file) - ["restic" "-r" (str restic-repository "/" backup-file-path) "-v" "init" "--cacert" certificate-file] - ["restic" "-r" (str restic-repository "/" backup-file-path) "-v" "init"] - ))) \ No newline at end of file + (let [{:keys [certificate-file password-file restic-repository backup-path]} config] + (cond + (some? certificate-file) + [ ["restic" "-r" (str restic-repository "/" backup-path) "--cacert" certificate-file "-v" "init"]] + (some? password-file) + [["restic" "-r" (str restic-repository "/" backup-path) "--password-file" password-file "-v" "init"]] + :else + [ ["restic" "-r" (str restic-repository "/" backup-path) "-v" "init"]] + ))) + +(defn-spec list-snapshot-command ::core/commands + [config ::config] + (let [{:keys [certificate-file password-file restic-repository backup-path]} config] + (cond + (some? certificate-file) + [["restic" "-r" (str restic-repository "/" backup-path) "--cacert" certificate-file "-v" "snapshots"]] + (some? password-file) + [["restic" "-r" (str restic-repository "/" backup-path) "--password-file" password-file "-v" "snapshots"]] + :else + [["restic" "-r" (str restic-repository "/" backup-path) "-v" "snapshots"]]))) diff --git a/test/dda/backup/core_test.clj b/test/dda/backup/core_test.clj new file mode 100644 index 0000000..539dc28 --- /dev/null +++ b/test/dda/backup/core_test.clj @@ -0,0 +1,16 @@ +(ns dda.backup.core-test + (:require + [clojure.test :refer [deftest is are testing run-tests]] + [clojure.spec.alpha :as s] + [clojure.spec.test.alpha :as st] + [dda.backup.core :as cut])) + +(deftest should-verify-command + (is (= {:app "restic", :params ["-r" "repo/dir" "-v" "init" "--cacert" "ca"]} + (s/conform ::cut/command ["restic" "-r" "repo/dir" "-v" "init" "--cacert" "ca"])))) + +(deftest should-verify-commands + (is (= [{:app "ls"} + {:app "restic", :params ["-r" "repo/dir" "-v" "init" "--cacert" "ca"]}] + (s/conform ::cut/commands [["ls"] + ["restic" "-r" "repo/dir" "-v" "init" "--cacert" "ca"]])))) diff --git a/test/dda/backup/management/domain_test.clj b/test/dda/backup/management/domain_test.clj index 812fa6e..6d2c6eb 100644 --- a/test/dda/backup/management/domain_test.clj +++ b/test/dda/backup/management/domain_test.clj @@ -5,13 +5,26 @@ [dda.backup.management.domain :as cut])) (st/instrument `cut/init-repo-command) +(st/instrument `cut/list-snapshot-command) (deftest should-calculate-init-repo-command - (is (= ["restic" "-r" "repo/dir" "-v" "init" "--cacert" "ca"] + (is (= [["restic" "-r" "repo/dir" "--cacert" "ca" "-v" "init"]] (cut/init-repo-command {:certificate-file "ca" :restic-repository "repo" - :backup-file-path "dir"}))) - (is (= ["restic" "-r" "repo/dir" "-v" "init"] + :backup-path "dir"}))) + (is (= [["restic" "-r" "repo/dir" "-v" "init"]] (cut/init-repo-command {:restic-repository "repo" - :backup-file-path "dir"}))) - ) + :backup-path "dir"})))) + +(deftest should-calculate-list-snapshot-command + (is (= [["restic" "-r" "repo/dir" "--cacert" "ca" "-v" "snapshots"]] + (cut/list-snapshot-command {:certificate-file "ca" + :restic-repository "repo" + :backup-path "dir"}))) + (is (= [["restic" "-r" "repo/dir" "--password-file" "password" "-v" "snapshots"]] + (cut/list-snapshot-command {:password-file "password" + :restic-repository "repo" + :backup-path "dir"}))) + (is (= [["restic" "-r" "repo/dir" "-v" "snapshots"]] + (cut/list-snapshot-command {:restic-repository "repo" + :backup-path "dir"}))))