add forget & backup

This commit is contained in:
Michael Jerger 2024-08-16 17:36:28 +02:00
parent 7dc92c6a2d
commit c6c96f5eb8
11 changed files with 198 additions and 84 deletions

View file

@ -2,6 +2,22 @@
(:require (:require
[orchestra.core :refer [defn-spec]] [orchestra.core :refer [defn-spec]]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[dda.backup.core :as core] [dda.backup.core.domain :as core]
[dda.backup.management.domain :as domain] [dda.backup.backup.domain :as domain]
[dda.backup.management :as mgm]
[dda.backup.infrastructure :as i])) [dda.backup.infrastructure :as i]))
(s/def ::config
(s/keys :req-un [::core/restic-repository ::core/backup-path]
:opt-un [::core/certificate-file ::core/directory ::core/debug ::core/dry-run]))
(defn-spec backup! nil?
[config ::config
files (s/* string?)]
(let [config-w-defaults (merge core/default config)]
(mgm/unlock! config-w-defaults)
(i/execute!
(domain/backup-files-command config-w-defaults files)
config-w-defaults)
(mgm/forget! config-w-defaults)
))

View file

@ -0,0 +1,11 @@
(ns dda.backup.backup.domain
(:require
[orchestra.core :refer [defn-spec]]
[clojure.spec.alpha :as s]
[dda.backup.core.domain :as core]))
(defn-spec backup-files-command ::core/commands
[config ::core/config
files (s/* string?)]
(let [{:keys [certificate-file password-file restic-repository backup-path]} config]
(core/repo-command config (into ["backup"] files))))

View file

@ -3,13 +3,10 @@
[orchestra.core :refer [defn-spec]] [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 ::dry-run boolean?)
(s/def ::debug boolean?) (s/def ::debug boolean?)
(def default {:dry-run false (def default {:dry-run false
:debug false}) :debug false
:days-to-keep 30
:months-to-keep 12})

View file

@ -0,0 +1,41 @@
(ns dda.backup.core.domain
(:require
[orchestra.core :refer [defn-spec]]
[clojure.spec.alpha :as s]))
(s/def ::command (s/cat
:app string?
:params (s/* string?)))
(s/def ::commands (s/coll-of ::command))
(s/def ::certificate-file string?)
(s/def ::password-file string?)
(s/def ::restic-repository string?)
(s/def ::backup-path string?)
(s/def ::directory string?)
(s/def ::days-to-keep pos?)
(s/def ::months-to-keep pos?)
(s/def ::config
(s/keys :req-un [::restic-repository ::backup-path ::days-to-keep ::months-to-keep]
:opt-un [::certificate-file ::password-file ::directory]))
(defn-spec repo-command ::commands
[config ::config
command ::command]
(let [{:keys [certificate-file password-file directory restic-repository backup-path]} config]
[(into
[]
(concat
(if (some? directory)
[{:dir directory}]
[])
["restic" "-r" (str restic-repository "/" backup-path) "-v"]
(cond
(some? certificate-file)
["--cacert" certificate-file]
(some? password-file)
["--password-file" password-file]
:else
[])
command))]))

View file

@ -1,11 +1,11 @@
(ns dda.backup.infrastructure (ns dda.backup.infrastructure
(:require [orchestra.core :refer [defn-spec]] (:require [orchestra.core :refer [defn-spec]]
[babashka.tasks :as t] [babashka.tasks :as t]
[dda.backup.core :as core])) [dda.backup.core.domain :as core]))
(defn-spec execute! nil? (defn-spec execute! nil?
[commands ::core/command [commands ::core/command
config any?] config ::core/config]
(let [{:keys [dry-run debug]} config] (let [{:keys [dry-run debug]} config]
(doseq [c commands] (doseq [c commands]
(when debug (when debug

View file

@ -2,13 +2,14 @@
(:require (:require
[orchestra.core :refer [defn-spec]] [orchestra.core :refer [defn-spec]]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[dda.backup.core :as core] [dda.backup.core.domain :as core]
[dda.backup.management.domain :as domain] [dda.backup.management.domain :as domain]
[dda.backup.infrastructure :as i])) [dda.backup.infrastructure :as i]))
(s/def ::config (s/def ::config
(s/keys :req-un [::domain/restic-repository ::domain/backup-path] (s/keys :req-un [::core/restic-repository ::core/backup-path]
:opt-un [::domain/certificate-file ::core/debug ::core/dry-run])) :opt-un [::core/certificate-file ::core/directory ::core/debug
::core/dry-run ::core/days-to-keep ::core/months-to-keep]))
(defn-spec initalized? boolean? (defn-spec initalized? boolean?
[config ::config] [config ::config]
@ -29,3 +30,8 @@
[config ::config] [config ::config]
(let [config-w-defaults (merge core/default config)] (let [config-w-defaults (merge core/default config)]
(i/execute! (domain/unlock-repo-command config-w-defaults) config-w-defaults))) (i/execute! (domain/unlock-repo-command config-w-defaults) config-w-defaults)))
(defn-spec forget! nil?
[config ::config]
(let [config-w-defaults (merge core/default config)]
(i/execute! (domain/forget-command config-w-defaults) config-w-defaults)))

View file

@ -2,49 +2,28 @@
(:require (:require
[orchestra.core :refer [defn-spec]] [orchestra.core :refer [defn-spec]]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[dda.backup.core :as core])) [dda.backup.core.domain :as core]))
(s/def ::restic-repository 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-path]
:opt-un [::certificate-file ::password-file]))
(defn repo-command
[config
commands]
(let [{:keys [certificate-file password-file restic-repository backup-path]} config]
[(into
["restic" "-r" (str restic-repository "/" backup-path) "-v"]
(concat
(cond
(some? certificate-file)
["--cacert" certificate-file]
(some? password-file)
["--password-file" password-file]
:else
[])
commands))]))
(defn-spec check-repo-command ::core/commands (defn-spec check-repo-command ::core/commands
[config ::config] [config ::core/config]
(let [{:keys [certificate-file password-file restic-repository backup-path]} config] (core/repo-command config ["check"]))
(repo-command config ["check"])))
(defn-spec init-repo-command ::core/commands (defn-spec init-repo-command ::core/commands
[config ::config] [config ::core/config]
(let [{:keys [certificate-file password-file restic-repository backup-path]} config] (core/repo-command config ["init"]))
(repo-command config ["init"])))
(defn-spec unlock-repo-command ::core/commands (defn-spec unlock-repo-command ::core/commands
[config ::config] [config ::core/config]
(let [{:keys [certificate-file password-file restic-repository backup-path]} config] (core/repo-command config ["--cleanup-cache" "unlock"]))
(repo-command config ["--cleanup-cache" "unlock"])))
(defn-spec list-snapshot-command ::core/commands (defn-spec list-snapshot-command ::core/commands
[config ::config] [config ::core/config]
(let [{:keys [certificate-file password-file restic-repository backup-path]} config] (core/repo-command config ["snapshots"]))
(repo-command config ["snapshots"])))
(defn-spec forget-command ::core/commands
[config ::core/config]
(let [{:keys [days-to-keep months-to-keep]} config]
(core/repo-command config ["forget" "--group-by" "''"
"--keep-last" "1"
"--keep-daily" (str days-to-keep)
"--keep-monthly" (str months-to-keep) "--prune"])))

View file

@ -0,0 +1,23 @@
(ns dda.backup.backup.domain-test
(:require
[clojure.test :refer [deftest is are testing run-tests]]
[clojure.spec.test.alpha :as st]
[dda.backup.backup.domain :as cut]))
(st/instrument `cut/backup-files-command)
(deftest should-calculate-backup-files-command
(is (= [[{:dir "dir-to-backup"}
"restic"
"-r"
"repo/dir-at-repo"
"-v"
"backup"
"file2"
"file2"]]
(cut/backup-files-command {:restic-repository "repo"
:backup-path "dir-at-repo"
:directory "dir-to-backup"
:days-to-keep 39
:months-to-keep 3}
["file2" "file2"]))))

View file

@ -0,0 +1,57 @@
(ns dda.backup.core.domain-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.domain :as cut]))
(st/instrument `cut/repo-command)
(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"]]))))
(deftest should-calculate-repo-command
(is (= [[{:dir "dir"}
"restic"
"-r"
"repo/dir"
"-v"
"--cacert"
"ca"
"backup"
"file1"
"file2"]]
(cut/repo-command {:certificate-file "ca"
:directory "dir"
:restic-repository "repo"
:backup-path "dir"
:days-to-keep 39
:months-to-keep 3}
["backup" "file1" "file2"])))
(is (= [["restic" "-r" "repo/dir" "-v" "--cacert" "ca" "snapshots"]]
(cut/repo-command {:certificate-file "ca"
:restic-repository "repo"
:backup-path "dir"
:days-to-keep 39
:months-to-keep 3}
["snapshots"])))
(is (= [["restic" "-r" "repo/dir" "-v" "--password-file" "password" "snapshots"]]
(cut/repo-command {:password-file "password"
:restic-repository "repo"
:backup-path "dir"
:days-to-keep 39
:months-to-keep 3}
["snapshots"])))
(is (= [["restic" "-r" "repo/dir" "-v" "snapshots"]]
(cut/repo-command {:restic-repository "repo"
:backup-path "dir"
:days-to-keep 39
:months-to-keep 3}
["snapshots"]))))

View file

@ -1,16 +0,0 @@
(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"]]))))

View file

@ -6,27 +6,27 @@
(st/instrument `cut/init-repo-command) (st/instrument `cut/init-repo-command)
(st/instrument `cut/unlock-repo-command) (st/instrument `cut/unlock-repo-command)
(st/instrument `cut/list-snapshot-command) (st/instrument `cut/forget-command)
(deftest should-calculate-list-snapshot-command
(is (= [["restic" "-r" "repo/dir" "-v" "--cacert" "ca" "snapshots"]]
(cut/list-snapshot-command {:certificate-file "ca"
:restic-repository "repo"
:backup-path "dir"})))
(is (= [["restic" "-r" "repo/dir" "-v" "--password-file" "password" "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"}))))
(deftest should-calculate-init-repo-command (deftest should-calculate-init-repo-command
(is (= [["restic" "-r" "repo/dir" "-v" "init"]] (is (= [["restic" "-r" "repo/dir" "-v" "init"]]
(cut/init-repo-command {:restic-repository "repo" (cut/init-repo-command {:restic-repository "repo"
:backup-path "dir"})))) :backup-path "dir"
:days-to-keep 39
:months-to-keep 3}))))
(deftest should-calculate-unlock-repo-command (deftest should-calculate-unlock-repo-command
(is (= [["restic" "-r" "repo/dir" "-v" "--cleanup-cache" "unlock"]] (is (= [["restic" "-r" "repo/dir" "-v" "--cleanup-cache" "unlock"]]
(cut/unlock-repo-command {:restic-repository "repo" (cut/unlock-repo-command {:restic-repository "repo"
:backup-path "dir"})))) :backup-path "dir"
:days-to-keep 39
:months-to-keep 3}))))
(deftest should-calculate-forget-command
(is (= [["restic" "-r" "repo/dir" "-v" "forget"
"--group-by" "''" "--keep-last" "1"
"--keep-daily" "39" "--keep-monthly" "3" "--prune"]]
(cut/forget-command {:restic-repository "repo"
:backup-path "dir"
:days-to-keep 39
:months-to-keep 3}))))