Compare commits

...

10 commits
master ... main

15 changed files with 93 additions and 40 deletions

View file

@ -41,7 +41,7 @@ package-jar:
<<: *clj <<: *clj
stage: package stage: package
script: script:
- pyb package_jar - pyb package
artifacts: artifacts:
paths: paths:
- target/org.domaindrivenarchitecture - target/org.domaindrivenarchitecture
@ -51,7 +51,7 @@ release-to-clojars:
<<: *tag_only <<: *tag_only
stage: upload stage: upload
script: script:
- pyb upload_clj - pyb upload
dda-backup-image-publish: dda-backup-image-publish:
<<: *img <<: *img

View file

@ -35,17 +35,17 @@ def initialize(project):
@task @task
def test_clj(project): def test(project):
run("make test", shell=True, check=True) run("make test", shell=True, check=True)
@task @task
def package_jar(project): def package(project):
run("make build-jar", shell=True, check=True) run("make build-jar", shell=True, check=True)
@task @task
def upload_clj(project): def upload(project):
run("make deploy", shell=True, check=True) run("make deploy", shell=True, check=True)

View file

@ -4,3 +4,4 @@ FROM ubuntu:24.04
ADD resources /tmp/ ADD resources /tmp/
RUN /tmp/install.sh RUN /tmp/install.sh
ADD local/ /usr/local/lib/dda-backup ADD local/ /usr/local/lib/dda-backup
RUN init-bb.bb

View file

@ -0,0 +1,3 @@
{:deps {org.clojure/spec.alpha {:mvn/version "0.4.233"}
orchestra/orchestra {:mvn/version "2021.01.01-1"}
org.domaindrivenarchitecture/dda-backup {:local/root "/usr/local/lib/dda-backup"}}}

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bb
(println "initialized")

View file

@ -15,15 +15,15 @@ function babashka_install() {
function main() { function main() {
{ {
upgradeSystem upgradeSystem
apt-get install -qqy ca-certificates curl gnupg postgresql-client-16 restic apt-get install -qqy ca-certificates curl gnupg postgresql-client-16 restic openjdk-21-jre-headless nano
curl -Ss --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/postgresql-common_pgdg_archive_keyring.gpg curl -Ss --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/postgresql-common_pgdg_archive_keyring.gpg
sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/postgresql-common_pgdg_archive_keyring.gpg] https://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list' sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/postgresql-common_pgdg_archive_keyring.gpg] https://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
upgradeSystem upgradeSystem
babashka_install babashka_install
} > /dev/null } > /dev/null
update-ca-certificates update-ca-certificates
install -m 0700 -o root -g root /tmp/init-bb.bb /usr/local/bin/
cleanupDocker cleanupDocker
} }

View file

@ -1,7 +1,6 @@
FROM c4k-forgejo-backup:latest FROM dda-backup:latest
# install it # install it
RUN apt update && apt install -qqy openjdk-17-jre-headless #ADD local/ /usr/local/lib/dda-backup
ADD local/ /usr/local/lib/dda-backup
ADD resources /tmp/ ADD resources /tmp/
RUN ENV_PASSWORD=env-password /tmp/test.bb RUN ENV_PASSWORD=env-password FILE_PASSWORD_FILE=/tmp/file_password /tmp/test.bb

View file

@ -26,6 +26,4 @@
"https://repo.prod.meissa.de/attachments/0a1da41e-aa5b-4a3e-a3b1-215cf2d5b021" "https://repo.prod.meissa.de/attachments/0a1da41e-aa5b-4a3e-a3b1-215cf2d5b021"
"https://repo.prod.meissa.de/attachments/f227cf65-cb0f-46a7-a6cd-28f46917412a") "https://repo.prod.meissa.de/attachments/f227cf65-cb0f-46a7-a6cd-28f46917412a")
(install! "provs-syspec.jar") (install! "provs-syspec.jar")
(tasks/shell "apt" "update")
(tasks/shell "apt" "install" "-qqy" "openjdk-17-jre-headless")
(tasks/shell "java" "-jar" "/usr/local/bin/provs-syspec.jar" "local" "-c" "/tmp/spec.yml" ) (tasks/shell "java" "-jar" "/usr/local/bin/provs-syspec.jar" "local" "-c" "/tmp/spec.yml" )

View file

@ -24,9 +24,9 @@
(defn prepare! (defn prepare!
[] []
(spit "file_password" "file-password") (spit "/tmp/file_password" "file-password")
(println (bc/env-or-file "file_password")) (println (bc/env-or-file "FILE_PASSWORD"))
(println (bc/env-or-file "env_password")) (println (bc/env-or-file "ENV_PASSWORD"))
(spit "restic-pwd" "ThePassword") (spit "restic-pwd" "ThePassword")
(tasks/shell "mkdir" "-p" "test-backup") (tasks/shell "mkdir" "-p" "test-backup")
(spit "test-backup/file" "I was here") (spit "test-backup/file" "I was here")
@ -43,6 +43,12 @@
(bak/backup-file! file-config) (bak/backup-file! file-config)
(bak/backup-db! (merge db-config dry-run))) (bak/backup-db! (merge db-config dry-run)))
(defn list-snapshots!
[]
(rc/list-snapshots! file-config)
(rc/list-snapshots! (merge db-config dry-run)))
(defn restic-restore! (defn restic-restore!
[] []
(rs/restore-file! file-config) (rs/restore-file! file-config)
@ -52,4 +58,5 @@
(prepare!) (prepare!)
(restic-repo-init!) (restic-repo-init!)
(restic-backup!) (restic-backup!)
(list-snapshots!)
(restic-restore!) (restic-restore!)

View file

@ -2,7 +2,7 @@
(:require (:require
[orchestra.core :refer [defn-spec]] [orchestra.core :refer [defn-spec]]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[clojure.string :as st])) [dda.backup.infrastructure :as i]))
(def default {:dry-run false (def default {:dry-run false
:debug false}) :debug false})
@ -13,11 +13,29 @@
::debug ::debug
::execution-directory])) ::execution-directory]))
(s/def ::aws-access-key-id string?)
(s/def ::aws-secret-access-key string?)
(s/def ::aws-config
(s/keys :req-un [::aws-access-key-id
::aws-secret-access-key]))
(defn-spec env-or-file string? (defn-spec env-or-file string?
[name string?] [name string?]
(let [name-upper (st/upper-case name) (let [from-env (System/getenv name)
name-lower (st/lower-case name) name-from-file (System/getenv (str name "_FILE"))]
from-env (System/getenv name-upper)] (cond
(if (some? from-env) (some? from-env) from-env
from-env (some? name-from-file) (slurp name-from-file)
(slurp name-lower)))) :else (throw ( RuntimeException.
(str "Environment: [" name "," name-from-file "] was missing." ))))))
(defn-spec create-aws-credentials! nil?
[config ::aws-config]
(let [{:keys [aws-access-key-id aws-secret-access-key]} config]
(i/execute! [["mkdir" "-p" "/root/.aws"]] {})
(spit "/root/.aws/credentials"
(str "[default]\n"
"aws_access_key_id=" aws-access-key-id "\n"
"aws_secret_access_key=" aws-secret-access-key "\n"))
(i/execute! [["chmod" "0600" "/root/.aws/credentials"]] {})))

View file

