-
Bug
-
Resolution: Unresolved
-
Blocker
-
None
-
quay-v3.17.0
-
False
-
-
False
-
-
Problem
The organization-level mirror feature has broken no_proxy support in the discovery phase (repository listing via Harbor/Quay API), causing failures when trying to bypass proxy for specific hosts.
Status:
- Repository mirror: ✅ Works correctly
- Org mirror - Discovery phase (HTTP API): ❌ BROKEN
- Org mirror - Image copy phase (skopeo): ✅ Works correctly
Root Cause
File: util/orgmirror/registry_adapter.py:64-71
The _build_proxies() method builds a proxies dict for Python's requests library but ignores the no_proxy configuration:
def _build_proxies(self) -> Dict: """Build proxies dict for requests library.""" proxies = {} if self.proxy.get("http_proxy"): proxies["http"] = self.proxy["http_proxy"] if self.proxy.get("https_proxy"): proxies["https"] = self.proxy["https_proxy"] # ❌ MISSING: no_proxy handling return proxies
Affected adapters:
- harbor_adapter.py:78 - Harbor project repository discovery
- quay_adapter.py:121 - Quay namespace repository discovery
Technical Details
The Python requests library does NOT support no_proxy via the proxies dict parameter. It only reads no_proxy from environment variables NO_PROXY or no_proxy.
Comparison with repository mirror:
Repository mirror correctly implements no_proxy in util/repomirror/skopeomirror.py:166-176:
def setup_env(self, proxy): env = os.environ.copy() if proxy.get("http_proxy"): env["HTTP_PROXY"] = proxy.get("http_proxy") if proxy.get("https_proxy"): env["HTTPS_PROXY"] = proxy.get("https_proxy") if proxy.get("no_proxy"): env["NO_PROXY"] = proxy.get("no_proxy") # ✅ Works return env
Org mirror does reuse this skopeo code for image operations (workers/repomirrorworker/_init_.py:1376, 1583), so no_proxy works for image copying and tag listing via skopeo.
Impact
Severity: Medium
User Impact:
- Organizations cannot bypass proxy for internal/private registries during discovery
- All Harbor/Quay API calls are forced through proxy, even for .local or .internal hosts
- Workaround: Deploy proxy with passthrough rules (requires infrastructure changes)
Affected Scenarios:
- Harbor registry on internal network (registry.internal.company.com)
- Quay registry with split-horizon DNS (quay.local)
- Cloud metadata endpoints that should not be proxied
- Corporate networks with selective proxy bypass requirements
Recommended Fix
Set NO_PROXY environment variable in _build_proxies() method:
def _build_proxies(self) -> Dict: """Build proxies dict for requests library.""" import os proxies = {} if self.proxy.get("http_proxy"): proxies["http"] = self.proxy["http_proxy"] if self.proxy.get("https_proxy"): proxies["https"] = self.proxy["https_proxy"] # ✅ FIX: Set NO_PROXY environment variable # The requests library reads this, but not from the proxies dict if self.proxy.get("no_proxy"): os.environ["NO_PROXY"] = self.proxy["no_proxy"] os.environ["no_proxy"] = self.proxy["no_proxy"] # Lowercase for compatibility return proxies
Alternative (thread-safe): Use context manager to set/restore env vars
Testing Requirements
- Unit test: Verify NO_PROXY env var is set when no_proxy config provided
- Integration test: Mock Harbor/Quay API, verify requests bypass proxy for no_proxy hosts
- End-to-end test: Configure org mirror with no_proxy, verify discovery succeeds without proxy
Related Code
- Repository mirror (working reference): util/repomirror/skopeomirror.py:166-176
- Org mirror discovery: util/orgmirror/harbor_adapter.py:54-150, util/orgmirror/quay_adapter.py:93-182
- Org mirror image copy (works): workers/repomirrorworker/_init_.py:1366-1379
References
- Python requests library: Proxies documentation
- Repository mirror feature:
PROJQUAY-8414 - Org mirror feature: PROJQUAY-10040