Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
de52643
feat(ol_types): add xqwatcher to Services and Application enums
blarghmatey Mar 11, 2026
c8d154a
feat(xqwatcher): update Vault policy to include xqueue credentials path
blarghmatey Mar 11, 2026
3f6c0ca
feat(xqwatcher): replace EC2 ASG deployment with Kubernetes Deployment
blarghmatey Mar 11, 2026
fb44413
feat(xqwatcher): update all 9 stack configs for Kubernetes deployment
blarghmatey Mar 11, 2026
5613460
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 11, 2026
1eedc5e
fix(xqwatcher): address PR review feedback and deployment issues
blarghmatey Mar 18, 2026
3b62704
chore: Use xqwatcher image from dockerhub pull-through cache
blarghmatey Mar 18, 2026
0d21de1
fix(xqwatcher): use correct xqueue-watcher CLI arguments
blarghmatey Mar 18, 2026
105f767
fix(xqwatcher): enable automount_service_account_token on Deployment …
blarghmatey Mar 18, 2026
365d19b
fix(xqwatcher): reference container image by digest instead of mutabl…
blarghmatey Mar 18, 2026
738d91a
fix(xqwatcher): invoke entrypoint via uv run
blarghmatey Mar 18, 2026
763968b
fix(xqwatcher): pass --no-sync to uv run to skip dependency installation
blarghmatey Mar 18, 2026
950ebf2
fix(xqwatcher): fix config directory structure for watcher discovery
blarghmatey Mar 18, 2026
d2cd7bc
fix(xqwatcher): serialize confd_json to string before writing to Vault
blarghmatey Mar 18, 2026
e6a8d65
fix(xqwatcher): require XQWATCHER_DOCKER_DIGEST; remove docker_tag fa…
blarghmatey Mar 18, 2026
708b03e
feat(xqwatcher): rewrite ContainerGrader image through ECR pull-throu…
blarghmatey Mar 18, 2026
37ed37b
ci: suppress CodeQL actions extractor failure
blarghmatey Mar 19, 2026
273bb96
feat(concourse): add reusable grader image build pipelines
blarghmatey Mar 19, 2026
02460a5
fix(concourse): track current working branches for grader image pipel…
blarghmatey Mar 19, 2026
f8c786c
fix(concourse): set build context to repo root for grader base image
blarghmatey Mar 19, 2026
1a3cc07
feat(concourse): ensure ECR repositories exist before pushing grader …
blarghmatey Mar 19, 2026
0198734
fix: pass repo-name-only to registry-image ECR resources
blarghmatey Mar 19, 2026
0e0e8d0
fix: track feature branch in meta pipeline pipeline-code resource
blarghmatey Mar 19, 2026
21929ee
feat: use SSH credentials for private grader repository access
blarghmatey Mar 19, 2026
6a8e14e
fix: use odlbot SSH key for private grader repo access
blarghmatey Mar 19, 2026
7c66896
fix: use DockerHub grader base image as build trigger
blarghmatey Mar 19, 2026
ff13341
feat: wire XQWATCHER_GRADER_* env vars and fix ECR image rewrite
blarghmatey Mar 19, 2026
0f8f7f5
config: Update MITx CI watcher config for use on K8s
blarghmatey Mar 19, 2026
5e38539
config: Get grader path to strip erroneous prefix
blarghmatey Mar 19, 2026
23298ed
fix: Set proper grader root for dockerized graders
blarghmatey Mar 19, 2026
3392b9f
fix: Don't strip path components either
blarghmatey Mar 19, 2026
a4fc006
fix: Update mitx CI watcher password to match xqueue
blarghmatey Mar 20, 2026
94edcd7
feat(xqwatcher): migrate grader config from SOPS/Vault KV to Pulumi c…
blarghmatey Mar 20, 2026
41b0aba
fix: address PR review feedback
blarghmatey Mar 20, 2026
7811043
feat(xqwatcher): add Docker+Pulumi Concourse pipeline
blarghmatey Mar 20, 2026
db24a45
fix: address remaining Copilot PR review feedback
blarghmatey Mar 20, 2026
f5eb04a
Add graders-mit-686x image build pipeline
blarghmatey Mar 20, 2026
d1f4d77
Delete .github/codeql/codeql-config.yml
blarghmatey Mar 20, 2026
d001f6e
Add 686x ContainerGrader to mitxonline production stack
blarghmatey Mar 20, 2026
ab4683a
Add edxorg xqueue server ref for 686x grader
blarghmatey Mar 20, 2026
0d529f8
feat(xqwatcher): surface new security env vars and add pod seccomp pr…
blarghmatey Mar 23, 2026
12ffdca
fix: address unresolved PR review feedback
blarghmatey Mar 23, 2026
a9df683
Apply suggestion from @Copilot
feoh Mar 24, 2026
f5ffad6
chore: Update watcher pipeline
blarghmatey Mar 24, 2026
1ac0e76
feat(xqwatcher): add HPA for CPU/memory-based autoscaling
blarghmatey Mar 24, 2026
5148008
feat(xqwatcher): separate edxorg server into its own Deployment
blarghmatey Mar 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 23 additions & 37 deletions src/bridge/secrets/xqwatcher/secrets.mitx.ci.yaml
Original file line number Diff line number Diff line change
@@ -1,65 +1,51 @@
---
graders_yaml:
graders:
- name: ENC[AES256_GCM,data:p5T9MPzwVzB2SmsbB7kFcEuBlR9HJGbyPVZw,iv:iFC4JC+oyLBtKH06ZGKOLdZDEleN2f9j4iXJxQpwWt8=,tag:588sITOlP+vcF66ohqyRLw==,type:str]
address: ENC[AES256_GCM,data:0ZoJISrNH1Y/fcbioWNDlvNpPzELSdN+jZolfqYOkWlYOnzufqUMlQ==,iv:OTS2obQKZd/yJray6BxhpOKEaOamXQf2RdsZibHklSc=,tag:Jusz+4i6wysepofR9M0mQA==,type:str]
git_ref: ENC[AES256_GCM,data:M5tIe1zv,iv:yB5QnVIDuBmYauTQzx6rzLwQNd6V+t15DUcAirIDySI=,tag:SsgXOI1nmtqfkhmCgVJbrg==,type:str]
env:
GIT_SSH_COMMAND: ENC[AES256_GCM,data:/tHzs53lMHrUmndEgR0jOhOPW0ned4A1USAZ2j9jLM+4KYjPKlicXEeWnOKL7wAwNZnlpN7O+iD0tE3UjkfkCrF9+MMMjzeh6Cxi7HjaX8B7yNVGXpt3CMBbVIduza0Qta6bqo0Ixao1xID4jhq2Hx/K0XTGHr8sq1WDo5RWjhgNni0HrYfQ7LCAT4/h8pNR,iv:3JZxMQWw95j4KGAL/bMqTo+irhdtlDEpVJjPrkK/IWQ=,tag:Uh0vwfZzZVN8nkxz0V6lDw==,type:str]
- name: ENC[AES256_GCM,data:guJV2vkSNpqaWWnlQgOoZhGXzLpPekf+GZABiO4=,iv:IJIIE0cFWPEhwcWKBQtcPGnv5XF4vy8ENEjETpIrnWc=,tag:lc82HaHmcJSy7Waxv7WN2Q==,type:str]
address: ENC[AES256_GCM,data:0ZoJISrNH1Y/fcbioWNDlvNpPzELSdN+jZolfqYOkWlYOnzufqUMlQ==,iv:OTS2obQKZd/yJray6BxhpOKEaOamXQf2RdsZibHklSc=,tag:Jusz+4i6wysepofR9M0mQA==,type:str]
git_ref: ENC[AES256_GCM,data:M5tIe1zv,iv:yB5QnVIDuBmYauTQzx6rzLwQNd6V+t15DUcAirIDySI=,tag:SsgXOI1nmtqfkhmCgVJbrg==,type:str]
env:
GIT_SSH_COMMAND: ENC[AES256_GCM,data:/tHzs53lMHrUmndEgR0jOhOPW0ned4A1USAZ2j9jLM+4KYjPKlicXEeWnOKL7wAwNZnlpN7O+iD0tE3UjkfkCrF9+MMMjzeh6Cxi7HjaX8B7yNVGXpt3CMBbVIduza0Qta6bqo0Ixao1xID4jhq2Hx/K0XTGHr8sq1WDo5RWjhgNni0HrYfQ7LCAT4/h8pNR,iv:3JZxMQWw95j4KGAL/bMqTo+irhdtlDEpVJjPrkK/IWQ=,tag:Uh0vwfZzZVN8nkxz0V6lDw==,type:str]
confd_json:
Watcher-MITx-6.00x:
AUTH:
- ENC[AES256_GCM,data:SCKbOmao2Gpl,iv:Hb7ZVtcobrj2E6hFBrmqVpq1oNnJ+j2YOQMcfLFN6Dc=,tag:3rvoooddYT3G04AQOsKxEA==,type:str]
- ENC[AES256_GCM,data:/FqGfC4XbHZ2AIaJiUHJA+hebqDA4eag+qwjiG2lywpzOOMJIwblQw==,iv:dmDX989O8vyVtgfcCcSG1IPoX/+Vy/CHifk+4omnwV8=,tag:QFkUcAaojGs/+c+5h3r5lg==,type:str]
- ENC[AES256_GCM,data:huly/No4UkykZIlKre7Lr5bJLH+4zmha3gS7m9bFbXO85TF/QPUpAg==,iv:CMds+DvCv7E9qyAlgxRvO2XAxkX4wso/21Q9zXQrf8I=,tag:xcsHlo32rScjVagNmndv8Q==,type:str]
CONNECTIONS: ENC[AES256_GCM,data:Gg==,iv:d7E2fNOoSSflC2UNEnIUg9bBCHI3rlbn8pgmHCnxX68=,tag:5V0iQ94DuAdt0+zxQXV39A==,type:int]
HANDLERS:
- CODEJAIL:
bin_path: ENC[AES256_GCM,data:kXgOjRNdv5RNXL2JcleS3u/W2FUelW/OWS6u9Dd3ASC2mOxHMAjxQK0VoivVPj0ZqSzlqhxFPg21sg==,iv:jtm/LiMJapsXJEIZGgOzknJ/Nmd9zFofyNtQG4jJLHs=,tag:gIBJjPWkIydCIzoan9V6kw==,type:str]
lang: ENC[AES256_GCM,data:vxjPnbN7oQ==,iv:m25r3jtmoUjIWYDKyKUX82awfO98K9UdFPzUGlmdcF4=,tag:8yMYlavG9/pPCzIl5prLcg==,type:str]
name: ENC[AES256_GCM,data:1ISqevS5v+s=,iv:pX1qlTFPdlrgqP16/Vm9OGJ/hKnuMScGwjJ3M+YWeA4=,tag:d88eMeekFkpm0mRbNy741A==,type:str]
user: ENC[AES256_GCM,data:jiWGB4mhGX4=,iv:WOiO7BPAsvjl9tQz8NwLLTYcCi/XwcixYei6ybWiDYg=,tag:yGfU4XhPE0hkkVFM3c3Hcg==,type:str]
HANDLER: ENC[AES256_GCM,data:xKNmClln1J5leWUOsHXo6d0XMm+tNAN9bek4soM5b49o6zLbv3s8TQ==,iv:kZ7jGM5B4n2RsOCppRTt0Cn8TDH2sSnAOuYbQl95dY4=,tag:OTw+Y0uhByeYXY8eP13dqw==,type:str]
- HANDLER: ENC[AES256_GCM,data:SUKLJX/arQHo7OMbzoOCQgqACuwEDVgJVJ0HGqbLWbDZR3u6dK6zvxJUrNVM7w==,iv:JRwutReGuNwudxa6sRZVLZjx34ZaiVqAQSmwdUgn5AI=,tag:w4hyFq+uznC/+u1uciYlwQ==,type:str]
KWARGS:
grader_root: ENC[AES256_GCM,data:A+hHIVLX0mTz1DHc7MMmVAf60hQ/EJjgzG5h9lnZppBLZIscVvhyryczyTS+RKimzqWQQYTT32FAsqYqvtI=,iv:dIMitVcAwebHlO3LRKoD13dVkMkuL2z6rX/gJbuGxKc=,tag:HDCOyEUMMK1/ErgXk6q7Kw==,type:str]
SERVER: ENC[AES256_GCM,data:fgyBM4dTnNCyUgb0O/nruyu5WgsGEZaYGHP+oV/Qi7llIUkOFDN9sQY=,iv:7GIz4gNKMqINA+i1WzGfEvptip3vLo6XnA/EScQbEy4=,tag:tjyrPKIx9dONJMgb6vyIPQ==,type:str]
grader_root: ENC[AES256_GCM,data:yW8aK1I4cgoeu/mWBVZic2lPPtFekwuG,iv:+Xp/VtAeSF843ov2dx9XMrTKvRPTZ0sSxt44abcg5so=,tag:SRC0qFcYk1X2XBF4OqpENg==,type:str]
image: ENC[AES256_GCM,data:K/smElRfcbDfioQwlbSO7nMoW7yI39IzNFY2TvSgrWNaFqo5MnZSnyFOPC021WzHRZWMdQR1kTLB2zImRZuFZcEcnN0XNyHPiYrL,iv:Zikm+Z2QR4b7UEXrfrQvGh5EdywYPYxUL0lSECx7chQ=,tag:SeUO/AQmu6/eolH3+jmAYQ==,type:str]
backend: ENC[AES256_GCM,data:Xhkvv02Rh5aNkw==,iv:ZN1iF4gQ7Krm99YjrrWkWbWC3PYROk9gsOqFmqS3X/E=,tag:klNdz4BlVdHTnT8sOQ8/dA==,type:str]
cpu_limit: ENC[AES256_GCM,data:47Kuqa8=,iv:uZRate/HQzNH0QggGZdzguU0vZxxS5M8WYRcXUnQvo8=,tag:XnCarT23s5qOsbMim4Xs+A==,type:str]
memory_limit: ENC[AES256_GCM,data:hpEAzVQ=,iv:K9Uz/YVxopA7x6amvG9GMzuvsBssTYdrFt0O8qfdcnU=,tag:XIg9CpujBmzCM/fFebxIjA==,type:str]
timeout: ENC[AES256_GCM,data:jV0=,iv:pw+yw/Wzt0rtnoJmwnXzETb2bCeeGnD/nNHRq/FJH20=,tag:hwUcPI6in9/Yvqea7Hxn4Q==,type:int]
image_pull_policy: ENC[AES256_GCM,data:XiQx6roJ,iv:pORRAsnjXxV/c2cHzepkSVgs18hhkHAAtOT/Npv9lME=,tag:VgUaG0Uqmj5JWo+iWujolw==,type:str]
SERVER: ENC[AES256_GCM,data:9+nHYHNrnrHmTw0UqzyvU4CoC0YeLPE4wQb5eTWFMXb0yw==,iv:NdCWF86cPGN180Puc6y37cuhV1H0vsMZgQBEG6zLUTg=,tag:VjWyEn/Bve29esECOBMotg==,type:str]
Watcher-MITx-6.0001r:
AUTH:
- ENC[AES256_GCM,data:GeoKMl2An+NT,iv:4bpjXM5pBTGk43L4aFffe/i7Xuiqqma4x1bjwqr2vZc=,tag:cRJlbd1X9ScKyIMXc56Mng==,type:str]
- ENC[AES256_GCM,data:2IRNwrwVNeQ/N5B3Ka0E8JKa2rMoY+g1h078CWy82O0EYrsfUAEIxw==,iv:sl5rkCOZxVIM2xkgAHvsg9wPl4arEOm7NTq4B67Dz5s=,tag:dpxlezEbjFndERvvvGQSkQ==,type:str]
- ENC[AES256_GCM,data:VKQGDGtNq+FQVFLFO6IHxos/nHs+GHihFZND/mnUngNFGSLj+NSi5w==,iv:Obb9DEHraRwAf/nCaWKyFJh5wK3dTL3gzwkEDVbhV7M=,tag:HXrvSTWBPuH9vPiFKLBQKA==,type:str]
CONNECTIONS: ENC[AES256_GCM,data:0g==,iv:6tyg9WvnRhnpLm0vKGefnd70VfpmEFy0ErgwnNiFSAU=,tag:fl01agv/QL6uosiMu0rDzA==,type:int]
HANDLERS:
- CODEJAIL:
bin_path: ENC[AES256_GCM,data:lsEJDjU3WT6woU5bptLcYR1wXqWdWUfTg95Rsi+KBHbJgB2WCSApOL4NokZErBfF9b2Gp6Oo8lbTnw==,iv:A2I+IE3Sb2sMMt3jzwQahVeHVVSKFegWe4lOYq7d+kA=,tag:fcR1QNOhmBa60VW62XcEwg==,type:str]
lang: ENC[AES256_GCM,data:UkMtJmLV7w==,iv:pbuB6D7FVuwpjJU8Aq/94McxvrADBG6q9NK1dInRaWA=,tag:keZqRH/pnb7hJGK/5IB6Dw==,type:str]
name: ENC[AES256_GCM,data:FNj9NpiNTLA=,iv:/NO4SppIdQ2sk4b4v0yFy5uhUA6xJe3Ln4CcbNOwoYQ=,tag:kPIcKyFzwlXawgYNuEFGQg==,type:str]
user: ENC[AES256_GCM,data:AgacvZvMofI=,iv:M8eB7g7NIieNs+WeQjemUfcyYiPxRSsxdQhKCHcehLg=,tag:kEFkDWkdhqWhrkSVnpPjRg==,type:str]
HANDLER: ENC[AES256_GCM,data:ptWfCuhtmp1XaCxZsxoyFryVbS82cJkYLOgeTfI883Abtal/nUK58g==,iv:Y2vuOaLH94pc9iY0V6qUfmlj9m3ijK/vxnyljFhBC4w=,tag:dBe2y1yG4y/MDqKeUlobow==,type:str]
- HANDLER: ENC[AES256_GCM,data:GxcBCI9x7tzIoP+2Ssgz92doSvmldQtDDx6Jl9duFWcXP/bwRKodTLfYDEwmaw==,iv:AXZJHneW4i1z90TK7SIr6WOG7HLz4EvSP2o0rWALMIM=,tag:5iOqnbcO53qOcgWYRS3O9Q==,type:str]
KWARGS:
grader_root: ENC[AES256_GCM,data:6UFR02eSi21NXOU6SQcZyRm3SbFqgMXV4yJiMTW8+lMiVRfRVyz0cFnQjFEAlwflHxgWgXNymHNTkxYFzSUpUw==,iv:AiEGSD68isqsL0Ften6dn+/DTpHfdbUGwBN5vdBd1w8=,tag:lCXfJNrV9hkrSRxFVesPsQ==,type:str]
SERVER: ENC[AES256_GCM,data:FHHp0nXRKUsYrfccjmv0TF1Qb6ms7sCRnvA/V2Pm0snJznW/YA66LRo=,iv:7l7VZyh2wyVT7q1j43fIWdDBsODzK9IGGZt9+D+Z55I=,tag:8zW+XIdqJjuuN2QY3ndSgg==,type:str]
xqwatcher_grader_code_ssh_identity: ENC[AES256_GCM,data:2ogEHew5oYkdHOhn/Td92T0tLF59cC0ts6kQddqEgUu/7/cSadFoGvb9RfS4TUOzhAARnMdMRT5JclXlp4Oi8T0X2nenAM/zZkokd5GMmC0J2mESCm2bbdXcG2qat9Rjga7d+1bLyP1+1heIHPb5uRsGJYkA87d1bvv8vlmwtEQN3VeBrD/0I+jwTUcLamVg4T602RxWMnEm9nXw0NTDUp4TsOMtIrzdBvs9IsNEqdDT7hwSkHpmC69dulUJzJGOSFYmkYFHcDAK8qTRdc8qp5vvMTz4k7X8JF8yp7LfEGuE5w==,iv:c2o8vAGEB8DFq9VtW8Zhm5Xat4s49x+oQf7212ZeFFk=,tag:9gI1u/SBMIjLDfY3b1X8+w==,type:str]
grader_root: ENC[AES256_GCM,data:IOvzEu688/L+NAhVumJegc8hY8Gq0JSR,iv:aBiBcv3PXlV4ZAAE+v44tjCgTNoWblQsvSyXBWu99VY=,tag:/+Tw3yjQyBNc1iDhnvmqQg==,type:str]
image: ENC[AES256_GCM,data:xbI2u7mnzujef23MXabbxrTtqFzlM6SoH8koIHvJhsViugeRGYMQTpd7gLaShLLJDPGMoQ/8MGuNuZp1IY1Rn+xoFGE8W5owiYHu,iv:hIn5E/VXuPuunHkxUkFoMhWeUw8Ex+x+pfHN+cTxf/8=,tag:EMY867H0qn83N5v0OpnDrg==,type:str]
backend: ENC[AES256_GCM,data:OaGBiwiRT0m/Pg==,iv:RBUzueYrobo6vv2LXXhTMPEY8q7ZvkDN86x8fBc4lOU=,tag:hqS+ZaFHjs0xhTO5ldc6pw==,type:str]
cpu_limit: ENC[AES256_GCM,data:FjtcqBs=,iv:/4awwScRxzctMgesO+Akjh+xawRxjQYM6FwctaUr6to=,tag:HLUnAYyAhknuBQXTRHs3ng==,type:str]
memory_limit: ENC[AES256_GCM,data:gISNMOg=,iv:y842XxT45ipoWCXrLO5Pjh6WgqtUyZ9qRfkCWfVx/6E=,tag:sdMFIVYXzUj9LeOA2XXnIg==,type:str]
timeout: ENC[AES256_GCM,data:KYY=,iv:YiBTO75tTrTB8N1sjLPA0YTJX48sls7EppkfmsYAbWg=,tag:vHJR93RPrWf+qtt7+aEIOA==,type:int]
image_pull_policy: ENC[AES256_GCM,data:++zPPhK8,iv:0mPD6jGWeGVsEGxmCeiJxyE9wYz0vMqVtLLYCguLg0s=,tag:ounenzLmuxsYg9tYsm86wg==,type:str]
SERVER: ENC[AES256_GCM,data:ScOVWtueEbmPj/cA42MlN58fxYYKjBWGh982ebrLp6qbaQ==,iv:uOWEPN5qBeZ9Yw6xr7hfZ6GWzgYGBYZkBFsvM0sfzyg=,tag:SyNl6UGl6yilFPNVqa1aGg==,type:str]
sops:
kms:
- arn: arn:aws:kms:us-east-1:610119931565:alias/infrastructure-secrets-ci
created_at: "2024-04-16T18:44:13Z"
enc: AQICAHjnbqe9AmEW1Js10nySybyuAG7Fb5E9EHUgkmqFDv7PxQGybcfmnUvB5N3pkXc+9ch5AAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM/4CSiwztDCKuyN3oAgEQgDvUtEGftvJN4EzTdnZS00yMzsZhgmq3lCXovEvM6fFJFBZYZjGAeKZYnhW69ITlOIUi8K4iZmlUy9eQFw==
aws_profile: ""
gcp_kms: []
azure_kv: []
hc_vault:
- vault_address: https://vault-ci.odl.mit.edu
engine_path: infrastructure
key_name: sops
created_at: "2024-04-16T18:44:13Z"
enc: vault:v1:DFw1gsayFWeGxTCrU0HCQzWk4YBPHQdKHpValoIHi4bO/jHn+eZv+Nr2d4FubYiq8jKrKREm/UgsizDS
age: []
lastmodified: "2024-04-25T18:35:23Z"
mac: ENC[AES256_GCM,data:X4CfjxG/ps13sYRd2PzeXl0MLz0pxkSKky23dIN/PmsH1xyhPnVXQ8wMV85vjN55LrGcSHs9GWAlJjqna43apnoggHfdqO/bYUeHhUjUJ8RiqXTFCi9NfRkCq5x1upmiXTR95fKdZUrykFZTGx+8JvTWLjs+2HfgHWL0kDk1HDU=,iv:RVkdd8V9rHgFbMP7ZqormU7TYXF2uwe46QCKHpmhi8E=,tag:xEdvYfirIpM/rwhKDAouHw==,type:str]
lastmodified: "2026-03-20T15:27:59Z"
mac: ENC[AES256_GCM,data:YuUS49U2swqS76nxsRcSxx3/66S4qxedfZeGyBKH3MsZRNCwy4BdP5xa45CwLT6xH/sWIoJPo6Drw7ECekY+wdjwqV2cM7hCtD+kH8CVqkx4CCIUNBvQyYY+d4bdiaSdty75pGgYQzD090AKtcE5acFMF3K/wrmYTPWzh8hBDRw=,iv:quJO4m+SuoiVPTAncLYJUl0jJhBWg64Abwp/oXeN9Hc=,tag:pHFGW/Prf8A2aYf2kCmSIQ==,type:str]
pgp:
- created_at: "2024-04-16T18:44:13Z"
enc: |-
Expand Down Expand Up @@ -142,4 +128,4 @@ sops:
-----END PGP MESSAGE-----
fp: 3582AE9F12CE295BDAF545ED17A5F53F11681446
unencrypted_suffix: _unencrypted
version: 3.8.1
version: 3.12.2
42 changes: 42 additions & 0 deletions src/ol_concourse/lib/containers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ol_concourse.lib.jobs.infrastructure import Output
from ol_concourse.lib.models.pipeline import (
AnonymousResource,
Cache,
Command,
Identifier,
Expand Down Expand Up @@ -35,3 +36,44 @@ def container_build_task(
outputs=[Output(name=Identifier("image"))],
),
)


