* mirror: Add FEATURE_ORG_MIRROR feature flag (PROJQUAY-1266)
Add organization-level repository mirroring feature flag to enable
the new org mirroring functionality. Feature is disabled by default.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* mirror: Add GET endpoint for org mirror config (PROJQUAY-1266)
Implements the GET /v1/organization/<org>/mirror endpoint to retrieve
organization-level mirror configuration. Includes business logic layer
with get_org_mirror_config() and comprehensive unit tests.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* mirror: Add POST endpoint for org mirror config (PROJQUAY-1266)
Add create endpoint for organization-level mirror configuration:
- POST /v1/organization/<orgname>/mirror creates new config
- Validates robot account ownership and credentials
- Returns 201 on success, 409 if config already exists
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* mirror: Add DELETE endpoint for org mirror config (PROJQUAY-1266)
Add delete endpoint for organization-level mirror configuration:
- DELETE /v1/organization/<orgname>/mirror removes config
- Also deletes all associated discovered repositories
- Returns 204 on success, 404 if config doesn't exist
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* mirror: Add PUT endpoint for org mirror config (PROJQUAY-1266)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix test failure
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(pre-commit): match black version with requirements-dev
* run `make black` against repo
* ci: switch to black 24.4.2
* fix: py312
* fix: flake8 errors
* fix: flake8 conflicts
* chore: add git blame ignore revs file
* chore: update ci to use new large ubuntu 24.04 runner
Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-Authored-By: Dave O'Connor <doconnor@redhat.com>
* fix: add libfreetype6-dev for Ubuntu 24.04 compatibility
The reportlab package requires FreeType development headers to build.
On Ubuntu 24.04, this dependency is not pulled in transitively and
must be explicitly installed. This fixes the "cannot find ft2build.h"
build error.
Added libfreetype6-dev to all jobs that install system dependencies
in CI.yaml and CI-nightly.yaml workflows.
Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-Authored-By: Dave O'Connor <doconnor@redhat.com>
* chore: set the TEST_DATETIME to a static value
this caused an issue in xdist when generating test names
Signed-off-by: Brady Pratt <bpratt@redhat.com>
* chore: cache pip packages in CI
Signed-off-by: Brady Pratt <bpratt@redhat.com>
* chore: run registry tests with -n auto
Signed-off-by: Brady Pratt <bpratt@redhat.com>
* chore: run psql with -n auto
Signed-off-by: Brady Pratt <bpratt@redhat.com>
* chore: add file locking to prevent parallel test db init race condition
When running pytest -n auto with multiple workers, both workers would
simultaneously execute populate_database(), causing duplicate key
violations on shared tables like imagestoragelocation:
Worker 1: Check if User "devtable" exists → No → Start populating
Worker 2: Check if User "devtable" exists → No → Start populating
Both: INSERT INTO imagestoragelocation (name) VALUES ('local_eu')
Result: IntegrityError - duplicate key violation
Solution: Wrap init_db_path fixture with FileLock to ensure only one
worker initializes the database at a time. The lock file is created
in pytest's shared temp directory, coordinating across all workers.
- First worker acquires lock and populates database
- Subsequent workers wait at lock, then see database is already
populated (via User.get() check in populate_database())
- Works for both PostgreSQL and MySQL
- 300-second timeout prevents deadlocks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: run mysql with -n auto
Signed-off-by: Brady Pratt <bpratt@redhat.com>
---------
Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Dave O'Connor <doconnor@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
fix(api): implement proper superuser permission model and fix access controls
Fixes multiple issues with superuser functionality and implements a comprehensive
permission model for FEATURE_SUPERUSERS_FULL_ACCESS:
**Permission Model:**
- Global Readonly Superusers (auditors): Always have read access to all content,
independent of FEATURE_SUPERUSERS_FULL_ACCESS setting
- Regular Superusers: Can access /v1/superuser endpoints and their own content.
Require FEATURE_SUPERUSERS_FULL_ACCESS=true for cross-namespace read access
- Full Access Superusers: Regular superusers with FULL_ACCESS enabled, can
perform CRUD on content they don't own
- Write operations: Only allowed for full access superusers (global readonly
superusers never get write access)
**Key Fixes:**
1. Fixed superuser panel endpoints returning 403 when FULL_ACCESS was disabled.
Basic panel operations (user list, logs, org list, messages) now work with
just FEATURE_SUPER_USERS enabled.
2. Updated decorators to properly differentiate between basic superuser
operations and permission bypass operations.
3. Implemented license bypass: Superusers with FULL_ACCESS now bypass
license/quota limits when creating or modifying private repositories.
4. Fixed 18 permission checks across 7 files to properly implement cross-namespace
access controls for different superuser types.
**Changes:**
- endpoints/api/__init__.py: Fixed allow_if_superuser(), require_repo_permission, and decorators
- endpoints/api/superuser.py: Updated SuperUserAppTokens permission check
- endpoints/api/organization.py: Updated 4 GET endpoints to require FULL_ACCESS
- endpoints/api/namespacequota.py: Updated 2 GET endpoints to require FULL_ACCESS
- endpoints/api/team.py: Updated 2 GET endpoints to require FULL_ACCESS
- endpoints/api/prototype.py: Updated 1 GET endpoint to require FULL_ACCESS
- endpoints/api/policy.py: Updated auto-prune policy endpoints
- endpoints/api/robot.py: Updated robot endpoints
- endpoints/api/build.py: Updated repository build logs
- endpoints/api/repository.py: Added license bypass for superusers with FULL_ACCESS
- endpoints/api/repository_models_pre_oci.py: Updated repository visibility query
- endpoints/api/logs.py: Fixed log access to require FULL_ACCESS for permission bypass
- endpoints/api/test/test_superuser_full_access.py: Added comprehensive test suite
- endpoints/api/test/test_appspecifictoken.py: Updated test mocking and added 403 test
- test/test_api_usage.py: Updated test expectations for license bypass behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
feat: Add image pull statistics API endpoints and UI integration
- Add new API endpoints for tag and manifest pull statistics
- Integrate pull metrics into web UI with new table columns
- Add FEATURE_IMAGE_PULL_STATS feature flag and PULL_METRICS_REDIS config
- Add pullstatsredisflushworker to supervisord configuration
- Add comprehensive test coverage for pull statistics functionality
Co-authored-by: shudeshp <shudeshp@redhat.com>
Update global read‑only superuser capability for API v2 and standardize registry authentication/authorization behavior. Centralize permission checks via decorators, refine bearer token issuance and scope handling, and align HTTP status codes across v2 endpoints. Update unit, integration, and protocol tests to validate the new contract.
* Fix missing axios import
* Rewrite OAuth error for react to show a new error component
* Rewrite tests for OAuth flow
* Fix navigating to /signin from Headertoolbar
* replace url_for() with urlencode + add config setting for test suite
* Add checks before embedding redirect url + redesign OAUTH error screen
Implements global read-only superuser permissions for v1 endpoints, adjusts superuser write checks, and updates app token listing and detail endpoints; includes comprehensive tests.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: resolve Sentry/OpenTelemetry integration conflicts
Configure Sentry to use minimal integrations when OTEL_TRACING is enabled
to prevent instrumentation conflicts that broke exception capture
---------
Co-authored-by: shudeshp <shudeshp@redhat.com>
* mirror: Add job timeout to mirror configurations (PROJQUAY-7249)
Previous global job timeout of 5 minutes was inadequate for big images. The timeout should now be configurable in much the same way as sync is. Minimum job length is 300 seconds/5 minutes.
The PR is still work in progress.
* Fix init db, remove reference to user data in logs
* Fix tests, change repo mirror configuration
* Fix tests, make mirroring cancellable through UI
* Add cancel mirror test, change HTML document to reflect mirror timeout
* Flake8 doesn't like when '==' is used with 'None'
* Fix mirror registry tests
* Add new cypress data to fix cypress tests
* Added ability to define upload chunk size to RADOS driver, small changes to repo mirror HTML page
* Fix database migration to follow HEAD
* Upload new database data for Cypress tests
* Make skopeo_timeout_interval mandatory on API calls
---------
Co-authored-by: Ivan Bazulic <ibazulic@redhat.com>
* marketplace: splittable sku for MW02702 (PROJQUAY-8151)
* Alembic migration to drop unique constraint on the orgrhsubscriptions
table
* Can split sub quantities of MW02702 across multiple orgs
* Can specify quantity for the MW02702 SKU across orgs on react UI
* Update angular UI to allow user to specify quantities for MW02702
* auth: Implement is_restricted_user for OIDC and allow super users to create content regardless of set restriction (PROJQUAY-8208)
Currently, if OIDC is set as an authentication mechanism and restricted users is set, Quay will return a `501 Not Implemented` on invocation. Now, Quay will properly check the restricted user whitelist for federated users.
Additionally, if user restriction is in place and super user's username was **not** explicitly whitelisted, super users would not be able to create new content inside the registry. Now, the username is explicitly checked in the UI to allow super users to create both organizations and repos regardless of restricted users whitelist.
* Add tests
* Add tests for usermanager
* api: Add ability to delete tags via v2 call (PROJQUAY-7599)
The deletion of tags was previously not supported by the Docker v2 API. Current versions of both the OCI spec and Docker v2 API provide this ability, hence adding it to Quay as well. See [OCI spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md) for more details.
* Fix test call
* Add missing argument to test
* Add security tests
* Enable conformance tests
* Switch to v1.1.0 instead of release candidate for conformance tests
* Revert changes to conformance tests
* feature flag: add feature flag for image expiry trigger (PROJQUAY-7460)
* add FEATURE_IMAGE_EXPIRY_TRIGGER to CLIENT_WHITELIST
* minor fix
* setting IMAGE_EXPIRY_TRIGGER to true for testing
* fixing config.json
* Add sqlite db support on quay start up
* Add batchmode to migration scripts to support sqlite db
* Add sqlite db to config-tool validator + alembic migration
* Fix migration script to prevent db row locking
Added commit statement to ensure previous transaction is
completed before the next one within the same table
* Clean up unused sqlite volume
* Apply black formatting to migration scripts
* Address review comments
* Ensure py39-unit test runs the alembic migration on Sqlite
* Add static type checking for alembic config file name
* alembic remove commit and invalidate during migration
When disconnecting from db, alembic tries to rollback
causing PendingRollbackError
* Bump go version in config-tool Dockerfile
* Explicitly commit transaction to prevent db table locking
* Clean up + remove debug statements
* Undo database secret key change
* Add TEST_DATABASE_URI to py39-unit to run unit test with sqlite db
* Drop index before dropping column to prevent sqlite error
* Add test coverage + address last set of reviews
---------
Signed-off-by: harishsurf <hgovinda@redhat.com>
* marketplace: change redhatsubscriptions model to return a list of customer ids (PROJQUAY-7129)
* Use list comprehension in model and expect to return None if no rows are
returned
* fix behavior for reconciler and fix unit test for reconciler
* feat: Add support for auto pruning at repository level (PROJQUAY-6354)
* Add repositoryautoprunepolicy table to alembic migration script
* Add repository auto-prune policy endpoints
* Add UI for repository auto-pruning policies
* case: apply repo auto-prune policy when no namespace policy given
* case: both namespace and repo pruning policy are given
* Add tests for repository autoprune endpoint
* Add cypress test for repository auto-prune
* Add repo auto-prune policy clean-up for repository deletion
* Add repository auto pruning tables to quay db snapshot for cypress tests
* Address review comments
* Add more tests + fix CI + reformat files
* Address review comments #2
---------
Signed-off-by: harishsurf <hgovinda@redhat.com>
* Adds handling for when a subscription returned from the subscription watch api has a quantity greater than 1. Number of private repos should be correctly calculated using the quantity.
* Updates ui so that subscriptions can only be added to an org as a group, i.e. a subscription with quantity = 2 cannot be split across organizations.
* billing: marketplace UI
adds UI in billing section for managing user and org-bound skus
add more unit tests for org binding
changed endpoint for bulk attaching skus to orgs
* update reconciliationworker to use webCustomerId instead of
ebsAccountNumber
* fix reconciler where it was incorrectly using the ebsAccountNumber to
create subscriptions
* add job to reconciler so that it reconciles different ids between the
database and the user api
* separate skus to be used by billing and skus to be used by reconciler