Feature/add mirror active field#19
Merged
rockythorn merged 10 commits intofeature/config-and-processing-refactorfrom Nov 14, 2025
Merged
Feature/add mirror active field#19rockythorn merged 10 commits intofeature/config-and-processing-refactorfrom
rockythorn merged 10 commits intofeature/config-and-processing-refactorfrom
Conversation
Add boolean active field to supported_products_rh_mirrors table to allow disabling mirrors without deleting them. This preserves historical data and mirror relationships while preventing the mirror from being used in new advisory processing. Changes: - Add active column with default true to supported_products_rh_mirrors - Add database index on active field for query performance - Add migration script for schema change - Update DB model with active field - Add active field to admin UI forms (create and edit) - Update mirror filtering in workflow service to respect active flag - Update configuration import/export to handle active field - Add active field validation in form processing
The active checkbox wasn't saving properly when unchecked because HTML forms don't send unchecked checkbox values. This caused the field to always default to "true" in the backend. Added hidden input with value "false" before each checkbox, so the form always sends a value. Backend now parses all "active" values and takes the last one (which will be "true" if checked, "false" if unchecked). Changes: - Add hidden input to mirror edit and new templates - Update both POST endpoints to manually parse form data for active field - Remove default="true" from Form parameters that was masking the issue
Implemented multi-level sorting and visual status indicators for mirrors in the admin UI to improve usability and organization. Changes: - Sort mirrors by active status (active first), then major version (desc), then name (asc) for logical grouping - Add Status column with green "Active" and gray "Inactive" tags for clear visual differentiation - Update validation to allow parentheses in mirror names for descriptive naming like "Rocky Linux 9 (BaseOS)" - Fetch mirrors with explicit ordering in backend instead of relying on database insertion order
The RHMatcherWorkflow was processing all mirrors regardless of their active status, causing unnecessary fetches from mirrors that should be skipped. This adds a check to skip mirrors where active=False in the match_rh_repos activity.
The block_remaining_rh_advisories function had a nested loop bug where it would iterate over all mirrors from a prefetch, then inside that loop query for active mirrors and iterate over them again. This caused: 1. Redundant database queries (N queries for N total mirrors) 2. Processing each active mirror N times instead of once 3. Variable shadowing with the reused 'mirror' variable name Simplified to a single query for active mirrors and one processing loop.
Removed unnecessary hidden input fields and simplified the form parsing logic for the active checkbox in mirror creation and editing forms. Changes: - Replaced complex list indexing with simple membership check - Removed hidden input fields from both Jinja templates - Updated comments to reflect simpler approach The functionality remains identical, but the code is more readable and maintainable.
Add comprehensive tests for the simplified checkbox parsing logic and active field functionality: - Checkbox parsing for checked/unchecked/missing states - Active field in configuration export (true/false cases) - Active field in configuration import validation - Backwards compatibility for imports without active field All tests pass successfully.
Both admin_supported_product_mirror_repomd_new_post and admin_supported_product_mirror_repomd_post had identical code for building form_data and calling validation. Extracted this into _validate_repomd_form helper that returns validated_data, errors, and the original form_data for use in error templates. This eliminates 14 lines of duplication across the two functions.
trinity-q
approved these changes
Nov 14, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds an
activeboolean field to thesupported_products_rh_mirrorstable, allowing operators to disable mirrors without deleting them. This preserves historical data and advisory relationships while preventing inactive mirrors from being processed in workflows. The feature includes database migration, UI controls, workflow integration, and comprehensive testing.Problem Statement
No way to temporarily disable mirrors
Apollo had no mechanism to disable a Red Hat mirror mapping without permanently deleting it. This created several operational problems:
Example scenarios:
Impact:
Changes
1. Database Schema (
apollo/schema.sql+ migration)Added
activeboolean column tosupported_products_rh_mirrorstable:Schema changes:
activecolumn: Boolean, NOT NULL, default TRUEactivefor query performance2. ORM Model Update (
apollo/db/__init__.py)Added
activefield toSupportedProductsRhMirrormodel:3. Workflow Integration
RHMatcherWorkflow (
apollo/rpmworker/rh_matcher_activities.py):Workflow service (
apollo/server/services/workflow_service.py):Bug fix: Fixed duplicate loop bug where inactive mirror filtering caused N redundant database queries and processed each mirror N times.
4. Admin UI
Mirror list view (
admin_supported_product.jinja):Mirror edit form (
admin_supported_product_mirror.jinja):Mirror creation form (
admin_supported_product_mirror_new.jinja):5. Import/Export
Export (
/admin/supported_products/{id}/mirrors/{mirror_id}/export):activefield in JSON exportImport (
/admin/supported_products/import):activefield in JSON importtrueif not provided (backward compatibility)6. Checkbox Handling Fix
Fixed HTML form handling for unchecked checkboxes (browsers don't send unchecked checkbox values):
Initial approach: Hidden input with
falsevalue before checkboxWhen checked: form sends
["false", "true"]→ take last value =trueWhen unchecked: form sends
["false"]→ take last value =falseSimplified approach: Direct membership check
7. Comprehensive Testing
New tests (
test_admin_routes_supported_products.py):test_checkbox_parsing_checked- Verify checked checkbox parsed correctlytest_checkbox_parsing_unchecked- Verify unchecked checkbox parsed correctlytest_checkbox_parsing_missing- Verify missing field defaults to Falsetest_export_active_true- Verify export includes active=truetest_export_active_false- Verify export includes active=falsetest_import_active_field- Verify import accepts active fieldtest_import_without_active- Verify backward compatibilityTotal: 217 lines of new test coverage
How It Fits Into Apollo
Apollo's mirror processing workflow:
Why this feature matters:
Use Cases
Staging New Mirror Configuration
Deprecating Old Versions
Result:
Incident Response
Testing Mirror Updates
Testing
Unit tests:
Integration validation:
Performance:
activefield ensures fast queriesFiles Changed