diff --git a/.gitignore b/.gitignore index dfbfb23..ed7cd31 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ public/js/ .eastwood +.envrc diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a52445c..510ff37 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -122,11 +122,3 @@ forgejo-backup-image-publish: stage: image script: - cd infrastructure/backup && pyb image publish - -# This is currently not needed -#forgejo-federated-image-publish: -# <<: *img -# <<: *tag_only -# stage: image -# script: -# - cd infrastructure/federated && pyb image publish \ No newline at end of file diff --git a/doc/Runbook_UpgradeFrom1.19.md b/doc/Runbook_UpgradeFrom1.19.md index c2b4106..1125200 100644 --- a/doc/Runbook_UpgradeFrom1.19.md +++ b/doc/Runbook_UpgradeFrom1.19.md @@ -7,7 +7,8 @@ * 1.21.1-0: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#1-21-1-0 * 7.0.0: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#7-0-0 * 8.0.0: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#8-0-0 - +* 9.0.0: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/release-notes-published/9.0.0.md +* ## Preparations 1. Stop Forgejo Prod: `k scale deployment forgejo --replicas=0` @@ -86,6 +87,20 @@ 1. Scale up Forgejo Deployment: `k scale -n forgejo deployment forgejo --replicas=1` 1. Check for errors: `k logs -n forgejo forgejo-...` +## Upgrade to 9.0.3 (no relevant breaking changes) + +1. Scale down Forgejo Deployment: `k scale -n forgejo deployment forgejo --replicas=0` +1. Set version to `9.0.3` with `k edit -n forgejo deployment forgejo` +1. Scale up Forgejo Deployment: `k scale -n forgejo deployment forgejo --replicas=1` +1. Check for errors: `k logs -n forgejo forgejo-...` + +## Upgrade to 10.0.3 (no relevant breaking changes) + +1. Scale down Forgejo Deployment: `k scale -n forgejo deployment forgejo --replicas=0` +1. Set version to `10.0.3` with `k edit -n forgejo deployment forgejo` +1. Scale up Forgejo Deployment: `k scale -n forgejo deployment forgejo --replicas=1` +1. Check for errors: `k logs -n forgejo forgejo-...` + ## Enable Federation 1. Scale down Forgejo Deployment: `k scale -n forgejo deployment forgejo --replicas=0` diff --git a/infrastructure/backup/image/Dockerfile b/infrastructure/backup/image/Dockerfile index 59a99c5..564b1ee 100644 --- a/infrastructure/backup/image/Dockerfile +++ b/infrastructure/backup/image/Dockerfile @@ -1,4 +1,4 @@ -FROM domaindrivenarchitecture/dda-backup:5.3.0 +FROM domaindrivenarchitecture/dda-backup:5.4.0 ADD resources /tmp RUN /tmp/install.bb diff --git a/infrastructure/backup/image/resources/backup.bb b/infrastructure/backup/image/resources/backup.bb index 6509399..f139424 100755 --- a/infrastructure/backup/image/resources/backup.bb +++ b/infrastructure/backup/image/resources/backup.bb @@ -5,6 +5,7 @@ '[dda.backup.config :as cfg] '[dda.backup.restic :as rc] '[dda.backup.postgresql :as pg] + '[dda.backup.monitoring :as mon] '[dda.backup.backup :as bak]) (def config (cfg/read-config "/usr/local/bin/config.edn")) @@ -24,6 +25,13 @@ (bak/backup-file! (:file-config config)) (bak/backup-db! (:db-config config))) -(prepare!) -(restic-repo-init!) -(restic-backup!) + +(try + (restic-repo-init!) + (mon/backup-start-metrics! (:db-config config)) + (prepare!) + (restic-repo-init!) + (restic-backup!) + (mon/backup-success-metrics! (:db-config config)) + (catch Exception e + (mon/backup-fail-metrics! (:db-config config)))) diff --git a/infrastructure/backup/image/resources/config.edn b/infrastructure/backup/image/resources/config.edn index 26d9fa1..3ed839a 100644 --- a/infrastructure/backup/image/resources/config.edn +++ b/infrastructure/backup/image/resources/config.edn @@ -1,12 +1,14 @@ -{:restic-repo {:password-file #env-or-file "RESTIC_PASSWORD_FILE" - :restic-repository #env-or-file "RESTIC_REPOSITORY"} +{:monitoring {:namespace "forgejo"} + + :restic-repo #merge [#ref [:monitoring] + {:password-file #env-or-file "RESTIC_PASSWORD_FILE" + :restic-repository #env-or-file "RESTIC_REPOSITORY"}] :file-config #merge [#ref [:restic-repo] {:backup-path "files" :execution-directory "/var/backups/" :files ["gitea/" "git/repositories/"]}] - :db-config #merge [#ref [:restic-repo] {:backup-path "pg-database" :pg-host #env-or-file "POSTGRES_SERVICE" diff --git a/infrastructure/backup/image/resources/install.bb b/infrastructure/backup/image/resources/install.bb index 3f96494..301e714 100755 --- a/infrastructure/backup/image/resources/install.bb +++ b/infrastructure/backup/image/resources/install.bb @@ -14,4 +14,5 @@ (in/install! "list-snapshots.bb") (in/install! "change-password.bb") (in/install! "wait.bb") +(in/install! "monitoring.bb") (ub/cleanup-container!) \ No newline at end of file diff --git a/infrastructure/backup/image/resources/monitoring.bb b/infrastructure/backup/image/resources/monitoring.bb new file mode 100644 index 0000000..b963e93 --- /dev/null +++ b/infrastructure/backup/image/resources/monitoring.bb @@ -0,0 +1,11 @@ +#!/usr/bin/env bb + +(require + '[dda.backup.monitoring :as mon]) + +(def config {:metrics {:kube_job_status_active 0 + :kube_job_status_failed 1 + :kube_job_status_succeeded 0 + :kube_job_status_start_time (/ (System/currentTimeMillis) 1000)}}) + +(mon/send-metrics! config) \ No newline at end of file diff --git a/infrastructure/federated/build.py b/infrastructure/federated/build.py deleted file mode 100644 index 4029b04..0000000 --- a/infrastructure/federated/build.py +++ /dev/null @@ -1,55 +0,0 @@ -from os import environ -from datetime import datetime -from pybuilder.core import task, init -from ddadevops import * - -name = 'c4k-forgejo' -MODULE = 'federated' -PROJECT_ROOT_PATH = '../..' -version = "4.1.3-dev" - -@init -def initialize(project): - image_tag = version - if "dev" in image_tag: - image_tag += datetime.now().strftime("%Y-%m-%d-%H-%M-%S") - - input = { - "name": name, - "module": MODULE, - "stage": "notused", - "project_root_path": PROJECT_ROOT_PATH, - "build_types": ["IMAGE"], - "mixin_types": [], - "image_naming": "NAME_AND_MODULE", - "image_tag": f"{image_tag}", - } - - project.build_depends_on("ddadevops>=4.7.0") - - build = DevopsImageBuild(project, input) - build.initialize_build_dir() - - -@task -def image(project): - build = get_devops_build(project) - build.image() - -@task -def drun(project): - build = get_devops_build(project) - build.drun() - - -@task -def test(project): - build = get_devops_build(project) - build.test() - - -@task -def publish(project): - build = get_devops_build(project) - build.dockerhub_login() - build.dockerhub_publish() diff --git a/infrastructure/federated/image/Dockerfile b/infrastructure/federated/image/Dockerfile deleted file mode 100644 index d86e4a8..0000000 --- a/infrastructure/federated/image/Dockerfile +++ /dev/null @@ -1,78 +0,0 @@ -#Build stage -FROM docker.io/library/golang:1.21-alpine3.19 as build-env - -ARG GOPROXY -ENV GOPROXY ${GOPROXY:-direct} - -#ARG GITEA_VERSION -ARG TAGS="sqlite sqlite_unlock_notify" -ENV TAGS "bindata timetzdata $TAGS" -ARG CGO_EXTRA_CFLAGS - -ENV FORGEJO_GIT_URL "https://codeberg.org/meissa/forgejo.git" -ENV FORGEJO_BRANCH "forgejo-federated-star" - -#Build deps -RUN apk -U upgrade -RUN apk cache clean -RUN apk --no-cache add build-base git nodejs npm - -#Setup repo -RUN git clone --single-branch --branch ${FORGEJO_BRANCH} ${FORGEJO_GIT_URL} ${GOPATH}/src/code.gitea.io/gitea - -WORKDIR ${GOPATH}/src/code.gitea.io/gitea - -#Checkout version if set -RUN make clean-all build - -# Begin env-to-ini build -RUN go build contrib/environment-to-ini/environment-to-ini.go - -# Run stage -FROM docker.io/library/alpine:3.18 -LABEL maintainer="contact@forgejo.org" - -EXPOSE 22 3000 - -RUN apk -U upgrade -RUN apk cache clean -RUN apk --no-cache add \ - bash \ - ca-certificates \ - curl \ - gettext \ - git \ - linux-pam \ - openssh \ - s6 \ - sqlite \ - su-exec \ - gnupg - -RUN addgroup \ - -S -g 1000 \ - git && \ - adduser \ - -S -H -D \ - -h /data/git \ - -s /bin/bash \ - -u 1000 \ - -G git \ - git && \ - echo "git:*" | chpasswd -e - -ENV USER git -ENV GITEA_CUSTOM /data/gitea - -VOLUME ["/data"] - -ENTRYPOINT ["/usr/bin/entrypoint"] -CMD ["/bin/s6-svscan", "/etc/s6"] - -COPY --from=build-env /go/src/code.gitea.io/gitea/docker/root / -COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea -COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini -COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh -RUN chmod 755 /usr/bin/entrypoint /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini -RUN chmod 755 /etc/s6/gitea/* /etc/s6/openssh/* /etc/s6/.s6-svscan/* -RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh diff --git a/project.clj b/project.clj index f0f3aee..4c5f950 100644 --- a/project.clj +++ b/project.clj @@ -4,8 +4,8 @@ :license {:name "Apache License, Version 2.0" :url "https://www.apache.org/licenses/LICENSE-2.0.html"} :dependencies [[org.clojure/clojure "1.12.0" :scope "provided"] - [org.clojure/tools.reader "1.5.0"] - [org.domaindrivenarchitecture/c4k-common-clj "9.0.1"] + [org.clojure/tools.reader "1.5.2"] + [org.domaindrivenarchitecture/c4k-common-clj "10.0.0"] [hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]] :target-path "target/%s/" :source-paths ["src/main/cljc" @@ -24,9 +24,9 @@ :main dda.c4k-forgejo.uberjar :uberjar-name "c4k-forgejo-standalone.jar" :dependencies [[org.clojure/tools.cli "1.1.230"] - [ch.qos.logback/logback-classic "1.5.16" + [ch.qos.logback/logback-classic "1.5.18" :exclusions [com.sun.mail/javax.mail]] - [org.slf4j/jcl-over-slf4j "2.0.16"] + [org.slf4j/jcl-over-slf4j "2.0.17"] [com.github.clj-easy/graal-build-time "1.0.5"]]}} :release-tasks [["test"] ["vcs" "assert-committed"] diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 4e238fd..a241a34 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -4,7 +4,7 @@ "src/test/cljc" "src/test/cljs" "src/test/resources"] - :dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "9.0.1"] + :dependencies [[org.domaindrivenarchitecture/c4k-common-cljs "10.0.0"] [hickory "0.7.1"]] :builds {:frontend {:target :browser :modules {:main {:init-fn dda.c4k-forgejo.browser/init}} diff --git a/src/main/cljc/dda/c4k_forgejo/core.cljc b/src/main/cljc/dda/c4k_forgejo/core.cljc index a1688a6..0ecdcec 100644 --- a/src/main/cljc/dda/c4k_forgejo/core.cljc +++ b/src/main/cljc/dda/c4k_forgejo/core.cljc @@ -14,11 +14,11 @@ (def config-defaults {:namespace "forgejo" :issuer "staging" - :deploy-federated "false" :federation-enabled "false" + :forgejo-image "codeberg.org/forgejo/forgejo:10.0.3" :db-name "forgejo" :pv-storage-size-gb 5 - :pvc-storage-class-name "" + :pvc-storage-class-name :local-path :postgres-image "postgres:14" :postgres-size :2gb :max-rate 10, @@ -30,11 +30,10 @@ ::forgejo/mailer-port ::forgejo/service-noreply-address] :opt-un [::forgejo/issuer - ::forgejo/deploy-federated ::forgejo/federation-enabled ::forgejo/default-app-name ::forgejo/service-domain-whitelist - ::forgejo/forgejo-image-version-overwrite + ::forgejo/forgejo-image ::backup/restic-repository ::mon/mon-cfg])) @@ -56,7 +55,8 @@ (ns/generate resolved-config) [(postgres/generate-configmap resolved-config) (when (contains? resolved-config :postgres-data-volume-path) - (postgres/generate-persistent-volume (select-keys resolved-config [:postgres-data-volume-path :pv-storage-size-gb]))) + (postgres/generate-persistent-volume + (select-keys resolved-config [:postgres-data-volume-path :pv-storage-size-gb]))) (postgres/generate-pvc (merge resolved-config {:pvc-storage-class-name storage-class})) (postgres/generate-deployment resolved-config) (postgres/generate-service resolved-config) diff --git a/src/main/cljc/dda/c4k_forgejo/forgejo.cljc b/src/main/cljc/dda/c4k_forgejo/forgejo.cljc index 971ae9e..b06fb6a 100644 --- a/src/main/cljc/dda/c4k_forgejo/forgejo.cljc +++ b/src/main/cljc/dda/c4k_forgejo/forgejo.cljc @@ -32,14 +32,13 @@ (s/def ::default-app-name string?) (s/def ::fqdn pred/fqdn-string?) -(s/def ::deploy-federated boolean-string?) (s/def ::federation-enabled boolean-string?) (s/def ::mailer-from pred/bash-env-string?) (s/def ::mailer-host pred/bash-env-string?) (s/def ::mailer-port pred/bash-env-string?) (s/def ::service-domain-whitelist domain-list?) (s/def ::service-noreply-address string?) -(s/def ::forgejo-image-version-overwrite string?) +(s/def ::forgejo-image string?) (s/def ::mailer-user pred/bash-env-string?) (s/def ::mailer-pw pred/bash-env-string?) (s/def ::issuer pred/letsencrypt-issuer?) @@ -48,6 +47,7 @@ (s/def ::max-concurrent-requests int?) (s/def ::config (s/keys :req-un [::fqdn + ::forgejo-image ::mailer-from ::mailer-host ::mailer-port @@ -56,30 +56,14 @@ ::max-rate ::max-concurrent-requests] :opt-un [::issuer - ::deploy-federated ::federation-enabled ::default-app-name ::service-domain-whitelist - ::forgejo-image-version-overwrite])) + ])) -(s/def ::auth (s/keys :req-un [::postgres/postgres-db-user ::postgres/postgres-db-password ::mailer-user ::mailer-pw])) - -(defn data-storage-by-volume-size - [total] - total) -;;TODO: remove unneccessaries, fedaration is merged -(def federated-image-name "domaindrivenarchitecture/c4k-forgejo-federated") -(def federated-image-version "latest") -(def non-federated-image-name "codeberg.org/forgejo/forgejo") -(def non-federated-image-version "8.0.3") - -(defn-spec generate-image-str string? - [config ::config] - (let [{:keys [deploy-federated forgejo-image-version-overwrite]} config - deploy-federated-bool (boolean-from-string deploy-federated)] - (if deploy-federated-bool - (str federated-image-name ":" (or forgejo-image-version-overwrite federated-image-version)) - (str non-federated-image-name ":" (or forgejo-image-version-overwrite non-federated-image-version))))) +(s/def ::auth (s/keys :req-un [::postgres/postgres-db-user + ::postgres/postgres-db-password + ::mailer-user ::mailer-pw])) #?(:cljs (defmethod yaml/load-resource :forgejo [resource-name] @@ -140,17 +124,17 @@ (defn-spec generate-data-volume pred/map-or-seq? [config ::config] - (let [{:keys [volume-total-storage-size]} config - data-storage-size (data-storage-by-volume-size volume-total-storage-size)] + (let [{:keys [volume-total-storage-size]} config] (-> (yaml/load-as-edn "forgejo/datavolume.yaml") - (cm/replace-all-matching "DATASTORAGESIZE" (str (str data-storage-size) "Gi"))))) + (cm/replace-all-matching "DATASTORAGESIZE" (str (str volume-total-storage-size) "Gi"))))) (defn-spec generate-deployment pred/map-or-seq? [config ::config] - (-> - (yaml/load-as-edn "forgejo/deployment.yaml") - (cm/replace-all-matching "IMAGE_NAME" (generate-image-str config)))) + (let [{:keys [forgejo-image]} config] + (-> + (yaml/load-as-edn "forgejo/deployment.yaml") + (cm/replace-all-matching "IMAGE_NAME" forgejo-image)))) (defn generate-service [] diff --git a/src/test/cljc/dda/c4k_forgejo/core_test.cljc b/src/test/cljc/dda/c4k_forgejo/core_test.cljc index df9720e..5beba93 100644 --- a/src/test/cljc/dda/c4k_forgejo/core_test.cljc +++ b/src/test/cljc/dda/c4k_forgejo/core_test.cljc @@ -20,7 +20,7 @@ (is (s/valid? cut/auth? (yaml/load-as-edn "forgejo-test/valid-auth.yaml")))) (deftest test-whole-generation - (is (= 32 + (is (= 35 (count (cut/config-objects (yaml/load-as-edn "forgejo-test/valid-config.yaml"))))) diff --git a/src/test/cljc/dda/c4k_forgejo/forgejo_test.cljc b/src/test/cljc/dda/c4k_forgejo/forgejo_test.cljc index f7b388d..965c26e 100644 --- a/src/test/cljc/dda/c4k_forgejo/forgejo_test.cljc +++ b/src/test/cljc/dda/c4k_forgejo/forgejo_test.cljc @@ -12,40 +12,6 @@ (st/instrument `cut/generate-ingress) (st/instrument `cut/generate-secrets) -(deftest should-generate-image-str - (testing "non-federated-image" - (is (= "codeberg.org/forgejo/forgejo:8.0.3" - (cut/generate-image-str {:fqdn "test.de" - :mailer-from "" - :mailer-host "m.t.de" - :mailer-port "123" - :service-noreply-address "" - :deploy-federated "false"}))) - (is (= "codeberg.org/forgejo/forgejo:1.19.3-0" - (cut/generate-image-str {:fqdn "test.de" - :mailer-from "" - :mailer-host "m.t.de" - :mailer-port "123" - :service-noreply-address "" - :deploy-federated "false" - :forgejo-image-version-overwrite "1.19.3-0"})))) - (testing "federated-image" - (is (= "domaindrivenarchitecture/c4k-forgejo-federated:latest" - (cut/generate-image-str {:fqdn "test.de" - :mailer-from "" - :mailer-host "m.t.de" - :mailer-port "123" - :service-noreply-address "" - :deploy-federated "true"}))) - (is (= "domaindrivenarchitecture/c4k-forgejo-federated:3.2.0" - (cut/generate-image-str {:fqdn "test.de" - :mailer-from "" - :mailer-host "m.t.de" - :mailer-port "123" - :service-noreply-address "" - :deploy-federated "true" - :forgejo-image-version-overwrite "3.2.0"}))))) - (deftest should-generate-appini-env (is (= {:APP_NAME-c1 "", :APP_NAME-c2 "test forgejo", @@ -74,7 +40,8 @@ :mailer-host "m.t.de" :mailer-port "123" :service-domain-whitelist "adb.de" - :service-noreply-address ""}) + :service-noreply-address "" + :forgejo-image "codeberg.org/forgejo/forgejo:8.0.3"}) (cut/generate-appini-env {:default-app-name "test forgejo" :federation-enabled "true" :fqdn "test.com" @@ -82,7 +49,8 @@ :mailer-host "mail.test.com" :mailer-port "456" :service-domain-whitelist "test.com,test.net" - :service-noreply-address "noreply@test.com"}))))) + :service-noreply-address "noreply@test.com" + :forgejo-image "codeberg.org/forgejo/forgejo:8.0.3"}))))) (deftest should-generate-deployment (testing "non-federated" @@ -114,37 +82,8 @@ :service-noreply-address "" :volume-total-storage-size 10 :max-rate 10 - :max-concurrent-requests 1})))) - (testing "federated-deployment" - (is (= {:apiVersion "apps/v1", - :kind "Deployment", - :metadata {:name "forgejo", :namespace "forgejo", :labels {:app "forgejo"}}, - :spec - {:replicas 1, - :selector {:matchLabels {:app "forgejo"}}, - :template - {:metadata {:name "forgejo", :labels {:app "forgejo"}}, - :spec - {:containers - [{:name "forgejo", - :image "domaindrivenarchitecture/c4k-forgejo-federated:latest", - :imagePullPolicy "IfNotPresent", - :envFrom [{:configMapRef {:name "forgejo-env"}} {:secretRef {:name "forgejo-secrets"}}], - :volumeMounts [{:name "forgejo-data-volume", :mountPath "/data"}], - :ports [{:containerPort 22, :name "git-ssh"} {:containerPort 3000, :name "forgejo"}]}], - :volumes [{:name "forgejo-data-volume", :persistentVolumeClaim {:claimName "forgejo-data-pvc"}}]}}}} - (cut/generate-deployment - {:default-app-name "" - :deploy-federated "true" - :fqdn "test.de" - :mailer-from "" - :mailer-host "m.t.de" - :mailer-port "123" - :service-domain-whitelist "adb.de" - :service-noreply-address "" - :volume-total-storage-size 10 - :max-rate 10 - :max-concurrent-requests 1}))))) + :max-concurrent-requests 1 + :forgejo-image "codeberg.org/forgejo/forgejo:8.0.3"}))))) (deftest should-generate-secret (is (= {:FORGEJO__database__USER-c1 "",