fix: make v02 git mirror sync manual and atomic
This commit is contained in:
@@ -2809,24 +2809,99 @@ repo_url="ssh://git@ssh.github.com:443/pikasTech/HWLAB.git"
|
||||
repo_path="/cache/pikasTech/HWLAB.git"
|
||||
lock_dir="/cache/.hwlab-sync.lock"
|
||||
mkdir -p /cache/pikasTech /root/.ssh
|
||||
if ! mkdir "\${lock_dir}" 2>/dev/null; then
|
||||
if ! mkdir "$lock_dir" 2>/dev/null; then
|
||||
echo "git mirror sync already running"
|
||||
exit 0
|
||||
fi
|
||||
trap 'rmdir "\${lock_dir}" 2>/dev/null || true' EXIT INT TERM
|
||||
trap 'rmdir "$lock_dir" 2>/dev/null || true' EXIT INT TERM
|
||||
cp /git-ssh/ssh-privatekey /root/.ssh/id_rsa
|
||||
chmod 0400 /root/.ssh/id_rsa
|
||||
export GIT_SSH_COMMAND="ssh -i /root/.ssh/id_rsa -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/root/.ssh/known_hosts -o ConnectTimeout=10 -o ServerAliveInterval=5 -o ServerAliveCountMax=1"
|
||||
if [ -d "\${repo_path}/objects" ] && [ -f "\${repo_path}/HEAD" ]; then
|
||||
git -C "\${repo_path}" remote set-url origin "\${repo_url}"
|
||||
timeout 180 git -C "\${repo_path}" remote update --prune
|
||||
if [ -d "$repo_path/objects" ] && [ -f "$repo_path/HEAD" ]; then
|
||||
git -C "$repo_path" remote set-url origin "$repo_url" || git -C "$repo_path" remote add origin "$repo_url"
|
||||
else
|
||||
rm -rf "\${repo_path}"
|
||||
timeout 240 git clone --mirror "\${repo_url}" "\${repo_path}"
|
||||
rm -rf "$repo_path"
|
||||
git init --bare "$repo_path"
|
||||
git -C "$repo_path" remote add origin "$repo_url"
|
||||
fi
|
||||
git -C "\${repo_path}" update-server-info
|
||||
git -C "\${repo_path}" rev-parse refs/heads/v0.2 | tee /cache/HWLAB-v0.2.head
|
||||
date -u +%Y-%m-%dT%H:%M:%SZ > /cache/HWLAB.last-sync
|
||||
git -C "$repo_path" config uploadpack.hideRefs refs/mirror-stage
|
||||
git -C "$repo_path" config --unset-all remote.origin.fetch 2>/dev/null || true
|
||||
git -C "$repo_path" config --add remote.origin.fetch '+refs/heads/*:refs/mirror-stage/heads/*'
|
||||
git -C "$repo_path" config --add remote.origin.fetch '+refs/tags/*:refs/mirror-stage/tags/*'
|
||||
git -C "$repo_path" for-each-ref --format='delete %(refname)' refs/mirror-stage | git -C "$repo_path" update-ref --stdin || true
|
||||
timeout 180 git -C "$repo_path" fetch --prune origin
|
||||
git -C "$repo_path" for-each-ref --format='%(objectname) %(refname)' refs/mirror-stage/heads > /tmp/hwlab-stage-heads
|
||||
git -C "$repo_path" for-each-ref --format='%(refname)' refs/mirror-stage/heads > /tmp/hwlab-stage-head-refs
|
||||
git -C "$repo_path" for-each-ref --format='%(objectname) %(refname)' refs/mirror-stage/tags > /tmp/hwlab-stage-tags
|
||||
git -C "$repo_path" for-each-ref --format='%(refname)' refs/mirror-stage/tags > /tmp/hwlab-stage-tag-refs
|
||||
if [ ! -s /tmp/hwlab-stage-heads ]; then
|
||||
echo "git mirror sync fetched no branch refs" >&2
|
||||
exit 41
|
||||
fi
|
||||
while read -r sha ref; do
|
||||
[ -n "$sha" ] || continue
|
||||
git -C "$repo_path" cat-file -e "$sha^{commit}"
|
||||
git -C "$repo_path" cat-file -e "$sha^{tree}"
|
||||
if git -C "$repo_path" rev-list --objects --missing=print "$sha" | grep -q '^?'; then
|
||||
echo "git mirror sync found missing objects for $ref $sha" >&2
|
||||
exit 42
|
||||
fi
|
||||
done < /tmp/hwlab-stage-heads
|
||||
while read -r sha ref; do
|
||||
[ -n "$sha" ] || continue
|
||||
name=$(printf '%s\n' "$ref" | sed 's#^refs/mirror-stage/heads/##')
|
||||
git -C "$repo_path" update-ref "refs/heads/$name" "$sha"
|
||||
done < /tmp/hwlab-stage-heads
|
||||
while read -r sha ref; do
|
||||
[ -n "$sha" ] || continue
|
||||
name=$(printf '%s\n' "$ref" | sed 's#^refs/mirror-stage/tags/##')
|
||||
git -C "$repo_path" update-ref "refs/tags/$name" "$sha"
|
||||
done < /tmp/hwlab-stage-tags
|
||||
git -C "$repo_path" for-each-ref --format='%(refname)' refs/heads > /tmp/hwlab-public-heads
|
||||
while read -r ref; do
|
||||
[ -n "$ref" ] || continue
|
||||
name=$(printf '%s\n' "$ref" | sed 's#^refs/heads/##')
|
||||
if ! grep -Fxq "refs/mirror-stage/heads/$name" /tmp/hwlab-stage-head-refs; then
|
||||
git -C "$repo_path" update-ref -d "$ref"
|
||||
fi
|
||||
done < /tmp/hwlab-public-heads
|
||||
git -C "$repo_path" for-each-ref --format='%(refname)' refs/tags > /tmp/hwlab-public-tags
|
||||
while read -r ref; do
|
||||
[ -n "$ref" ] || continue
|
||||
name=$(printf '%s\n' "$ref" | sed 's#^refs/tags/##')
|
||||
if ! grep -Fxq "refs/mirror-stage/tags/$name" /tmp/hwlab-stage-tag-refs; then
|
||||
git -C "$repo_path" update-ref -d "$ref"
|
||||
fi
|
||||
done < /tmp/hwlab-public-tags
|
||||
git -C "$repo_path" for-each-ref --format='delete %(refname)' refs/mirror-stage | git -C "$repo_path" update-ref --stdin || true
|
||||
if git -C "$repo_path" show-ref --verify --quiet refs/heads/v0.2; then
|
||||
git -C "$repo_path" symbolic-ref HEAD refs/heads/v0.2
|
||||
elif git -C "$repo_path" show-ref --verify --quiet refs/heads/G14; then
|
||||
git -C "$repo_path" symbolic-ref HEAD refs/heads/G14
|
||||
fi
|
||||
git -C "$repo_path" fsck --connectivity-only --no-dangling >/tmp/hwlab-git-fsck.out
|
||||
git -C "$repo_path" update-server-info
|
||||
v02_head=$(git -C "$repo_path" rev-parse refs/heads/v0.2 2>/dev/null || true)
|
||||
g14_head=$(git -C "$repo_path" rev-parse refs/heads/G14 2>/dev/null || true)
|
||||
v02_gitops_head=$(git -C "$repo_path" rev-parse refs/heads/v0.2-gitops 2>/dev/null || true)
|
||||
published_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
printf '%s\n' "$v02_head" | tee /cache/HWLAB-v0.2.head
|
||||
printf '%s\n' "$published_at" > /cache/HWLAB.last-sync
|
||||
export v02_head g14_head v02_gitops_head published_at
|
||||
node - <<'NODE' | tee /cache/HWLAB.last-sync.json
|
||||
const payload = {
|
||||
event: "git-mirror-sync",
|
||||
status: "published",
|
||||
repository: "pikasTech/HWLAB",
|
||||
publishedAt: process.env.published_at,
|
||||
refs: {
|
||||
"refs/heads/v0.2": process.env.v02_head || null,
|
||||
"refs/heads/G14": process.env.g14_head || null,
|
||||
"refs/heads/v0.2-gitops": process.env.v02_gitops_head || null
|
||||
}
|
||||
};
|
||||
console.log(JSON.stringify(payload));
|
||||
NODE
|
||||
`,
|
||||
"http.mjs": `import { createServer } from "node:http";
|
||||
import { spawn } from "node:child_process";
|
||||
@@ -3007,47 +3082,6 @@ function contentType(filePath) {
|
||||
kind: "Service",
|
||||
metadata: { name: "git-mirror-http", namespace: "devops-infra", labels: { ...labels, "app.kubernetes.io/component": "read-only-http" } },
|
||||
spec: { selector: { "app.kubernetes.io/name": "git-mirror", "app.kubernetes.io/component": "read-only-http" }, ports: [{ name: "http", port: 80, targetPort: "http" }] }
|
||||
},
|
||||
{
|
||||
apiVersion: "batch/v1",
|
||||
kind: "CronJob",
|
||||
metadata: { name: "git-mirror-hwlab-sync", namespace: "devops-infra", labels: { ...labels, "app.kubernetes.io/component": "sync-controller" } },
|
||||
spec: {
|
||||
schedule: "*/2 * * * *",
|
||||
concurrencyPolicy: "Forbid",
|
||||
successfulJobsHistoryLimit: 3,
|
||||
failedJobsHistoryLimit: 3,
|
||||
jobTemplate: {
|
||||
spec: {
|
||||
backoffLimit: 1,
|
||||
activeDeadlineSeconds: 300,
|
||||
template: {
|
||||
metadata: { labels: { ...labels, "app.kubernetes.io/component": "sync-controller" } },
|
||||
spec: {
|
||||
restartPolicy: "Never",
|
||||
hostNetwork: true,
|
||||
dnsPolicy: "ClusterFirstWithHostNet",
|
||||
volumes: [
|
||||
{ name: "cache", persistentVolumeClaim: { claimName: "git-mirror-cache" } },
|
||||
{ name: "git-ssh", secret: { secretName: "git-mirror-github-ssh", defaultMode: 0o400 } },
|
||||
{ name: "script", configMap: { name: "git-mirror-sync-script", defaultMode: 0o755 } }
|
||||
],
|
||||
containers: [{
|
||||
name: "sync",
|
||||
image: ciToolsRunnerImage,
|
||||
imagePullPolicy: "IfNotPresent",
|
||||
command: ["/script/sync.sh"],
|
||||
volumeMounts: [
|
||||
{ name: "cache", mountPath: "/cache" },
|
||||
{ name: "git-ssh", mountPath: "/git-ssh", readOnly: true },
|
||||
{ name: "script", mountPath: "/script", readOnly: true }
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user