diff options
Diffstat
| -rw-r--r-- | .dockerignore | 15 | +0 −15 |
| -rw-r--r-- | .github/workflows/build.yml | 139 | +8 −131 |
| -rw-r--r-- | .gitignore | 1 | +0 −1 |
| -rw-r--r-- | README.md | 24 | +14 −10 |
| -rw-r--r-- | REUSE.toml | 2 | +0 −2 |
| -rw-r--r-- | Taskfile.yml | 96 | +94 −2 |
| -rw-r--r-- | charts/mirum/Chart.yaml | 10 | +0 −10 |
| -rw-r--r-- | charts/mirum/templates/_helpers.tpl | 40 | +0 −40 |
| -rw-r--r-- | charts/mirum/templates/server-deployment.yaml | 142 | +0 −142 |
| -rw-r--r-- | charts/mirum/templates/server-httproute.yaml | 26 | +0 −26 |
| -rw-r--r-- | charts/mirum/templates/server-service.yaml | 23 | +0 −23 |
| -rw-r--r-- | charts/mirum/templates/server-tcproute.yaml | 22 | +0 −22 |
| -rw-r--r-- | charts/mirum/templates/worker-deployment.yaml | 87 | +0 −87 |
| -rw-r--r-- | charts/mirum/values.yaml | 75 | +0 −75 |
| -rw-r--r-- | cmd/mirum-server/Dockerfile | 20 | +0 −20 |
| -rw-r--r-- | cmd/mirum-worker/Dockerfile | 26 | +0 −26 |
| -rw-r--r-- | mise.lock | 14 | +14 −0 |
| -rw-r--r-- | mise.toml | 6 | +2 −4 |
| -rw-r--r-- | nfpm.yaml | 6 | +3 −3 |
| -rw-r--r-- | packaging/apt-ftparchive.conf | 29 | +29 −0 |
20 files changed, 164 insertions, 639 deletions
diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 --- a/.dockerignore +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -.git -.github -.task -build -cmd/mirum-agent/.zig-cache -cmd/mirum-agent/zig-out -cmd/mirum-agent/zig-pkg -cmd/mirum-server/apipb -cmd/mirum-server/static -cmd/mirum-server/web/gen -cmd/mirum-server/web/node_modules -internal/protocol/wirepb diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7e1bd0e..99da313 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,11 +18,6 @@ jobs: build: name: Build and publish Nightly runs-on: ubuntu-latest - concurrency: - group: >- - package-publish-mirum-${{ github.ref == 'refs/heads/main' && 'nightly' - || startsWith(github.ref, 'refs/tags/v') && 'stable' || github.ref }} - cancel-in-progress: false permissions: contents: write steps: @@ -45,7 +40,6 @@ jobs: GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} APK_PRIVATE_KEY: ${{ secrets.APK_PRIVATE_KEY }} - PACKAGE_KEY_VERSION: ${{ vars.PACKAGE_KEY_VERSION }} - name: Lint run: task lint @@ -53,17 +47,6 @@ jobs: - name: Tests run: task test - - name: Upload container binaries - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: container-binaries - path: | - build/mirum-server-linux-amd64 - build/mirum-server-linux-arm64 - build/mirum-worker-linux-amd64 - build/mirum-worker-linux-arm64 - if-no-files-found: error - - name: Publish if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | @@ -71,123 +54,17 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" . build/dist/build.env task publish:release CHANNEL=$CHANNEL VERSION=$VERSION - mise run publish -- \ - --service mirum \ - --channel "$CHANNEL" \ - --input build/dist \ - deb rpm apk + task publish:repos \ + CHANNEL=$CHANNEL \ + S3_BUCKET=${{ vars.S3_BUCKET }} \ + S3_PUBLIC_URL=${{ vars.S3_PUBLIC_URL }} \ + S3_PROVIDER="${{ vars.S3_PROVIDER || 'Other' }}" \ + S3_REGION=${{ vars.S3_REGION }} \ + S3_ENDPOINT=${{ vars.S3_ENDPOINT }} \ + GPG_KEY_ID=${{ vars.GPG_KEY_ID }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - GPG_KEY_ID: ${{ vars.GPG_KEY_ID }} - APK_PRIVATE_KEY: ${{ secrets.APK_PRIVATE_KEY }} - PACKAGE_KEY_VERSION: ${{ vars.PACKAGE_KEY_VERSION }} - S3_BUCKET: ${{ vars.S3_BUCKET }} - S3_ENDPOINT: ${{ vars.S3_ENDPOINT }} - S3_PUBLIC_URL: ${{ vars.S3_PUBLIC_URL }} S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - - oci: - name: OCI artifacts - needs: [build] - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - - uses: jdx/mise-action@5228313ee0372e111a38da051671ca30fc5a96db # v3 - with: - version: 2026.7.5 - experimental: true - install: false - - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - with: - name: container-binaries - path: .container - - - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - - - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - - - name: Determine artifact version - id: artifact - shell: bash - run: | - base_version=$(cat VERSION) - if [[ "$GITHUB_REF" == refs/heads/main ]]; then - version="$base_version-nightly.$(git log -1 --format=%ct)" - elif [[ "$GITHUB_REF" == refs/tags/v* ]]; then - version="${GITHUB_REF_NAME#v}" - if [[ "$version" != "$base_version" ]]; then - echo "Tag version $version does not match VERSION $base_version" >&2 - exit 1 - fi - else - version="$base_version-pr.$GITHUB_RUN_NUMBER" - fi - echo "version=$version" >> "$GITHUB_OUTPUT" - - - name: Log in to GHCR - if: github.event_name != 'pull_request' - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Log Helm in to GHCR - if: github.event_name != 'pull_request' - env: - GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - printf '%s' "$GHCR_TOKEN" | mise x helm@4.1.1 -- \ - helm registry login ghcr.io --username "$GITHUB_ACTOR" --password-stdin - - - name: Build and publish OCI artifacts - shell: bash - run: | - version="${{ steps.artifact.outputs.version }}" - image_output=() - chart_output=() - - if [[ "${{ github.event_name }}" != pull_request ]]; then - image_output+=(--push) - chart_output+=(--push "oci://ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/charts") - fi - - for service in server worker; do - image="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/mirum-$service" - tags=( - --tag "$image:sha-$GITHUB_SHA" - --tag "$image:$version" - ) - labels=( - --label "org.opencontainers.image.revision=$GITHUB_SHA" - --label "org.opencontainers.image.source=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" - --label "org.opencontainers.image.version=$version" - ) - - if [[ "$GITHUB_REF" == refs/heads/main ]]; then - tags+=(--tag "$image:nightly") - elif [[ "$GITHUB_REF" == refs/tags/v* ]]; then - tags+=(--tag "$image:latest") - fi - - mise run container -- \ - --context . \ - --file "cmd/mirum-$service/Dockerfile" \ - --platform linux/amd64,linux/arm64 \ - --cache-scope "mirum-$service" \ - "${tags[@]}" "${labels[@]}" "${image_output[@]}" - done - - mise run chart -- \ - --chart charts/mirum \ - --version "$version" \ - --app-version "$version" \ - "${chart_output[@]}" diff --git a/.gitignore b/.gitignore index 437dc77..149195c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ /dev /build -/.container /.task mise.local.toml mise.*.local.toml diff --git a/README.md b/README.md index a9f4640..8cb272c 100644 --- a/README.md +++ b/README.md @@ -139,8 +139,8 @@ Please note that the project is in its infancy and is **not** intended for produ ```bash sudo apt install curl gnupg -curl -fsSL https://pkg.dimidiumlabs.io/packages.gpg | sudo gpg --dearmor -o /usr/share/keyrings/dimidiumlabs.gpg -echo "deb [signed-by=/usr/share/keyrings/dimidiumlabs.gpg] https://pkg.dimidiumlabs.io/mirum/apt/ nightly main" | sudo tee /etc/apt/sources.list.d/mirum.list +curl -fsSL https://dl.mirum.dev/public.gpg | sudo gpg --dearmor -o /usr/share/keyrings/mirum.gpg +echo "deb [signed-by=/usr/share/keyrings/mirum.gpg] https://dl.mirum.dev/apt/ nightly main" | sudo tee /etc/apt/sources.list.d/mirum.list sudo apt update && sudo apt install mirum # Start the server @@ -154,10 +154,10 @@ sudo systemctl enable --now mirum-worker@default ```bash # DNF5 (Fedora 41+, RHEL 10+) -sudo dnf config-manager addrepo --from-repofile=https://pkg.dimidiumlabs.io/mirum/rpm/nightly/mirum-nightly.repo +sudo dnf config-manager addrepo --from-repofile=https://dl.mirum.dev/rpm/nightly/mirum-nightly.repo # DNF4 (Fedora 40 and older, RHEL 8/9) -sudo curl -o /etc/yum.repos.d/mirum-nightly.repo https://pkg.dimidiumlabs.io/mirum/rpm/nightly/mirum-nightly.repo +sudo curl -o /etc/yum.repos.d/mirum-nightly.repo https://dl.mirum.dev/rpm/nightly/mirum-nightly.repo sudo dnf install mirum @@ -171,8 +171,8 @@ sudo systemctl enable --now mirum-worker@default **openSUSE:** ```bash -sudo rpm --import https://pkg.dimidiumlabs.io/packages.gpg -sudo zypper addrepo https://pkg.dimidiumlabs.io/mirum/rpm/nightly/ mirum-nightly +sudo rpm --import https://dl.mirum.dev/public.gpg +sudo zypper addrepo https://dl.mirum.dev/rpm/nightly/ mirum-nightly sudo zypper refresh sudo zypper install mirum @@ -185,11 +185,15 @@ sudo systemctl enable --now mirum-worker@default **Alpine:** +No repository yet — grab the signing key and the signed `.apk` from the nightly +release: + ```sh -sudo wget -O /etc/apk/keys/packages.0001.rsa.pub https://pkg.dimidiumlabs.io/keys/packages.0001.rsa.pub -echo "https://pkg.dimidiumlabs.io/mirum/apk/nightly" | sudo tee -a /etc/apk/repositories -sudo apk update -sudo apk add mirum +sudo wget -O /etc/apk/keys/mirum.rsa.pub https://dl.mirum.dev/mirum.rsa.pub + +# Download the .apk for your arch from +# https://github.com/dimidiumlabs/mirum/releases/tag/nightly +sudo apk add ./mirum_<version>_<arch>.apk # Start the server sudo rc-update add mirum-server default diff --git a/REUSE.toml b/REUSE.toml index 708bc13..850dd72 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -14,7 +14,6 @@ path = [ "mise.lock", "packaging/dl/*", "packaging/logo.svg", - "charts/mirum/templates/*", "buf.*", ] SPDX-FileCopyrightText = "2026 Nikolay Govorov" @@ -30,7 +29,6 @@ SPDX-License-Identifier = "CC-BY-3.0" [[annotations]] path = [ "README.md", - "charts/mirum/README.md", "docs/**.md", ] SPDX-FileCopyrightText = "2026 Nikolay Govorov" diff --git a/Taskfile.yml b/Taskfile.yml index 8e9b060..f803a40 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -250,12 +250,104 @@ tasks: --version "{{.VERSION}}" \ --arch "$arch" \ --output "{{.DIST_DIR}}" \ + --apk-public-key mirum.rsa.pub \ $formats rm -rf {{.BUILD_DIR}}/tmp done printf 'VERSION={{.VERSION}}\nCHANNEL={{.CHANNEL}}\n' > {{.DIST_DIR}}/build.env + publish:repos: + desc: Publish packages to APT and RPM repositories on S3 + requires: + vars: + [ + CHANNEL, + S3_BUCKET, + S3_PUBLIC_URL, + S3_PROVIDER, + S3_REGION, + S3_ENDPOINT, + GPG_KEY_ID, + ] + cmds: + - | + set -e + export GNUPGHOME=$(mktemp -d) + RCLONE_CONF=$(mktemp) + chmod 700 "$GNUPGHOME" + cleanup() { rm -rf "$GNUPGHOME" "$RCLONE_CONF"; } + trap cleanup EXIT + + cat > "$RCLONE_CONF" << EOF + [s3] + type = s3 + provider = {{.S3_PROVIDER}} + access_key_id = ${S3_ACCESS_KEY_ID} + secret_access_key = ${S3_SECRET_ACCESS_KEY} + region = {{.S3_REGION}} + endpoint = {{.S3_ENDPOINT}} + EOF + export RCLONE_CONFIG="$RCLONE_CONF" + + printf '%s' "$GPG_PRIVATE_KEY" | gpg --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --import + echo "allow-loopback-pinentry" >> "$GNUPGHOME/gpg-agent.conf" + gpgconf --kill gpg-agent + + # Upload static files + gpg --export --armor "{{.GPG_KEY_ID}}" > "$GNUPGHOME/public.gpg" + rclone copyto "$GNUPGHOME/public.gpg" "s3:{{.S3_BUCKET}}/public.gpg" + rclone copy packaging/dl/ "s3:{{.S3_BUCKET}}/" + + if [ -f "{{.DIST_DIR}}/mirum.rsa.pub" ]; then + rclone copyto "{{.DIST_DIR}}/mirum.rsa.pub" "s3:{{.S3_BUCKET}}/mirum.rsa.pub" + fi + + # APT repository + CHANNEL={{.CHANNEL}} + mkdir -p /tmp/apt-cache apt-repo + rclone copy "s3:{{.S3_BUCKET}}/apt/" apt-repo/ + + for ch in stable nightly; do + mkdir -p apt-repo/pool/$ch + for arch in {{.LINUX_PKG_TARGETS}}; do + mkdir -p apt-repo/dists/$ch/main/binary-$arch + done + done + cp {{.DIST_DIR}}/*.deb apt-repo/pool/$CHANNEL/ + + cd apt-repo + apt-ftparchive generate "$(pwd)/../packaging/apt-ftparchive.conf" + apt-ftparchive \ + -o APT::FTPArchive::Release::Codename=$CHANNEL \ + -o APT::FTPArchive::Release::Components=main \ + -o APT::FTPArchive::Release::Architectures="{{.LINUX_PKG_TARGETS}}" \ + release dists/$CHANNEL/ > dists/$CHANNEL/Release + gpg --default-key="{{.GPG_KEY_ID}}" --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" -abs -o dists/$CHANNEL/Release.gpg dists/$CHANNEL/Release + gpg --default-key="{{.GPG_KEY_ID}}" --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --clearsign -o dists/$CHANNEL/InRelease dists/$CHANNEL/Release + cd .. + rclone copy apt-repo/ "s3:{{.S3_BUCKET}}/apt/" --progress + + # RPM repository + mkdir -p rpm-repo + rclone copy "s3:{{.S3_BUCKET}}/rpm/$CHANNEL/" rpm-repo/ + + cp {{.DIST_DIR}}/*.rpm rpm-repo/ + + createrepo_c --update rpm-repo/ + gpg --default-key="{{.GPG_KEY_ID}}" --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" --detach-sign --armor rpm-repo/repodata/repomd.xml + + cat > rpm-repo/mirum-${CHANNEL}.repo << REPOEOF + [mirum-${CHANNEL}] + name=Mirum ${CHANNEL} + gpgkey={{.S3_PUBLIC_URL}}/public.gpg + baseurl={{.S3_PUBLIC_URL}}/rpm/${CHANNEL}/ + enabled=1 + gpgcheck=1 + REPOEOF + + rclone copy rpm-repo/ "s3:{{.S3_BUCKET}}/rpm/$CHANNEL/" --progress + publish:release: desc: Create or update a GitHub Release requires: @@ -275,11 +367,11 @@ tasks: done fi - gh release create "$TAG" {{.DIST_DIR}}/*.deb {{.DIST_DIR}}/*.rpm {{.DIST_DIR}}/*.apk {{.DIST_DIR}}/*.tar.gz {{.DIST_DIR}}/*.zip {{.DIST_DIR}}/SHA256SUMS \ + gh release create "$TAG" {{.DIST_DIR}}/*.deb {{.DIST_DIR}}/*.rpm {{.DIST_DIR}}/*.apk {{.DIST_DIR}}/*.rsa.pub {{.DIST_DIR}}/*.tar.gz {{.DIST_DIR}}/*.zip {{.DIST_DIR}}/SHA256SUMS \ --title "$NAME" \ $( [ "{{.CHANNEL}}" = "nightly" ] && echo "--prerelease" ) \ --notes "**Version**: {{.VERSION}}" \ - || gh release upload "$TAG" {{.DIST_DIR}}/*.deb {{.DIST_DIR}}/*.rpm {{.DIST_DIR}}/*.apk {{.DIST_DIR}}/*.tar.gz {{.DIST_DIR}}/*.zip {{.DIST_DIR}}/SHA256SUMS --clobber + || gh release upload "$TAG" {{.DIST_DIR}}/*.deb {{.DIST_DIR}}/*.rpm {{.DIST_DIR}}/*.apk {{.DIST_DIR}}/*.rsa.pub {{.DIST_DIR}}/*.tar.gz {{.DIST_DIR}}/*.zip {{.DIST_DIR}}/SHA256SUMS --clobber # Local dev env devenv:config: diff --git a/charts/mirum/Chart.yaml b/charts/mirum/Chart.yaml deleted file mode 100644 --- a/charts/mirum/Chart.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -apiVersion: v2 -type: application -version: 0.1.0 - -name: mirum -home: https://github.com/dimidiumlabs/mirum -description: Mirum CI server and workers diff --git a/charts/mirum/templates/_helpers.tpl b/charts/mirum/templates/_helpers.tpl deleted file mode 100644 --- a/charts/mirum/templates/_helpers.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{{/* SPDX-License-Identifier: AGPL-3.0-or-later */}} -{{/* vim: set filetype=helm: */}} -{{- define "mirum.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{- define "mirum.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name (include "mirum.name" .) | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} - -{{- define "mirum.labels" -}} -helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }} -app.kubernetes.io/name: {{ include "mirum.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end -}} - -{{- define "mirum.componentLabels" -}} -{{ include "mirum.labels" .root }} -app.kubernetes.io/component: {{ .component }} -{{- end -}} - -{{- define "mirum.selectorLabels" -}} -app.kubernetes.io/name: {{ include "mirum.name" .root }} -app.kubernetes.io/instance: {{ .root.Release.Name }} -app.kubernetes.io/component: {{ .component }} -{{- end -}} - -{{- define "mirum.image" -}} -{{- if .image.digest -}} -{{- printf "%s@%s" .image.repository .image.digest -}} -{{- else -}} -{{- printf "%s:%s" .image.repository (default .root.Chart.AppVersion .image.tag) -}} -{{- end -}} -{{- end -}} diff --git a/charts/mirum/templates/server-deployment.yaml b/charts/mirum/templates/server-deployment.yaml deleted file mode 100644 --- a/charts/mirum/templates/server-deployment.yaml +++ /dev/null @@ -1,142 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -{{- if and .Values.server.enabled (ne (int .Values.server.replicaCount) 1) }} -{{- fail "mirum: server.replicaCount must be 1 while the task queue is process-local" }} -{{- end }} -{{- if and .Values.server.enabled .Values.server.postgresqlMtls.enabled (not .Values.server.serviceAccountName) }} -{{- fail "mirum: server.serviceAccountName is required when server.postgresqlMtls.enabled=true" }} -{{- end }} -{{- if .Values.server.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "mirum.fullname" . }}-server - labels: - {{- include "mirum.componentLabels" (dict "root" . "component" "server") | nindent 4 }} -spec: - replicas: {{ .Values.server.replicaCount }} - strategy: - type: Recreate - selector: - matchLabels: - {{- include "mirum.selectorLabels" (dict "root" . "component" "server") | nindent 6 }} - template: - metadata: - annotations: - {{- with .Values.server.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "mirum.selectorLabels" (dict "root" . "component" "server") | nindent 8 }} - {{- with .Values.server.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - automountServiceAccountToken: false - {{- with .Values.server.serviceAccountName }} - serviceAccountName: {{ . | quote }} - {{- end }} - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} - securityContext: - runAsNonRoot: true - runAsUser: 10000 - runAsGroup: 10000 - fsGroup: 10000 - fsGroupChangePolicy: OnRootMismatch - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - containers: - - name: server - image: {{ include "mirum.image" (dict "root" . "image" .Values.server.image) | quote }} - imagePullPolicy: {{ .Values.server.image.pullPolicy }} - args: ["daemon", "--config=/etc/mirum/secret/config.yaml"] - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: [ALL] - readOnlyRootFilesystem: true - ports: - - name: web - containerPort: {{ .Values.server.webPort }} - - name: grpc - containerPort: {{ .Values.server.grpcPort }} - {{- with .Values.server.extraEnv }} - env: - {{- toYaml . | nindent 12 }} - {{- end }} - startupProbe: - tcpSocket: { port: web } - failureThreshold: 30 - periodSeconds: 2 - readinessProbe: - tcpSocket: { port: web } - livenessProbe: - tcpSocket: { port: web } - periodSeconds: 20 - resources: - {{- toYaml .Values.server.resources | nindent 12 }} - volumeMounts: - - name: config - mountPath: /etc/mirum/secret - readOnly: true - {{- with .Values.server.grpcTls.existingSecret }} - - name: grpc-tls - mountPath: /etc/mirum/grpc-tls - readOnly: true - {{- end }} - {{- if .Values.server.postgresqlMtls.enabled }} - - name: postgresql-tls - mountPath: {{ .Values.server.postgresqlMtls.mountPath }} - readOnly: true - {{- end }} - - name: run - mountPath: /run/mirum-server - volumes: - - name: config - secret: - secretName: {{ .Values.server.existingSecret }} - defaultMode: 0440 - {{- with .Values.server.grpcTls.existingSecret }} - - name: grpc-tls - secret: - secretName: {{ . }} - defaultMode: 0440 - {{- end }} - {{- if .Values.server.postgresqlMtls.enabled }} - - name: postgresql-tls - csi: - driver: csi.cert-manager.io - readOnly: true - volumeAttributes: - csi.cert-manager.io/issuer-name: {{ required "mirum: server.postgresqlMtls.issuerName is required" .Values.server.postgresqlMtls.issuerName | quote }} - csi.cert-manager.io/issuer-kind: {{ .Values.server.postgresqlMtls.issuerKind | quote }} - csi.cert-manager.io/common-name: {{ required "mirum: server.postgresqlMtls.commonName is required" .Values.server.postgresqlMtls.commonName | quote }} - csi.cert-manager.io/uri-sans: {{ .Values.server.postgresqlMtls.uriSan | quote }} - csi.cert-manager.io/key-algorithm: "ECDSA" - csi.cert-manager.io/key-size: "256" - csi.cert-manager.io/key-encoding: "PKCS8" - csi.cert-manager.io/key-usages: "digital signature,client auth" - csi.cert-manager.io/duration: {{ .Values.server.postgresqlMtls.duration | quote }} - csi.cert-manager.io/renew-before: {{ .Values.server.postgresqlMtls.renewBefore | quote }} - csi.cert-manager.io/fs-group: {{ .Values.server.postgresqlMtls.fsGroup | quote }} - {{- end }} - - name: run - emptyDir: {} - {{- with .Values.server.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.server.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.server.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} - -# vim: set filetype=helm: diff --git a/charts/mirum/templates/server-httproute.yaml b/charts/mirum/templates/server-httproute.yaml deleted file mode 100644 --- a/charts/mirum/templates/server-httproute.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -{{- if and .Values.server.enabled .Values.server.route.enabled }} -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: {{ include "mirum.fullname" . }} - labels: - {{- include "mirum.componentLabels" (dict "root" . "component" "server") | nindent 4 }} -spec: - {{- with .Values.server.route.parentRefs }} - parentRefs: - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.server.route.hostnames }} - hostnames: - {{- toYaml . | nindent 4 }} - {{- end }} - rules: - - backendRefs: - - name: {{ include "mirum.fullname" . }} - port: {{ .Values.server.webPort }} -{{- end }} - -# vim: set filetype=helm: diff --git a/charts/mirum/templates/server-service.yaml b/charts/mirum/templates/server-service.yaml deleted file mode 100644 --- a/charts/mirum/templates/server-service.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -{{- if .Values.server.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "mirum.fullname" . }} - labels: - {{- include "mirum.componentLabels" (dict "root" . "component" "server") | nindent 4 }} -spec: - selector: - {{- include "mirum.selectorLabels" (dict "root" . "component" "server") | nindent 4 }} - ports: - - name: web - port: {{ .Values.server.webPort }} - targetPort: web - - name: grpc - port: {{ .Values.server.grpcPort }} - targetPort: grpc -{{- end }} - -# vim: set filetype=helm: diff --git a/charts/mirum/templates/server-tcproute.yaml b/charts/mirum/templates/server-tcproute.yaml deleted file mode 100644 --- a/charts/mirum/templates/server-tcproute.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -{{- if and .Values.server.enabled .Values.server.grpcRoute.enabled }} -apiVersion: gateway.networking.k8s.io/v1 -kind: TCPRoute -metadata: - name: {{ include "mirum.fullname" . }}-grpc - labels: - {{- include "mirum.componentLabels" (dict "root" . "component" "server") | nindent 4 }} -spec: - {{- with .Values.server.grpcRoute.parentRefs }} - parentRefs: - {{- toYaml . | nindent 4 }} - {{- end }} - rules: - - backendRefs: - - name: {{ include "mirum.fullname" . }} - port: {{ .Values.server.grpcPort }} -{{- end }} - -# vim: set filetype=helm: diff --git a/charts/mirum/templates/worker-deployment.yaml b/charts/mirum/templates/worker-deployment.yaml deleted file mode 100644 --- a/charts/mirum/templates/worker-deployment.yaml +++ /dev/null @@ -1,87 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -{{- if .Values.worker.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "mirum.fullname" . }}-worker - labels: - {{- include "mirum.componentLabels" (dict "root" . "component" "worker") | nindent 4 }} -spec: - replicas: {{ .Values.worker.replicaCount }} - selector: - matchLabels: - {{- include "mirum.selectorLabels" (dict "root" . "component" "worker") | nindent 6 }} - template: - metadata: - annotations: - {{- with .Values.worker.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "mirum.selectorLabels" (dict "root" . "component" "worker") | nindent 8 }} - {{- with .Values.worker.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - automountServiceAccountToken: false - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} - securityContext: - runAsNonRoot: true - runAsUser: 10000 - runAsGroup: 10000 - fsGroup: 10000 - fsGroupChangePolicy: OnRootMismatch - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - containers: - - name: worker - image: {{ include "mirum.image" (dict "root" . "image" .Values.worker.image) | quote }} - imagePullPolicy: {{ .Values.worker.image.pullPolicy }} - args: ["--config=/etc/mirum/secret/config.yaml"] - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: [ALL] - readOnlyRootFilesystem: true - {{- with .Values.worker.extraEnv }} - env: - {{- toYaml . | nindent 12 }} - {{- end }} - resources: - {{- toYaml .Values.worker.resources | nindent 12 }} - volumeMounts: - - name: config - mountPath: /etc/mirum/secret - readOnly: true - - name: workspace - mountPath: /var/lib/mirum-worker - - name: tmp - mountPath: /tmp - volumes: - - name: config - secret: - secretName: {{ .Values.worker.existingSecret }} - defaultMode: 0440 - - name: workspace - emptyDir: {} - - name: tmp - emptyDir: {} - {{- with .Values.worker.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.worker.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.worker.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} - -# vim: set filetype=helm: diff --git a/charts/mirum/values.yaml b/charts/mirum/values.yaml deleted file mode 100644 --- a/charts/mirum/values.yaml +++ /dev/null @@ -1,75 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" - -server: - enabled: true - replicaCount: 1 - image: - repository: ghcr.io/dimidiumlabs/mirum-server - tag: "" - digest: "" - pullPolicy: IfNotPresent - # Must contain config.yaml and any private files other than the gRPC - # certificate. Keep database_uri, pepper, token, and webhook_secret in this - # Secret rather than Helm values. - existingSecret: mirum-server - # Optional existing ServiceAccount used by the server. The default empty - # value preserves the current Deployment and external database path. - serviceAccountName: "" - postgresqlMtls: - # Opt-in client-certificate mount for passwordless PostgreSQL mTLS. Disabled - # by default; no CSI resources or volume mounts are rendered unless enabled. - enabled: false - mountPath: /etc/mirum/postgresql-tls - issuerName: "" - issuerKind: ClusterIssuer - commonName: "" - uriSan: "spiffe://ddlabs.internal/ns/${POD_NAMESPACE}/sa/${SERVICE_ACCOUNT_NAME}/pod/${POD_UID}" - duration: 2160h - renewBefore: 360h - fsGroup: 10000 - grpcTls: - # Optional cert-manager-style Secret containing tls.crt and tls.key. The - # files are mounted at /etc/mirum/grpc-tls/ for config.yaml to reference. - existingSecret: "" - webPort: 3000 - grpcPort: 2000 - route: - enabled: false - hostnames: [] - parentRefs: [] - grpcRoute: - enabled: false - parentRefs: [] - resources: {} - extraEnv: [] - podAnnotations: {} - podLabels: {} - nodeSelector: {} - tolerations: [] - affinity: {} - -worker: - enabled: false - replicaCount: 1 - image: - repository: ghcr.io/dimidiumlabs/mirum-worker - tag: "" - digest: "" - pullPolicy: IfNotPresent - # Must contain config.yaml, the Ed25519 key referenced by key_file, and an - # optional CA file referenced by tls_ca. - existingSecret: mirum-worker - resources: {} - extraEnv: [] - podAnnotations: {} - podLabels: {} - nodeSelector: {} - tolerations: [] - affinity: {} - -terminationGracePeriodSeconds: 40 diff --git a/cmd/mirum-server/Dockerfile b/cmd/mirum-server/Dockerfile deleted file mode 100644 --- a/cmd/mirum-server/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -FROM gcr.io/distroless/static-debian13:nonroot@sha256:1c2c046bc09ed40fad370b599a0b1ae7987f55b01e247cf27a7c27cd97e5bbc7 - -ARG TARGETARCH - -LABEL org.opencontainers.image.source="https://github.com/dimidiumlabs/mirum" \ - org.opencontainers.image.licenses="AGPL-3.0-or-later" \ - org.opencontainers.image.title="mirum-server" - -COPY --chown=root:root --chmod=0755 .container/mirum-server-linux-${TARGETARCH} /usr/local/bin/mirum-server -COPY LICENSE README.md /usr/share/doc/mirum/ - -USER 10000:10000 -EXPOSE 3000 2000 -ENTRYPOINT ["/usr/local/bin/mirum-server"] -CMD ["daemon", "--config=/etc/mirum/config.yaml"] - -# syntax=docker/dockerfile: diff --git a/cmd/mirum-worker/Dockerfile b/cmd/mirum-worker/Dockerfile deleted file mode 100644 --- a/cmd/mirum-worker/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -FROM docker.io/library/alpine:3.23.5@sha256:fd791d74b68913cbb027c6546007b3f0d3bc45125f797758156952bc2d6daf40 - -ARG TARGETARCH - -LABEL org.opencontainers.image.source="https://github.com/dimidiumlabs/mirum" \ - org.opencontainers.image.licenses="AGPL-3.0-or-later" \ - org.opencontainers.image.title="mirum-worker" - -RUN apk add --no-cache bash ca-certificates git && \ - addgroup -g 10000 mirum-worker && \ - adduser -D -H -u 10000 -G mirum-worker -h /var/lib/mirum-worker \ - -s /sbin/nologin mirum-worker && \ - install -d -o mirum-worker -g mirum-worker -m 0750 /var/lib/mirum-worker - -COPY --chown=root:root --chmod=0755 .container/mirum-worker-linux-${TARGETARCH} /usr/local/bin/mirum-worker -COPY LICENSE README.md /usr/share/doc/mirum/ - -USER 10000:10000 -WORKDIR /var/lib/mirum-worker -ENTRYPOINT ["/usr/local/bin/mirum-worker"] -CMD ["--config=/etc/mirum/config.yaml"] - -# syntax=docker/dockerfile: diff --git a/mise.lock b/mise.lock index c1cad8c..ea51012 100644 --- a/mise.lock +++ b/mise.lock @@ -56,6 +56,20 @@ url = "https://nodejs.org/dist/v24.18.0/node-v24.18.0-linux-arm64.tar.gz" checksum = "sha256:783130984963db7ba9cbd01089eaf2c2efb055c7c1693c943174b967b3050cb8" url = "https://nodejs.org/dist/v24.18.0/node-v24.18.0-linux-x64.tar.gz" +[[tools.rclone]] +version = "1.74.4" +backend = "aqua:rclone/rclone" + +[tools.rclone."platforms.linux-arm64"] +checksum = "sha256:97685285c9ad6a0cf17d5844115d2a67245af6444db672187074bd9c358de419" +url = "https://github.com/rclone/rclone/releases/download/v1.74.4/rclone-v1.74.4-linux-arm64.zip" +url_api = "https://api.github.com/repos/rclone/rclone/releases/assets/470550100" + +[tools.rclone."platforms.linux-x64"] +checksum = "sha256:fe435e0c36228e7c2f116a8701f01127bb1f694005fc11d1f27186c8bca4115d" +url = "https://github.com/rclone/rclone/releases/download/v1.74.4/rclone-v1.74.4-linux-amd64.zip" +url_api = "https://api.github.com/repos/rclone/rclone/releases/assets/470549540" + [[tools.task]] version = "3.52.0" backend = "aqua:go-task/task" diff --git a/mise.toml b/mise.toml index 9170cef..1be13f0 100644 --- a/mise.toml +++ b/mise.toml @@ -11,6 +11,7 @@ buf = "1.67.0" gh = "2.96.0" go = "1.26.6" node = "24.18.0" +rclone = "1.74.4" task = "3.52.0" # Removed after Taskfile.yml is migrated to mise tasks. zig = "0.16.0" @@ -18,21 +19,18 @@ zig = "0.16.0" # APT "apt:apt-utils" = "latest" "apt:createrepo-c" = "latest" -"apt:debsigs" = "latest" "apt:gnupg" = "latest" "apt:openssl" = "latest" -"apt:rpm" = "latest" "apt:zip" = "latest" # DNF "dnf:createrepo_c" = "latest" "dnf:gnupg2" = "latest" "dnf:openssl" = "latest" -"dnf:rpm" = "latest" "dnf:zip" = "latest" [task_config] dir = "{{cwd}}" includes = [ - "git::https://github.com/dimidiumlabs/platform.git//tasks?ref=8bc35fe8be889c50db2d1fb4425cc1b4097dc6b8", + "git::https://github.com/dimidiumlabs/infra.git//tasks?ref=9e7330a3e5bde39a87e0ac1b76c9e85db7a6d64a", ] diff --git a/nfpm.yaml b/nfpm.yaml index a0fc6ad..e3c23af 100644 --- a/nfpm.yaml +++ b/nfpm.yaml @@ -127,6 +127,6 @@ rpm: apk: signature: key_file: ${APK_SIGNING_KEY} - # nFPM appends ".rsa.pub"; the versioned basename lets clients retain - # historical package keys during rotation. - key_name: packages.${PACKAGE_KEY_VERSION} + # nfpm appends ".rsa.pub" to this value when embedding the signature; + # clients must install the public key as /etc/apk/keys/mirum.rsa.pub. + key_name: mirum diff --git a/packaging/apt-ftparchive.conf b/packaging/apt-ftparchive.conf new file mode 100644 --- /dev/null +++ b/packaging/apt-ftparchive.conf @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2026 Nikolay Govorov +// SPDX-License-Identifier: AGPL-3.0-or-later + +Dir { + ArchiveDir "."; + CacheDir "/tmp/apt-cache"; +}; + +Default { + Packages::Compress ". gzip"; + Packages::Extensions ".deb"; +}; + +TreeDefault { + Packages "$(DIST)/$(SECTION)/binary-$(ARCH)/Packages"; + BinCacheDB "packages-$(DIST)-$(ARCH).db"; +}; + +Tree "dists/stable" { + Sections "main"; + Architectures "amd64 arm64 riscv64 ppc64le"; + Directory "pool/stable"; +}; + +Tree "dists/nightly" { + Sections "main"; + Architectures "amd64 arm64 riscv64 ppc64le"; + Directory "pool/nightly"; +}; |