@ -4,7 +4,7 @@
[dda.backup.core.domain :as core])) [dda.backup.core.domain :as core]))
(defn-spec execute! nil? (defn-spec execute! nil?
[commands ::core/command [commands ::core/commands
config ::core/execution] config ::core/execution]
(let [{:keys [dry-run debug]} config] (let [{:keys [dry-run debug]} config]
(doseq [c commands] (doseq [c commands]

View file

@ -21,9 +21,12 @@
(defn-spec create-pg-pass! nil? (defn-spec create-pg-pass! nil?
[config ::pg-config] [config ::pg-config]
(let [config-w-defaults (merge default config)] (let [config-w-defaults (merge default config)]
(spit "/root/.pgpass" (domain/pgpass config-w-defaults)))) (spit "/root/.pgpass" (domain/pgpass config-w-defaults))
(i/execute! [["chmod" "0600" "/root/.pgpass"]] config)))
(defn-spec drop-create-db! nil? (defn-spec drop-create-db! nil?
[config ::pg-config] [config ::pg-config]
(let [config-w-defaults (merge default config)] (let [config-w-defaults (merge default config)]
(i/execute! (domain/db-drop-create-command config-w-defaults) config-w-defaults))) (try (i/execute! (domain/db-drop-command config-w-defaults) config-w-defaults)
(catch Exception e (println (.getMessage e))))
(i/execute! (domain/db-create-command config-w-defaults) config-w-defaults)))

View file

@ -67,12 +67,18 @@
(defn-spec pgpass string? (defn-spec pgpass string?
[config ::pg-config] [config ::pg-config]
(let [{:keys [pg-host pg-db pg-user pg-password]} config] (let [{:keys [pg-host pg-port pg-db pg-user pg-password]} config]
(str pg-host ":" pg-db ":" pg-user ":" pg-password))) (str pg-host ":" pg-port ":" pg-db ":" pg-user ":" pg-password "\n"
pg-host ":" pg-port ":template1:" pg-user ":" pg-password "\n")))
(defn-spec db-drop-create-command ::cd/commands (defn-spec db-drop-command ::cd/commands
[config ::pg-config] [config ::pg-config]
(let [{:keys [pg-db]} config (let [{:keys [pg-db]} config
config-w-template (merge config {:pg-db "template1"})] config-w-template (merge config {:pg-db "template1"})]
[(psql-command config-w-template ["-c" (str "\"DROP DATABASE \\\"" pg-db "\\\";\"")]) [(psql-command config-w-template ["-c" (str "DROP DATABASE \"" pg-db "\";")])]))
(psql-command config-w-template ["-c" (str "\"CREATE DATABASE \\\"" pg-db "\\\";\"")])]))
(defn-spec db-create-command ::cd/commands
[config ::pg-config]
(let [{:keys [pg-db]} config
config-w-template (merge config {:pg-db "template1"})]
[(psql-command config-w-template ["-c" (str "CREATE DATABASE \"" pg-db "\";")])]))

View file

@ -42,4 +42,9 @@
(defn-spec forget! nil? (defn-spec forget! nil?
[restic-config ::restic-config] [restic-config ::restic-config]
(let [config-w-defaults (merge core/default restic-config)] (let [config-w-defaults (merge core/default restic-config)]
(i/execute! (domain/forget-command config-w-defaults) config-w-defaults))) (i/execute! (domain/forget-command config-w-defaults) config-w-defaults)))
(defn-spec list-snapshots! nil?
[restic-config ::restic-config]
(let [config-w-defaults (merge core/default restic-config)]
(i/execute! (domain/list-snapshot-command config-w-defaults) config-w-defaults)))

View file

@ -5,10 +5,11 @@
[dda.backup.postgresql.domain :as cut])) [dda.backup.postgresql.domain :as cut]))
(st/instrument `cut/pgpass) (st/instrument `cut/pgpass)
(st/instrument `cut/db-drop-create-command) (st/instrument `cut/db-drop-command)
(st/instrument `cut/db-create-command)
(deftest should-calculate-pgpass (deftest should-calculate-pgpass
(is (= "localhost:mydb:user:password" (is (= "localhost:5432:mydb:user:password\nlocalhost:5432:template1:user:password\n"
(cut/pgpass {:restic-repository "repo" (cut/pgpass {:restic-repository "repo"
:backup-path "dir-at-repo" :backup-path "dir-at-repo"
:pg-host "localhost" :pg-host "localhost"
@ -17,12 +18,21 @@
:pg-user "user" :pg-user "user"
:pg-password "password"})))) :pg-password "password"}))))
(deftest should-calculate-db-drop-create-command (deftest should-calculate-db-drop-command
(is (= [["psql" "-d" "template1" "-h" "localhost" "-p" "5432" "-U" "user" (is (= [["psql" "-d" "template1" "-h" "localhost" "-p" "5432" "-U" "user"
"--no-password" "-c" "\"DROP DATABASE \\\"mydb\\\";\""] "--no-password" "-c" "DROP DATABASE \"mydb\";"]]
["psql" "-d" "template1" "-h" "localhost" "-p" "5432" "-U" "user" (cut/db-drop-command {:restic-repository "repo"
"--no-password" "-c" "\"CREATE DATABASE \\\"mydb\\\";\""]] :backup-path "dir-at-repo"
(cut/db-drop-create-command {:restic-repository "repo" :pg-host "localhost"
:pg-port 5432
:pg-db "mydb"
:pg-user "user"
:pg-password "password"}))))
(deftest should-calculate-db-create-command
(is (= [["psql" "-d" "template1" "-h" "localhost" "-p" "5432" "-U" "user"
"--no-password" "-c" "CREATE DATABASE \"mydb\";"]]
(cut/db-create-command {:restic-repository "repo"
:backup-path "dir-at-repo" :backup-path "dir-at-repo"
:pg-host "localhost" :pg-host "localhost"
:pg-port 5432 :pg-port 5432