def ensure_ecr_task(ecr_repo_name: str) -> TaskStep:
"""Return a TaskStep that creates an ECR repository if it does not exist.

Uses the AWS CLI with instance credentials (IRSA / worker IAM role).
Safe to run on every pipeline execution: ``describe-repositories`` is a
no-op when the repo already exists, and ``create-repository`` only runs
when it does not.

Args:
ecr_repo_name: The ECR repository name *without* the registry host,
e.g. ``"mitodl/graders-mit-600x"``.
"""
return TaskStep(
task=Identifier("ensure-ecr-repository"),
config=TaskConfig(
platform="linux",
image_resource=AnonymousResource(
type="registry-image",
source={"repository": "amazon/aws-cli", "tag": "latest"},
),
params={
"REPO_NAME": ecr_repo_name,
"AWS_DEFAULT_REGION": "us-east-1",
"AWS_PAGER": "cat",
},
run=Command(
path="sh",
args=[
"-exc",
(
"aws ecr describe-repositories"
" --repository-names ${REPO_NAME}"
" || aws ecr create-repository"
" --repository-name ${REPO_NAME}"
),
],
),
),
)
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""
Pipeline that builds the xqueue-watcher grader base image and pushes it to
both DockerHub and ECR.

The base image (grader_support/Dockerfile.base) is the foundation for all
course-specific grader images. Publishing it to both registries allows:
- DockerHub (mitodl/xqueue-watcher-grader-base): public reference usable
without AWS credentials; used in grader repo Dockerfiles as the default
GRADER_BASE_IMAGE build arg. The per-grader Concourse build pipelines
trigger off this DockerHub image so a base image rebuild automatically
triggers downstream grader image rebuilds.
- ECR (mitodl/xqueue-watcher-grader-base): private mirror for use inside
AWS without DockerHub rate-limit concerns.

Triggers:
- Push to the xqueue-watcher repo on paths under grader_support/.
"""

import sys

from ol_concourse.lib.containers import container_build_task, ensure_ecr_task
from ol_concourse.lib.models.fragment import PipelineFragment
from ol_concourse.lib.models.pipeline import (
GetStep,
Identifier,
Input,
Job,
Pipeline,
PutStep,
)
from ol_concourse.lib.resources import git_repo, registry_image

_AWS_ACCOUNT_ID = "610119931565"
_AWS_REGION = "us-east-1"
_BASE_IMAGE_REPO = "mitodl/xqueue-watcher-grader-base"


def grader_base_image_pipeline() -> Pipeline:
"""Return the pipeline that builds and publishes the grader base image."""
xqwatcher_repo = git_repo(
name=Identifier("xqueue-watcher-code"),
uri="https://github.com/mitodl/xqueue-watcher",
branch="main",
paths=["grader_support/"],
)

# DockerHub push target — public, used by grader repo Dockerfiles as default
# GRADER_BASE_IMAGE build arg and accessible without AWS credentials.
dockerhub_base_image = registry_image(
name=Identifier("grader-base-dockerhub"),
image_repository=_BASE_IMAGE_REPO,
image_tag="latest",
username="((dockerhub.username))",
password="((dockerhub.password))", # noqa: S106
)

# ECR push target — private mirror for use inside AWS without DockerHub
# rate-limit concerns. The per-grader Concourse build pipelines trigger
# off the DockerHub base image (grader_base_dockerhub_repo), not ECR.
ecr_base_image = registry_image(
name=Identifier("grader-base-ecr"),
image_repository=_BASE_IMAGE_REPO,
image_tag="latest",
ecr_region=_AWS_REGION,
)

build_job = Job(
name=Identifier("build-grader-base-image"),
plan=[
GetStep(get=xqwatcher_repo.name, trigger=True),
container_build_task(
inputs=[Input(name=xqwatcher_repo.name)],
build_parameters={
"CONTEXT": str(xqwatcher_repo.name),
"DOCKERFILE": (
f"{xqwatcher_repo.name}/grader_support/Dockerfile.base"
),
},
),
ensure_ecr_task(_BASE_IMAGE_REPO),
# Push to DockerHub first — fail fast if credentials are wrong
# before consuming the ECR push quota.
PutStep(
put=dockerhub_base_image.name,
params={
"image": "image/image.tar",
"additional_tags": f"./{xqwatcher_repo.name}/.git/describe_ref",
},
),
PutStep(
put=ecr_base_image.name,
params={
"image": "image/image.tar",
"additional_tags": f"./{xqwatcher_repo.name}/.git/describe_ref",
},
),
],
)

fragment = PipelineFragment(
resources=[xqwatcher_repo, dockerhub_base_image, ecr_base_image],
jobs=[build_job],
)

return Pipeline(
resource_types=fragment.resource_types,
resources=fragment.resources,
jobs=fragment.jobs,
)


if __name__ == "__main__":
pipeline_json = grader_base_image_pipeline().model_dump_json(indent=2)
with open("definition.json", "w") as definition: # noqa: PTH123
definition.write(pipeline_json)
sys.stdout.write(pipeline_json)
sys.stdout.write(
"\nfly -t <target> set-pipeline -p build-grader-base-image -c definition.json\n"
)
Loading
Loading