-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cron job to start rebuild everything pipelines #845
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM python:3.10 | ||
|
||
WORKDIR /scripts/ | ||
COPY requirements.txt ./ | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
COPY sync-git-remotes.py ./ | ||
|
||
ENTRYPOINT [ "python", "./sync-git-remotes.py"] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sentry-sdk==1.32.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import argparse | ||
import base64 | ||
import os | ||
import re | ||
import subprocess | ||
import sys | ||
import tempfile | ||
from contextlib import contextmanager | ||
|
||
try: | ||
import sentry_sdk | ||
sentry_sdk.init( | ||
# This cron job only runs once weekly, | ||
# so just record all transactions. | ||
traces_sample_rate=1.0, | ||
) | ||
except Exception: | ||
print("Could not configure sentry.") | ||
|
||
|
||
# Copied from SpackCIBridge.py | ||
def setup_ssh(self, ssh_key_base64): | ||
"""Start the ssh agent.""" | ||
print("Starting ssh-agent") | ||
output = subprocess.run(["ssh-agent", "-s"], check=True, stdout=subprocess.PIPE).stdout | ||
|
||
# Search for PID in output. | ||
pid_regexp = re.compile(r"SSH_AGENT_PID=([0-9]+)") | ||
match = pid_regexp.search(output.decode("utf-8")) | ||
if match is None: | ||
print("WARNING: could not detect ssh-agent PID.", file=sys.stderr) | ||
print("ssh-agent will not be killed upon program termination", file=sys.stderr) | ||
else: | ||
pid = match.group(1) | ||
os.environ["SSH_AGENT_PID"] = pid | ||
self.cleanup_ssh_agent = True | ||
|
||
# Search for socket in output. | ||
socket_regexp = re.compile(r"SSH_AUTH_SOCK=([^;]+);") | ||
match = socket_regexp.search(output.decode("utf-8")) | ||
if match is None: | ||
print("WARNING: could not detect ssh-agent socket.", file=sys.stderr) | ||
print("Key will be added to caller's ssh-agent (if any)", file=sys.stderr) | ||
else: | ||
socket = match.group(1) | ||
os.environ["SSH_AUTH_SOCK"] = socket | ||
|
||
# Add the key. | ||
ssh_key = base64.b64decode(ssh_key_base64) | ||
ssh_key = ssh_key.replace(b"\r", b"") | ||
with tempfile.NamedTemporaryFile() as fp: | ||
fp.write(ssh_key) | ||
fp.seek(0) | ||
subprocess.run(["ssh-add", fp.name], check=True) | ||
|
||
|
||
def setup_repo(pull_remote, push_remote, branch): | ||
subprocess.run(["git", "init"], check=True) | ||
subprocess.run(["git", "config", "user.email", "noreply@spack.io"], check=True) | ||
subprocess.run(["git", "config", "user.name", "spackbot"], check=True) | ||
subprocess.run(["git", "config", "advice.detachedHead", "false"], check=True) | ||
|
||
subprocess.run(["git", "remote", "add", "origin", pull_remote], check=True) | ||
subprocess.run(["git", "remote", "set-url", "--push", "origin", push_remote], check=True) | ||
|
||
fetch_args = ["git", "fetch", "-q", "origin", branch] | ||
subprocess.run(fetch_args, check=True, stdout=subprocess.PIPE).stdout | ||
subprocess.run(["git", "checkout", branch], check=True) | ||
|
||
|
||
@contextmanager | ||
def chworkingdir(path): | ||
save_dir = os.path.realpath(os.curdir) | ||
if path: | ||
if not os.path.exists(path): | ||
os.makedirs(path) | ||
os.chdir(path) | ||
yield path | ||
else: | ||
with tempfile.TemporaryDirectory() as tmpdir: | ||
os.chdir(tmpdir) | ||
yield tmpdir | ||
|
||
os.chdir(save_dir) | ||
|
||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser(description="Pull and repush a branch from one remote to another") | ||
parser.add_argument("--push-remote", help="Host to push to") | ||
parser.add_argument("--push-branch", help="Name of pushed branch") | ||
|
||
parser.add_argument("--tag", action="store_true", help="Use a tag instead of a branch alias") | ||
|
||
parser.add_argument("--pull-remote", help="Host to pull to") | ||
parser.add_argument("--pull-branch", help="Name of pulled branch") | ||
|
||
parser.add_argument("--working-dir", help="Set the working directory") | ||
|
||
args = parser.parse_args() | ||
|
||
# Configure ssh for pushing to gitlab | ||
ssh_key_base64 = os.getenv("GITLAB_SSH_KEY_BASE64") | ||
if ssh_key_base64 is None: | ||
raise Exception("GITLAB_SSH_KEY_BASE64 environment is not set") | ||
setup_ssh(ssh_key_base64) | ||
|
||
with chworkingdir(args.working_dir): | ||
setup_repo(args.pull_remote, args.push_remote, args.pull_branch) | ||
|
||
if args.tag: | ||
subprocess.run(["git", "tag", args.push_branch], check=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you may need an annotated tag object. I feel like Zack ran into something like that when pushing the develop snapshot tags. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is here for potentially changing this to tag develop and push the new tag on the currently running develop, or push a new develop. I am not sure what is better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I know what you mean. I'm was just wondering if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, this isn't for a release or anything so I don't think there is a need to add any annotations. These also only get pushed to gitlab, so they are opaque to the world. |
||
else: | ||
subprocess.run(["git", "checkout", "-b", args.push_branch], check=True) | ||
|
||
# Push the renamed branch to the push remote | ||
subprocess.run(["git", "push", "-f", "origin", args.push_branch], check=True) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
apiVersion: batch/v1 | ||
kind: CronJob | ||
metadata: | ||
name: rebuild-everything | ||
namespace: custom | ||
spec: | ||
schedule: "0 0 */14 * 6" | ||
concurrencyPolicy: Forbid | ||
jobTemplate: | ||
spec: | ||
activeDeadlineSeconds: 1200 # terminate any running job after 20 minutes | ||
backoffLimit: 0 | ||
template: | ||
spec: | ||
restartPolicy: Never | ||
containers: | ||
- name: sync | ||
image: ghcr.io/spack/git-remote-sync:0.0.1 | ||
imagePullPolicy: IfNotPresent | ||
resources: | ||
requests: | ||
cpu: 500m | ||
memory: 500M | ||
env: | ||
# This secret is double base64 encoded | ||
- name: GITLAB_SSH_KEY_BASE64 | ||
valueFrom: | ||
secretKeyRef: | ||
name: rebuild-everything | ||
key: gitlab-ssh-key | ||
args: | ||
- "--push-mirror" | ||
- "git@ssh.gitlab.spack.io:spack/spack.git" | ||
- "--push-branch" | ||
- "develop-re-$(date --iso-8601)" | ||
- "--pull-mirror" | ||
- "https://github.com/spack/spack.git" | ||
- "--pull-branch" | ||
- "develop" | ||
nodeSelector: | ||
spack.io/node-pool: base |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
apiVersion: bitnami.com/v1alpha1 | ||
kind: SealedSecret | ||
metadata: | ||
name: rebuild-everything | ||
namespace: custom | ||
spec: | ||
encryptedData: | ||
# This token must have repo:status permissions | ||
scottwittenburg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
gitlab-ssh-key: AgBOg3sj4PYdQRvGEISHOUQVRa1FSEX+oiILWWrvGGUZ5jKrcCX+7vNKJZx/9MQIkMhZGFfkfvCyUjcu7ztehdfljnIZMdnkC3JvYp4l8AmGJhC6S3rJwHbQZaAiv+zWTrHHLztGI5rm9CnhzzLM5eAdWrFy8lPYoF89dzQuRrJgNQ/7eDpfEhtfXVQkNO/pzLTBTlQ4vBjj/eC3d34SuYygfmUXmmJvYMrw/3NsRFOBiUQiywU+m13VA2l+xRG9CNSBMxktyLj1oW7MKLFuIRb0Jnv5hOg6rBoXhRATaHeTj2n4VNr4ztbZtSeq2k/ZL1bgk7nppfSIc/K8crpBXApQBHkORjQnhnGGWSZqii5LC7sU0tRQOUu0987xAtO6V/EvpAa+ZsthhGyCv1E7VK/NemFVHipf+2cO39y7AC5Xk6wUn+FpW18yWPpPofylvIdLjmh5qDlqKPx8ZLgcwx+/1IHjmod7iSKHFw8wWQgX8W0NmAjqWmblHaCoXLrqEEOvQIyT0LH7+VjRJtprEnyPUFTAy75Kk6VFa3UkBkzorsdGw7R2vhEVVzV/WnZSY7rAL//CLdiXP/ut/tf8aHj4A1zezSRo3nm7lXl7DfCa9NAUNg+Y20AGpNKKAGmWRwAcxw92jmK09lrWVmFxAxRoxz3HexzpAvJxb2YEU9/C4gkP0+OYZ1pqKQI+UfISjrzNco3eYWXX9rrTEYqrcHu/FCRKTGp2oKndsAH5ehPONo8nV23uatUS7uhBfZCF0MfqZrfLaPhCMxiMlvuVtFc1WmtzJ4NwxoaBXhrtYgwVP+k2nPXEVYvbwNNG7/1UdGdgdJMhJmvkoPgwXbRF9PddI+9tm4jAp6fXj837yAeVA5Je/kNdXhlw4LmADm7J5E1jNIDMJg6MqGAOZ1aNJypb+YVZ/pbULTUnP963jlzzp1FFuHT/CnaB14/MeXWYCBtqUHiQ5pExxSxgaI4Fjm63loQSEaDiO3+PkghsNWkNQ10liFznAGSoABfiIaOcadnBWsI2zJ+bE1ST2U8mVF2ClvzloJ8lk23p3MvstuliEQqRlKLDWPERAEBIljd5GtQBH2LVq7FsKoHWIqLSXjdUxNE13ns+ngDwCIA5snoKyqxec9IJLpBaTMnyDStMdLbxwuE6PJRVYOoktTa+OV1Ja6yBYmyjAQG5hzJMxY1FBQZTSUlB5K029sT5s35o8aRrpiwatcQLKZuKqw6SI0wtSgKIkL5f3BnuwGeUfeUPveW0IAxHH0dUbQEZkNyqjgQbVq6Oui4LGp9ZLgFLpNYmVC0O62y1cOtJmmo5jztPJS+zJ0zJKbgArKUgsZa7+9BVJefTTmY43C1TttFbVQhg5+O0KY9xuoxfxY6y4tWjuTm3fK3l5e/UrA+8SR+PX0CWm2puADR7eNyvWK1YmogNOf//FA== | ||
template: | ||
metadata: | ||
annotations: | ||
kustomize.toolkit.fluxcd.io/reconcile: disabled | ||
sealedsecrets.bitnami.com/managed: "true" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you look at the one provided by
contextlib
? Maybe you don't need to write your own.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would have to be something like
with tempdir.TemporaryDirectory() as workingdir, contextmanager.chdir(workingdir)
which I didn't like. The one I have lets be choose whether to chdir to a temp dir or a persistent dir which was nice to test this locally.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did the something similar for testing protected publish locally, this is how I avoided forcing use of a temporary directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, the way yield works is still a bit of magic to me, I didn't know I could construct it, return the yielded result, and use it in a with clause. 🪄