Repository navigation
v0.18.0
v0.18.0
APT Proxy v0.18.0 adds complete offline repository snapshots, verified runtime mirror failover, persistent cache integrity, resource admission, explicit shared Unix disk coordination and a real APT client matrix. Review the upgrade notes below before deploying.
New capabilities
- Complete repository snapshots and offline maintenance.
apt-proxy repository prefetchcollects the selected suite, components,
binary architectures and optional Sources indexes, plus every referenced
object. Sizes and SHA256 digests are verified before atomic publication.
verify,repair,export,importandserveoperate on that complete
selected set. Offline serving never falls back to the network. APT continues
to verify the preserved repository signatures and expiry.
See snapshot commands and limits. - Snapshot-checked runtime mirror failover. Optional
mirror_health
mappings allow bounded switching among operator-approved equivalent public
Debian-family archives. Replacement metadata must match every current,
fully observed Release/InRelease fingerprint. Unknown, expired, divergent or
private snapshots cannot switch. Probes have bounded time and size; status is
available throughGET /api/mirrors/statusunder the existing management API
authentication policy. This is
metadata equality checking, not a PGP verifier or an atomic repository snapshot.
See runtime mirror health. - Persistent cache integrity.
cache.integrity: sha256is now the daemon
default. Private records bind body digest/length, request key, status, headers
and generation. Damaged records become misses without removing a concurrently
published replacement. Verification also applies to S3 and survives restart.
See integrity and storage I/O costs. - Real APT client compatibility tests. Debian Bookworm/Trixie and Ubuntu
22.04/24.04 run signed update, installation, source downloads, SHA256 by-hash,
asserted gzip fallback, ranges, retries, interrupted transfers, authenticated
HTTPS and imported offline snapshots. The runner supports digest-pinned and
long image references, rejects colliding evidence identifiers before cleanup
and uploads failure evidence in CI. These fixtures do not establish universal
public-mirror compatibility. See client matrix. - Shared temporary-storage and download admission. One per-process budget
covers unknown-length spools, HTTP cache response copies, native publication
stages and S3 inline/spilled payloads. Known-length downloads also obey object
and active-download limits. Disk admission preserves free-space headroom.
See resource limits. - Explicit repository identity and shared Unix disk coordination. Public
SHA256 by-hash indexes can share identity across explicit repository roots
only after the body matches the requested digest. Kernel file locks coordinate
cache publication and miss followers across processes; durable invalidation
barriers preserve newer generations. Packages and mutable metadata retain
per-process identities when coordination is enabled. Private requests never
join the shared cache. See configuration and maintenance.
Correctness and dependency updates
- Own detached request metadata before Fiber/fasthttp reuses its request buffers,
preserving URL fields, headers, Vary selectors and caller values/deadlines
throughout asynchronous publication. - Cancel in-flight upstream work at application pre-shutdown, before connection
draining and cache teardown. Reuse cancellation domains for requests with the
same caller lifetime without accumulating one callback per completed request. - Recheck coordinated cache fills without counting internal retries as extra
native hits/misses. Keep integrity and invalidation checks on those rechecks. - Preserve replacement ordering, cross-instance header generations, full Vary
selection and client conditional semantics through the cache wrappers. - Keep GET length verification active for the released library's versioned Vary
keys, including ordinary retrieval and coordinated rechecks when integrity
digests are disabled; HEAD metadata behavior remains valid. A narrow bridge
retains recognized apt-cacher-ngHTTPS///rewrite markers with Fiber v3.6.0,
preserving ordinary routed-target slash/escape checks, download access
controls, stable cancellation contexts and streaming trailers. - Honor explicit
0cache size, TTL and cleanup controls supplied by CLI or
environment variables. Omitted controls keep the ordinary defaults of 10 GiB,
seven days and one hour; YAML nonpositive cache fields retain those defaults.
Disabling backend TTL does not override HTTP freshness or origin directives. - Replace interim cache/VFS commit pins with released
httpcache-kit v4.1.0
and vfs-kit v1.4.5. - Upgrade Fiber v3.5.0 to v3.6.0, MinIO's Go client v7.3.0 to v7.4.1,
and the indirect klauspost/compress dependency v1.20.1 to v1.20.3.
The Go toolchain remains v1.27.2. The release workflow pins GoReleaser v2.18.3
instead of following an unversioned tool installation. Other resolved
dependency versions are recorded in go.mod and go.sum.
Upgrade from v0.17.2
- Save the running binary/image reference and configuration. Stop the process
before making a consistent disk-cache backup. Keep a dedicated snapshot
directory separate from the daemon's disposable cache directory. - Plan for a temporary increase in origin traffic. Legacy entries without
private SHA256 metadata become misses and are lazily refetched. The private
isolation namespace excludes older potentially authenticated entries without
deleting their files. httpcache-kit v4.1.0 additionally versions its Vary
namespace: persisted legacy variants safely miss and rewarm; ordinary
non-Vary base keys are unchanged by that library migration. No manual purge
is required. Normal single-instance cleanup can retire unreachable objects. - Review the default verification cost. A hit reads the complete body before
response delivery, including HEAD; on S3 this can require a full object
transfer before the first byte is returned.cache.integrity: noneis an
explicit performance opt-out for ordinary mode. Enablingshared_cache
forces SHA256 integrity even with that opt-out. Digests detect accidental
corruption; an attacker able to rewrite records can recompute them, so APT
signature and package verification remain essential. - Review the new bounded defaults below. A large CUDA/kernel/toolchain artifact
exceeding the default object limit requires an explicit larger disk limit.
S3 is restricted to at most 5120 MiB per object for single PUT. Zero selects
defaults; it does not disable limits. The legacydownloadspool limits
remain additional bounds. Ifresources.total_temp_mbis omitted, an explicit
download.total_spool_mbsupplies the shared total. - Provision writable temporary storage even with S3. Inline payloads and their
overlapping spill copies consume the shared budget. This is a payload-copy
budget, not a total RSS or filesystem quota. HTTP buffers, bookkeeping,
persistent entries and other processes need additional headroom. Resource
counters are per process, even on a shared volume. - Enable optional features deliberately. Omitted
mirror_healthand
shared_cacheleave runtime failover and shared identities disabled.
repositoryis an explicit command with independent limits and a separate
store. Main YAML feature changes require restart; SIGHUP/API refresh reloads
distribution routing and resets mirror health after a successful election. - For shared Unix disk mode, stop and upgrade every sharing instance together
with identical repository policy. Keep cache/lock directories private on a
filesystem supporting process-sharedflock. Do not remove lock files while
an instance is running. TTL/MaxSize eviction, background cleanup and startup
stage sweeping are disabled; online global purge is rejected. Stop all
instances for cache/orphan maintenance. Shared S3/Windows coordination is
unavailable; isolate S3 instances with separate prefixes.
cache:
integrity: sha256
resources:
max_object_mb: 1024 # MiB; 1 GiB
total_temp_mb: 4096 # MiB; 4 GiB per process
max_active_downloads: 32
min_free_mb: 128
download:
max_spool_mb: 1024 # additional unknown-length spool bound
total_spool_mb: 4096
timeout_seconds: 1200 # 20 minutesAn active-download or shared temporary-budget refusal returns 503 with
Retry-After: 1; the legacy unknown-length spool sub-limit returns 502.
A cache-copy refusal after a complete upstream response skips publication
without discarding that response. Cache hits need no upstream slot. Cacheable
budget-controlled GET responses may report X-Cache-Staging as an HTTP trailer;
ADMITTED indicates staging admission, not completion of asynchronous commit.
Snapshot and private-repository boundaries
A snapshot includes every package/source object from the selected indexes, not
the solved dependencies of one package. Other suites/components/architectures
require their own selection. Optional translations, Contents, AppStream and
installer trees are outside this snapshot subset. Historical generations may
accumulate beyond one operation's total-byte bound.
Selected xz indexes require xz in PATH. The ordinary distroless image does
not contain it; build docker/Dockerfile.offline for the documented offline
image with xz and CA certificates. Prefetch/import/repair need a writable store
owned by the service account; serving an existing verified store supports a
read-only mount. Authenticated private origins are outside the snapshot command.
Authenticated live requests still forward credentials only to their configured
upstream and use no-store cache bypass. Optional mirror failover excludes them;
shared-cache participation also excludes unrecognized custom headers and bodies.
Configure trusted origins and any private-network access exceptions explicitly.
See private repository isolation.
Validation
PR #157 was validated at
ebca8a078756:
- The complete race-enabled Go suite passed with 82.9% statement coverage.
- All 12 CI checks succeeded, and the matching Codex review reported no
major issues with no unresolved review threads. - Six signed APT scenarios passed with one clean Go 1.27.2 Linux arm64
binary: Debian Bookworm/Trixie and Ubuntu 22.04/24.04 with public optional
policies enabled, plus Bookworm and Ubuntu 24.04 private-repository samples
with those policies active. Signatures and TLS verification remained enabled.
Repeated authenticated responses matched fixture bytes, carriedno-store
and never returned a cache HIT; proxy logs contained no fixture credentials. - The scenarios covered signed updates, tampered-signature rejection,
SHA256 by-hash, asserted gzip binary/source indexes, installation, source
retrieval, byte ranges, retries, interrupted transfers and imported offline
snapshots after the origin and normal proxy were stopped.
The release merge
1cd3f766f3fd
has the same source tree, 30f8797ec172b55b9a0cb0b914cde285775687a0, as the
validated PR head. The local scenarios use controlled Linux arm64 repositories;
cross-instance coalescing and runtime failover decisions are covered by separate
Go regressions. Other public mirrors and architectures require their own
validation.
Rollback
Keep the prior executable and configuration. Stop every sharing instance before
rollback, restore its compatible configuration, and use a separate old cache
directory/prefix or a quiesced pre-upgrade backup. Do not let old and new
instances concurrently write a shared store. Old versions do not understand
new integrity/coordination policies; rollback must not assume new private
records or Vary keys remain usable. Keep offline snapshot stores separate from
daemon cache maintenance.
Changelog
Features
- 2ca9f95: feat: bound download spooling and upstream fetch time (@soulteary)
- f1e3dee: feat: bound download spooling and upstream fetch time (@soulteary)
- 41ee247: feat: bound download spooling and upstream fetch time (@soulteary)
- d34401d: feat: bound download spooling and upstream fetch time (@soulteary)
- 40b6476: feat: bound download spooling and upstream fetch time (@soulteary)
- f951471: feat: bound download spooling and upstream fetch time (@soulteary)
- 3f89a9a: feat: cache bounded installer PXE and UEFI boot resources (@soulteary)
- 7764e9a: feat: cache common Debian-family installer boot files and manifests (@soulteary)
- 4a357e5: feat: configure download limits and document resource budgets (@soulteary)
- bbdc684: feat: configure download limits and document resource budgets (@soulteary)
- d57eb18: feat: configure download limits and document resource budgets (@soulteary)
- cf02c5d: feat: configure download limits and document resource budgets (@soulteary)
- 4495e7c: feat: configure download limits and document resource budgets (@soulteary)
- 44c378f: feat: coordinate verified repository by-hash cache across Unix processes (@soulteary)
- eed4fa1: feat: expand Debian-family repository index coverage (@soulteary)
- 7cd5fca: feat: expand Debian-family repository index coverage (@soulteary)
- 87cad07: feat: expand Debian-family repository index coverage (@soulteary)
- 5cf95b1: feat: guard package-download upstream hosts, ports and dialed addresses (@soulteary)
- 71ef8a3: feat: restrict package downloads by connection-peer CIDR policy (@soulteary)
- 5f56031: feat: route and cache versioned Debian-family source pool artifacts (@soulteary)
Bug fixes
- ed5c483: fix(ci): share non-default OtterIO integration credentials (@soulteary)
- fd668b6: fix(distro): match Contents pdiff indexes and patches (@soulteary)
- 27e0529: fix: acknowledge cleanup errors in failed download paths (@soulteary)
- db08e64: fix: apply repository cache defaults before cache storage (@soulteary)
- f32d17b: fix: apply repository cache defaults before cache storage (@soulteary)
- e79b319: fix: apply repository cache defaults before cache storage (@soulteary)
- 5e25989: fix: apply repository cache defaults before cache storage (@soulteary)
- 830d9c9: fix: apply upstream access policy to mirror probes and geo discovery (@soulteary)
- ef9ece6: fix: cancel detached repository work before server drain (@soulteary)
- 266450e: fix: clear APT evidence before compilation and container builds (@soulteary)
- aea960e: fix: clear completed empty replays when selecting a recovered mirror (@soulteary)
- 250ba46: fix: contain aborted downloads and verify unknown-length bodies (@soulteary)
- 9916953: fix: contain aborted downloads and verify unknown-length bodies (@soulteary)
- 4e8e4f8: fix: contain aborted downloads and verify unknown-length bodies (@soulteary)
- 51f9010: fix: contain aborted downloads and verify unknown-length bodies (@soulteary)
- 183d6b6: fix: contain aborted downloads and verify unknown-length bodies (@soulteary)
- 8e183f4: fix: count incomplete downloads and bound mirror replay headers (@soulteary)
- ef30926: fix: honor configured storage directories for download spools (@soulteary)
- 9ef27d0: fix: integrate reviewed staging dependency and safe disk admission (@soulteary)
- 1bca465: fix: isolate credential-bearing requests from shared repository caches (@soulteary)
- 5caf289: fix: isolate credential-bearing requests from shared repository caches (@soulteary)
- 011f75e: fix: isolate credential-bearing requests from shared repository caches (@soulteary)
- 675bb65: fix: isolate credential-bearing requests from shared repository caches (@soulteary)
- 9b1dcd7: fix: merge download limits through legacy configuration API (@soulteary)
- 69fe6a5: fix: own asynchronous cache requests and preserve retry accounting (@soulteary)
- 225d2e0: fix: pin reviewed conditional and Vary generation corrections (@soulteary)
- bd7745a: fix: pin reviewed integrity library and explain operator-owned imports (@soulteary)
- 55e2f21: fix: preserve client cache directives during repository routing (@soulteary)
- be5ab0b: fix: preserve client cache directives during repository routing (@soulteary)
- b790b42: fix: preserve explicit empty download ACL lists across YAML merges (@soulteary)
- 8c91cb1: fix: preserve healthy routes and bound repository method and spill lifecycles (@soulteary)
- 15d1e4e: fix: preserve upgrade deadline and half-close behavior (@soulteary)
- a1d0844: fix: preserve upstream trailers when spooling fixed-length responses (@soulteary)
- 6209990: fix: prevent unverified mirror errors from poisoning shared by-hash cache (@soulteary)
- e3d589c: fix: propagate configured mirror credentials before cache lookup (@soulteary)
- e8bc7f7: fix: race approved address families within a shared dial deadline (@soulteary)
- a8aee21: fix: recognize Ubuntu legacy installer image directories (@soulteary)
- 3754255: fix: reject cached body length mismatches and refetch complete objects (@soulteary)
- 5feffcd: fix: reject cached body length mismatches and refetch complete objects (@soulteary)
- fc91ddb: fix: reject cached body length mismatches and refetch complete objects (@soulteary)
- e68b8fc: fix: reject cached body length mismatches and refetch complete objects (@soulteary)
- 2f63071: fix: reject cached body length mismatches and refetch complete objects (@soulteary)
- 9784b8b: fix: reject invalid filesystem block sizes before resource admission (@soulteary)
- 5cb8b8c: fix: retain negative caching without repository freshness defaults (@soulteary)
- 578adaf: fix: retain spool reservations until cleanup succeeds (@soulteary)
Dependencies
- f4200ab: chore(deps): bump anchore/sbom-action/download-syft (@dependabot[bot])
Others
- e24be5e: Add bounded repository-verified runtime mirror failover (@soulteary)
- 5041c0a: Add complete repository snapshots and offline maintenance commands (@soulteary)
- d643e56: Bound all temporary payload copies and upstream download admission (@soulteary)
- 3cbb547: Fix late connection cleanup test timing and update cache validation dependency (@soulteary)
- 33e12c6: Fix private cache safety, diagnostics, and download spool cleanup (@soulteary)
- 9de4a7c: Merge main and reconcile OtterIO integration setup (@soulteary)
- bc4bf17: Merge the offline repository baseline and preserve integrity documentation (@soulteary)
- 6e8269b: Pin reviewed Vary semantics and test dependent PR branches (@soulteary)
- 68124e5: Redact complete repository credentials and address cache review feedback (@soulteary)
- 790efe7: Require private SHA256 verification for cache hits (@soulteary)
- 46ee432: Test actual signed APT clients and offline snapshots across Debian and Ubuntu (@soulteary)
- ebca8a0: Update stable dependencies and prepare v0.18.0 documentation (@soulteary)