Repository navigation
0.10.0-rc.3
Pre-releaseRelease candidate. Docker :latest and a plain pip install stay on 0.9.9 until 0.10.0 ships, so nothing moves unless you opt in. 0.10.0-rc.3 is 0.10.0-rc.2 plus the scopes-mode clone repack below. See the 0.10.0-rc.2 notes for the security fixes and the 0.10.0-rc.1 notes for the move to pydantic v2 and Starlette 1.x.
Scope clones stop growing without bound (#961)
This affects opal-server in scopes mode (OPAL_SCOPES=1) only.
The problem. The scopes git fetcher (pygit2 on libgit2) writes one pack file per fetch and never merges them. On repositories with many branches, a fetch can also re-download history the clone already has. A scope clone's disk usage therefore grows until the volume holding the clones fills up.
The fix. Once a successful fetch leaves a clone with at least OPAL_SCOPES_GIT_REPACK_PACK_LIMIT pack files (default 50), opal-server runs git repack -a -d -k on it:
- It merges the packs into one and drops the duplicate objects.
- It runs at the end of the sync pass, after the pass's notifications.
- A single-scope refresh repacks its own clone right after its sync.
- It never starts while another sync pass is running in the same process.
⚠️ Before upgrading opal-server in scopes mode
This is a behaviour change: repacking is on by default. To turn it off, set OPAL_SCOPES_GIT_REPACK_PACK_LIMIT=0.
Check these first:
- git: the
gitbinary must be onPATH. The official images ship it. - Memory: a repack takes about 0.5 KB per object of the repository, inside the opal-server container. Leave that room under the container's memory limit.
- On Linux, git runs with
oom_score_adj1000, so the kernel picks the repack first. - On Kubernetes with cgroup v2, an OOM kill takes the whole container. The clone is then left alone for an hour, so a repack that keeps running out of memory restarts the container at most hourly instead of in a loop.
- On Linux, git runs with
- Disk: git writes the merged pack before it deletes the old ones, so the volume needs room for one more copy of the largest clone's packs. On a Kubernetes
emptyDirwith asizeLimit, the kubelet evicts the pod when the volume passes the limit, so size the limit with that headroom. - Filesystem: repacks are serialized per pod with an
flockon the clones directory. It must be a local filesystem, or NFS mounted withlocal_lock=flock.
New settings and metrics
Settings:
OPAL_SCOPES_GIT_REPACK_PACK_LIMIT(default50): the pack count that triggers a repack.0or negative turns repacking off, and1counts as2.OPAL_SCOPES_GIT_REPACK_TIMEOUT(default120seconds): a hard limit on one repack.
Metrics:
opal_server.scopes.git_repack{outcome}- the
opal_server.scopes.git_repack_secondsdistribution opal_server.scopes.git_op_skipped, with reasonsrepack_runningandpass_in_flight
A clone whose repack failed is left alone for an hour by every process of the pod. An INFO line names it.
How to opt in
Docker: every image is published under the 0.10.0-rc.3 tag, plus -alpine:
permitio/opal-server:0.10.0-rc.3
permitio/opal-client:0.10.0-rc.3
permitio/opal-client-standalone:0.10.0-rc.3
permitio/opal-client-cedar:0.10.0-rc.3
permitio/opal-client-eopa:0.10.0-rc.3
pip: pre-releases are skipped unless you ask for them:
pip install --pre opal-client # or: opal-client==0.10.0rc3
pip install --pre opal-server