Uploaded image for project: 'Project Quay'
  1. Project Quay
  2. PROJQUAY-10255

[Data Model] Add Architecture Filter to RepoMirrorConfig

XMLWordPrintable

    • Icon: Story Story
    • Resolution: Unresolved
    • Icon: Undefined Undefined
    • None
    • None
    • None
    • Security & Compliance
    • False
    • Hide

      None

      Show
      None
    • False
    • Not Selected

      [Data Model] Add Architecture Filter to RepoMirrorConfig

      Summary

      Add database schema support for storing architecture filter configuration on repository mirrors. This allows users to specify which architectures (e.g., amd64, arm64) should be mirrored from multi-architecture images, enabling storage savings by excluding unnecessary platforms.

      Acceptance Criteria

      • [ ] RepoMirrorConfig model includes architecture_filter field storing list of architectures to mirror
      • [ ] Empty/null architecture filter means "mirror all architectures" (backwards compatible)
      • [ ] Alembic migration creates the new column with proper defaults
      • [ ] Migration is reversible (downgrade removes the column)
      • [ ] Model functions can read/write architecture filter configuration
      • [ ] Existing mirrors without architecture config continue to work unchanged

      Technical Requirements

      Database Changes

      File: data/database.py

      Add new field to RepoMirrorConfig class (around line 2056):

      class RepoMirrorConfig(BaseModel):
          # ... existing fields ...
      
          # Architecture filter for multi-arch images. JSON array of architecture strings.
          # Empty array or null means mirror all architectures.
          # Example: ["amd64", "arm64"]
          architecture_filter = JSONField(default=[], null=True)
      

      Migration

      File: data/migrations/versions/XXXX_add_mirror_architecture_filter.py

      Create new Alembic migration following the pattern in 5248ddf35167_repository_mirror.py:

      """Add architecture_filter to repomirrorconfig
      
      Revision ID: <generated>
      Revises: <previous>
      Create Date: <date>
      """
      
      import sqlalchemy as sa
      from alembic import op
      
      revision = "<generated>"
      down_revision = "<previous>"
      
      def upgrade(op, tables, tester):
          op.add_column(
              "repomirrorconfig",
              sa.Column("architecture_filter", sa.Text(), nullable=True)
          )
      
      def downgrade(op, tables, tester):
          op.drop_column("repomirrorconfig", "architecture_filter")
      

      Model Functions

      File: data/model/repo_mirror.py

      Add helper functions for architecture filter management:

      def get_architecture_filter(repository):
          """
          Returns the architecture filter for a repository mirror, or None if not configured.
          Returns empty list if mirror should include all architectures.
          """
          mirror = get_mirror(repository)
          if mirror is None:
              return None
          return mirror.architecture_filter or []
      
      def set_architecture_filter(repository, architectures):
          """
          Sets the architecture filter for a repository mirror.
      
          Args:
              repository: Repository model instance
              architectures: List of architecture strings (e.g., ["amd64", "arm64"]) or empty list for all
          """
          # Validate architectures
          valid_archs = {"amd64", "arm64", "ppc64le", "s390x", "386", "riscv64"}
          for arch in architectures:
              if arch not in valid_archs:
                  raise ValueError(f"Invalid architecture: {arch}")
      
          mirror = get_mirror(repository)
          if mirror is None:
              raise ValueError("Repository does not have mirroring configured")
      
          mirror.architecture_filter = architectures
          mirror.save()
          return mirror
      

      Implementation Notes

      Existing Patterns to Follow

      • JSONField usage: See external_registry_config in RepoMirrorConfig for JSON field pattern
      • Migration pattern: Follow 5248ddf35167_repository_mirror.py for migration structure
      • Model functions: Follow patterns in data/model/repo_mirror.py for function signatures and error handling

      Architecture Values

      Standard OCI architecture values to support:
      - amd64 (x86_64)
      - arm64 (aarch64)
      - ppc64le
      - s390x
      - 386 (i386/i686)
      - riscv64

      Edge Cases

      • Empty list [] = mirror all architectures (default behavior)
      • null = same as empty list (backwards compatibility)
      • Single architecture ["amd64"] = only mirror that architecture
      • Multiple architectures ["amd64", "arm64"] = mirror selected architectures

      Backwards Compatibility

      • Existing mirrors without architecture_filter set should continue to work
      • Default value ensures all architectures are mirrored if not configured
      • No changes to existing mirror behavior unless explicitly configured

      Dependencies

      • None (foundational story)

      Testing Requirements

      Unit Tests

      File: data/model/test/test_repo_mirror.py (create or extend)

      def test_get_architecture_filter_not_configured():
          """Test getting architecture filter when not set returns empty list."""
      
      def test_get_architecture_filter_configured():
          """Test getting architecture filter when set returns correct list."""
      
      def test_set_architecture_filter_valid():
          """Test setting valid architecture filter."""
      
      def test_set_architecture_filter_invalid_arch():
          """Test setting invalid architecture raises ValueError."""
      
      def test_set_architecture_filter_empty_for_all():
          """Test setting empty list mirrors all architectures."""
      

      Migration Tests

      Follow pattern from existing migration tests to verify:
      - Column is added correctly
      - Default value is applied to existing rows
      - Downgrade removes column

      Definition of Done

      • [ ] Code implemented and follows project conventions
      • [ ] All acceptance criteria met
      • [ ] Unit tests written and passing
      • [ ] Migration tested (upgrade and downgrade)
      • [ ] No regressions in existing mirroring functionality
      • [ ] Code reviewed and approved

              marckok Marcus Kok
              marckok Marcus Kok
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: