Initial commit.
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: "0 0 * * 1"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
# packages: write # not yet supported by Gitea
|
||||
|
||||
jobs:
|
||||
base:
|
||||
name: Base Image
|
||||
runs-on: logaldeveloper-archlinux
|
||||
outputs:
|
||||
version_tag: ${{ steps.metadata.outputs.version_tag }}
|
||||
base_digest: ${{ steps.build-image.outputs.digest }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Log in to Gitea Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: git.logal.dev
|
||||
username: ${{ gitea.repository_owner }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build rootfs
|
||||
working-directory: archlinux-base
|
||||
run: bash build-rootfs.sh
|
||||
|
||||
- name: Package rootfs
|
||||
working-directory: archlinux-base
|
||||
run: |
|
||||
tar --numeric-owner --acls --xattrs \
|
||||
--directory build/rootfs \
|
||||
--create \
|
||||
--file build/rootfs.tar \
|
||||
.
|
||||
rm -rf build/rootfs
|
||||
|
||||
- name: Generate image metadata
|
||||
id: metadata
|
||||
run: |
|
||||
version_tag=$(date -u +%Y%m%d).${{ gitea.run_number }}
|
||||
created=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
printf 'created=%s\n' "$created" | tee -a "$GITEA_OUTPUT"
|
||||
printf 'version_tag=%s\n' "$version_tag" | tee -a "$GITEA_OUTPUT"
|
||||
|
||||
- name: Build image
|
||||
id: build-image
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
with:
|
||||
context: archlinux-base
|
||||
network: host
|
||||
push: true
|
||||
build-args: |
|
||||
OCI_CREATED=${{ steps.metadata.outputs.created }}
|
||||
OCI_REVISION=${{ gitea.sha }}
|
||||
OCI_VERSION=${{ steps.metadata.outputs.version_tag }}
|
||||
tags: |
|
||||
git.logal.dev/logaldeveloper/archlinux-base:${{ steps.metadata.outputs.version_tag }}
|
||||
git.logal.dev/logaldeveloper/archlinux-base:latest
|
||||
|
||||
- name: Generate SBOM
|
||||
working-directory: archlinux-base
|
||||
env:
|
||||
SYFT_CHECK_FOR_APP_UPDATE: "false"
|
||||
run: |
|
||||
syft scan registry:git.logal.dev/logaldeveloper/archlinux-base:${{ steps.metadata.outputs.version_tag }} \
|
||||
--override-default-catalogers alpm-db-cataloger \
|
||||
--source-name git.logal.dev/logaldeveloper/archlinux-base \
|
||||
--source-version "${{ steps.metadata.outputs.version_tag }}" \
|
||||
--output syft-table \
|
||||
--output cyclonedx-json=archlinux-base-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json
|
||||
sha256sum archlinux-base-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json
|
||||
zstd -T0 --ultra -22 \
|
||||
archlinux-base-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json
|
||||
|
||||
- name: Upload SBOM artifact
|
||||
uses: christopherhx/gitea-upload-artifact@8818363695ca2d5782c64f6453273341374767b7 # v7
|
||||
with:
|
||||
name: archlinux-base-cyclonedx-${{ steps.metadata.outputs.version_tag }}
|
||||
path: archlinux-base/archlinux-base-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json.zst
|
||||
if-no-files-found: error
|
||||
archive: "false"
|
||||
|
||||
ci:
|
||||
name: CI Image
|
||||
needs: base
|
||||
runs-on: logaldeveloper-archlinux
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Log in to Gitea Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: git.logal.dev
|
||||
username: ${{ gitea.repository_owner }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Generate image metadata
|
||||
id: metadata
|
||||
run: |
|
||||
version_tag="${{ needs.base.outputs.version_tag }}"
|
||||
created=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
printf 'created=%s\n' "$created" | tee -a "$GITEA_OUTPUT"
|
||||
printf 'version_tag=%s\n' "$version_tag" | tee -a "$GITEA_OUTPUT"
|
||||
|
||||
- name: Build image
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
with:
|
||||
context: archlinux-ci
|
||||
network: host
|
||||
push: true
|
||||
build-args: |
|
||||
ARCHLINUX_BASE_IMAGE=git.logal.dev/logaldeveloper/archlinux-base:${{ steps.metadata.outputs.version_tag }}
|
||||
OCI_BASE_DIGEST=${{ needs.base.outputs.base_digest }}
|
||||
OCI_CREATED=${{ steps.metadata.outputs.created }}
|
||||
OCI_REVISION=${{ gitea.sha }}
|
||||
OCI_VERSION=${{ steps.metadata.outputs.version_tag }}
|
||||
tags: |
|
||||
git.logal.dev/logaldeveloper/archlinux-ci:${{ steps.metadata.outputs.version_tag }}
|
||||
git.logal.dev/logaldeveloper/archlinux-ci:latest
|
||||
|
||||
- name: Generate SBOM
|
||||
working-directory: archlinux-ci
|
||||
env:
|
||||
SYFT_CHECK_FOR_APP_UPDATE: "false"
|
||||
run: |
|
||||
syft scan registry:git.logal.dev/logaldeveloper/archlinux-ci:${{ steps.metadata.outputs.version_tag }} \
|
||||
--override-default-catalogers alpm-db-cataloger \
|
||||
--source-name git.logal.dev/logaldeveloper/archlinux-ci \
|
||||
--source-version "${{ steps.metadata.outputs.version_tag }}" \
|
||||
--output syft-table \
|
||||
--output cyclonedx-json=archlinux-ci-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json
|
||||
sha256sum archlinux-ci-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json
|
||||
zstd -T0 --ultra -22 \
|
||||
archlinux-ci-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json
|
||||
|
||||
- name: Upload SBOM artifact
|
||||
uses: christopherhx/gitea-upload-artifact@8818363695ca2d5782c64f6453273341374767b7 # v7
|
||||
with:
|
||||
name: archlinux-ci-cyclonedx-${{ steps.metadata.outputs.version_tag }}
|
||||
path: archlinux-ci/archlinux-ci-${{ steps.metadata.outputs.version_tag }}.cyclonedx.json.zst
|
||||
if-no-files-found: error
|
||||
archive: "false"
|
||||
@@ -0,0 +1,5 @@
|
||||
/archlinux-base/build/
|
||||
/archlinux-base/*.cyclonedx.json
|
||||
/archlinux-base/*.cyclonedx.json.zst
|
||||
/archlinux-ci/*.cyclonedx.json
|
||||
/archlinux-ci/*.cyclonedx.json.zst
|
||||
@@ -0,0 +1,46 @@
|
||||
# Arch Linux Images
|
||||
|
||||
Arch Linux container images for my projects and CI pipelines. These images are
|
||||
tailored to my own repositories; they are not designed for general use and may
|
||||
change without notice.
|
||||
|
||||
The images are rebuilt weekly and published to my container registry.
|
||||
|
||||
## Images
|
||||
|
||||
- `archlinux-base`: vanilla Arch Linux image assembled from the official Arch
|
||||
bootstrap tarball.
|
||||
- `archlinux-ci`: CI image built from `archlinux-base` with the development and
|
||||
build tools I use in CI jobs.
|
||||
|
||||
Both images are published as `latest` and as `<yyyymmdd>.<run-number>` tags.
|
||||
|
||||
## Build Flow
|
||||
|
||||
The base image build downloads the latest official Arch bootstrap archive from
|
||||
[my private Arch Linux mirror](https://logal.dev/projects/arch-linux-mirror/),
|
||||
verifies its hashes and signature, updates the extracted rootfs with pacman,
|
||||
then packages it into a tarball. The Docker image is built from `scratch` with
|
||||
that rootfs.
|
||||
|
||||
The CI image is built after the base image, uses the same version tag, and adds:
|
||||
|
||||
- `7zip`
|
||||
- `base-devel`
|
||||
- `docker`
|
||||
- `ffmpeg`
|
||||
- `git`
|
||||
- `hugo`
|
||||
- `nodejs`
|
||||
- `python`
|
||||
- `shellcheck`
|
||||
- `syft`
|
||||
- `uv`
|
||||
|
||||
The CI image also installs the LogalNet internal certificate authority.
|
||||
|
||||
## Software Bill of Materials
|
||||
|
||||
Each build generates a CycloneDX Software Bill of Materials for the published
|
||||
image, available from the corresponding
|
||||
[CI job log](https://git.logal.dev/LogalDeveloper/Arch-Linux-Images/actions).
|
||||
@@ -0,0 +1,2 @@
|
||||
build/*
|
||||
!build/rootfs.tar
|
||||
@@ -0,0 +1,22 @@
|
||||
FROM scratch
|
||||
|
||||
ARG OCI_CREATED=""
|
||||
ARG OCI_REVISION=""
|
||||
ARG OCI_SOURCE="https://git.logal.dev/LogalDeveloper/Arch-Linux-Images"
|
||||
ARG OCI_VENDOR="Logan Fick <https://logal.dev/>"
|
||||
ARG OCI_VERSION=""
|
||||
|
||||
LABEL org.opencontainers.image.created="${OCI_CREATED}" \
|
||||
org.opencontainers.image.source="${OCI_SOURCE}" \
|
||||
org.opencontainers.image.url="${OCI_SOURCE}" \
|
||||
org.opencontainers.image.revision="${OCI_REVISION}" \
|
||||
org.opencontainers.image.vendor="${OCI_VENDOR}" \
|
||||
org.opencontainers.image.version="${OCI_VERSION}" \
|
||||
org.opencontainers.image.title="Arch Linux Base" \
|
||||
org.opencontainers.image.description="Vanilla Arch Linux container image built from the official Arch bootstrap tarball."
|
||||
|
||||
ADD build/rootfs.tar /
|
||||
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
CMD ["/usr/bin/bash"]
|
||||
Executable
+153
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if (( EUID != 0 )); then
|
||||
printf 'error: %s must be run as root\n' "$0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Keep all temporary files and the updated rootfs under this image directory so
|
||||
# later CI steps can scan and package it from the Docker build context.
|
||||
build_dir="$PWD/build"
|
||||
rootfs_dir="$build_dir/rootfs"
|
||||
bootstrap_base_url="https://mirrors.logal.dev/archlinux/iso/latest"
|
||||
bootstrap_tar_name="archlinux-bootstrap-x86_64.tar.zst"
|
||||
bootstrap_tar="$build_dir/$bootstrap_tar_name"
|
||||
bootstrap_sig="$build_dir/$bootstrap_tar_name.sig"
|
||||
sha256sums="$build_dir/sha256sums.txt"
|
||||
b2sums="$build_dir/b2sums.txt"
|
||||
|
||||
# Download with retries because the bootstrap tarball is the largest and most
|
||||
# failure-prone external input to this build.
|
||||
download_file() {
|
||||
local source_url=$1
|
||||
local output_path=$2
|
||||
|
||||
printf 'Downloading %s\n' "$source_url"
|
||||
curl --fail --location --show-error --retry 5 --retry-delay 3 \
|
||||
--output "$output_path" \
|
||||
"$source_url"
|
||||
}
|
||||
|
||||
section() {
|
||||
printf '\n[build-rootfs] %s\n' "$1"
|
||||
}
|
||||
|
||||
# The bootstrap rootfs has its own placeholder resolver config. We replace it
|
||||
# only while pacman needs network access inside the chroot.
|
||||
restore_resolv_conf() {
|
||||
if [[ -e "$rootfs_dir/etc/resolv.conf.bootstrap" ]]; then
|
||||
chroot "$rootfs_dir" /usr/bin/mv /etc/resolv.conf.bootstrap /etc/resolv.conf
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove the expanded rootfs only if the build fails; successful builds leave it
|
||||
# behind for later CI steps such as scanning and packaging.
|
||||
cleanup_target() {
|
||||
if [[ -d "$rootfs_dir" ]]; then
|
||||
restore_resolv_conf
|
||||
rm -rf "$rootfs_dir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_target EXIT
|
||||
|
||||
# Start from a fresh rootfs directory.
|
||||
section "Preparing build directory"
|
||||
mkdir -p "$build_dir"
|
||||
mkdir -p "$rootfs_dir"
|
||||
|
||||
# Fetch the official bootstrap archive, its signature, and both checksum files
|
||||
# from the Logal mirror.
|
||||
section "Downloading bootstrap files"
|
||||
download_file "$bootstrap_base_url/$bootstrap_tar_name" "$bootstrap_tar"
|
||||
download_file "$bootstrap_base_url/$bootstrap_tar_name.sig" "$bootstrap_sig"
|
||||
download_file "$bootstrap_base_url/sha256sums.txt" "$sha256sums"
|
||||
download_file "$bootstrap_base_url/b2sums.txt" "$b2sums"
|
||||
|
||||
bootstrap_sha256_line="$(grep -F " $bootstrap_tar_name" "$sha256sums")"
|
||||
bootstrap_b2_line="$(grep -F " $bootstrap_tar_name" "$b2sums")"
|
||||
|
||||
# Verify both published hashes before trusting the downloaded tarball.
|
||||
section "Verifying bootstrap archive"
|
||||
printf 'Expected bootstrap SHA256: %s\n' "${bootstrap_sha256_line%% *}"
|
||||
printf 'Actual bootstrap SHA256: '
|
||||
sha256sum "$bootstrap_tar"
|
||||
printf '%s\n' "$bootstrap_sha256_line" |
|
||||
sed "s# $bootstrap_tar_name\$# $bootstrap_tar#" |
|
||||
sha256sum --check --strict |
|
||||
sed 's/: / (SHA256): /'
|
||||
|
||||
printf 'Expected bootstrap BLAKE2: %s\n' "${bootstrap_b2_line%% *}"
|
||||
printf 'Actual bootstrap BLAKE2: '
|
||||
b2sum "$bootstrap_tar"
|
||||
printf '%s\n' "$bootstrap_b2_line" |
|
||||
sed "s# $bootstrap_tar_name\$# $bootstrap_tar#" |
|
||||
b2sum --check --strict |
|
||||
sed 's/: / (BLAKE2): /'
|
||||
|
||||
# Verify the upstream pacman signature against the host pacman keyring.
|
||||
pacman-key --verify "$bootstrap_sig" "$bootstrap_tar"
|
||||
|
||||
# Expand the rootfs without the archive's top-level root.x86_64 directory.
|
||||
section "Extracting bootstrap rootfs"
|
||||
tar --use-compress-program=unzstd \
|
||||
--acls \
|
||||
--xattrs \
|
||||
--extract \
|
||||
--file "$bootstrap_tar" \
|
||||
--directory "$rootfs_dir" \
|
||||
--strip-components=1
|
||||
|
||||
rm -f \
|
||||
"$bootstrap_tar" \
|
||||
"$bootstrap_sig" \
|
||||
"$sha256sums" \
|
||||
"$b2sums"
|
||||
|
||||
# The bootstrap tarball does not include an initialized pacman keyring.
|
||||
section "Initializing pacman keyring"
|
||||
rm -rf "$rootfs_dir/etc/pacman.d/gnupg"
|
||||
pacman-key --gpgdir "$rootfs_dir/etc/pacman.d/gnupg" --init
|
||||
pacman-key --gpgdir "$rootfs_dir/etc/pacman.d/gnupg" \
|
||||
--populate-from "$rootfs_dir/usr/share/pacman/keyrings" \
|
||||
--populate archlinux
|
||||
|
||||
# Pin package updates to the Logal Arch mirror as well.
|
||||
section "Configuring rootfs for updates"
|
||||
printf '%s\n' "Server = https://mirrors.logal.dev/archlinux/\$repo/os/\$arch" \
|
||||
> "$rootfs_dir/etc/pacman.d/mirrorlist"
|
||||
|
||||
# Some install scripts write to /dev/null. The bootstrap archive ships an empty
|
||||
# /dev, so provide a temporary node for the chrooted pacman transaction.
|
||||
mknod -m 666 "$rootfs_dir/dev/null" c 1 3
|
||||
|
||||
# Give the chroot DNS resolution for package downloads, then restore the
|
||||
# bootstrap resolver placeholder before packaging.
|
||||
chroot "$rootfs_dir" /usr/bin/mv /etc/resolv.conf /etc/resolv.conf.bootstrap
|
||||
cp /etc/resolv.conf "$rootfs_dir/etc/resolv.conf"
|
||||
|
||||
# Plain chroot lacks mount metadata, so CheckSpace cannot reliably inspect the
|
||||
# target filesystem during the update.
|
||||
cp "$rootfs_dir/etc/pacman.conf" "$rootfs_dir/etc/pacman-install.conf"
|
||||
sed -i 's/^[[:space:]]*CheckSpace/#&/' "$rootfs_dir/etc/pacman-install.conf"
|
||||
|
||||
section "Updating rootfs packages"
|
||||
chroot "$rootfs_dir" /usr/bin/pacman \
|
||||
--config /etc/pacman-install.conf \
|
||||
-Syu \
|
||||
--disable-sandbox \
|
||||
--noconfirm
|
||||
|
||||
chroot "$rootfs_dir" /usr/bin/rm /etc/pacman-install.conf
|
||||
restore_resolv_conf
|
||||
|
||||
# Drop downloaded package files so they are not baked into the container image.
|
||||
section "Cleaning package cache"
|
||||
{ yes || true; } | chroot "$rootfs_dir" /usr/bin/pacman -Scc
|
||||
|
||||
section "Finalizing rootfs"
|
||||
chroot "$rootfs_dir" /usr/bin/rm -f /dev/null
|
||||
|
||||
# Leave build/rootfs in place. CI packages it after any scan steps have run.
|
||||
trap - EXIT
|
||||
@@ -0,0 +1,41 @@
|
||||
ARG ARCHLINUX_BASE_IMAGE=git.logal.dev/logaldeveloper/archlinux-base:latest
|
||||
FROM ${ARCHLINUX_BASE_IMAGE}
|
||||
|
||||
ARG ARCHLINUX_BASE_IMAGE
|
||||
ARG OCI_BASE_DIGEST=""
|
||||
ARG OCI_CREATED=""
|
||||
ARG OCI_REVISION=""
|
||||
ARG OCI_SOURCE="https://git.logal.dev/LogalDeveloper/Arch-Linux-Images"
|
||||
ARG OCI_VENDOR="Logan Fick <https://logal.dev/>"
|
||||
ARG OCI_VERSION=""
|
||||
|
||||
LABEL org.opencontainers.image.created="${OCI_CREATED}" \
|
||||
org.opencontainers.image.source="${OCI_SOURCE}" \
|
||||
org.opencontainers.image.url="${OCI_SOURCE}" \
|
||||
org.opencontainers.image.revision="${OCI_REVISION}" \
|
||||
org.opencontainers.image.vendor="${OCI_VENDOR}" \
|
||||
org.opencontainers.image.version="${OCI_VERSION}" \
|
||||
org.opencontainers.image.title="Arch Linux CI" \
|
||||
org.opencontainers.image.description="Arch Linux container image for LogalDeveloper's CI jobs." \
|
||||
org.opencontainers.image.base.name="${ARCHLINUX_BASE_IMAGE}" \
|
||||
org.opencontainers.image.base.digest="${OCI_BASE_DIGEST}"
|
||||
|
||||
COPY logalnet-internal-ca.crt /tmp/logalnet-internal-ca.crt
|
||||
|
||||
RUN pacman -Syu --needed --disable-sandbox --noconfirm \
|
||||
base-devel \
|
||||
7zip \
|
||||
docker \
|
||||
ffmpeg \
|
||||
git \
|
||||
hugo \
|
||||
nodejs \
|
||||
python \
|
||||
shellcheck \
|
||||
syft \
|
||||
uv \
|
||||
&& trust anchor --store /tmp/logalnet-internal-ca.crt \
|
||||
&& rm /tmp/logalnet-internal-ca.crt \
|
||||
&& { yes || true; } | pacman -Scc
|
||||
|
||||
CMD ["/usr/bin/bash"]
|
||||
@@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICsTCCAjagAwIBAgIRAIRTi2u8EKDZNutOTc8H2ZUwCgYIKoZIzj0EAwMwbTEL
|
||||
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDkxvZ2FsRGV2ZWxvcGVyMREwDwYDVQQLEwhM
|
||||
b2dhbE5ldDEyMDAGA1UEAxMpTG9nYWxOZXQgSW50ZXJuYWwgQ2VydGlmaWNhdGlv
|
||||
biBBdXRob3JpdHkwHhcNMjYwMzE1MjA0NzMyWhcNNDYwMzEwMjA0NzMyWjBtMQsw
|
||||
CQYDVQQGEwJVUzEXMBUGA1UEChMOTG9nYWxEZXZlbG9wZXIxETAPBgNVBAsTCExv
|
||||
Z2FsTmV0MTIwMAYDVQQDEylMb2dhbE5ldCBJbnRlcm5hbCBDZXJ0aWZpY2F0aW9u
|
||||
IEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABHOYlJioKnPe6eRrnk4X
|
||||
qEA6eCwVUqU/3A1vJhwZV7rfS+gs97zqIiJyYsiOsXl0EDoXLB0TVOdDm/R2r76j
|
||||
4fJXtWupGXQczRAxVuAtoZfG5iCTCV5EFlX4sxbo+FZleqOBmTCBljAOBgNVHQ8B
|
||||
Af8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU5OcAiltvnWIG
|
||||
B/SNXy9CCLQu78kwUQYDVR0eAQH/BEcwRaARMA+CDW5ldC5sb2dhbC5kZXahMDAK
|
||||
hwgAAAAAAAAAADAihyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAK
|
||||
BggqhkjOPQQDAwNpADBmAjEAjd3B7ov6IyXxhgf3/yi+flBaHTBW9nGQvM2r/PfF
|
||||
yMfzMlfN4+uPQZn4jjCcYb8hAjEAnu1uAT9bGhAtgz8N5iqV6yS4LkGScQBAlDrN
|
||||
30YeI+zbnwVaiGwOJmvZlG/Lw23T
|
||||
-----END CERTIFICATE-----
|
||||
Reference in New Issue
Block a user