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

Quay 3.17 New UI allows setting tag expiration on org mirror repos (should be disabled)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • quay-v3.17.0
    • quay-ui
    • False
    • Hide

      None

      Show
      None
    • False

      Summary

      The new UI allows users to attempt setting tag expiration on organization mirror repositories, when these controls should be disabled upfront. The backend correctly rejects the request with HTTP 503, but users see a confusing generic error instead of being prevented from the action.

      Current Behavior (Incorrect)

      1. User opens Tags tab for an org mirror repository (e.g., quayqe/repo216)
      2. UI displays tag expiration controls as enabled/clickable
      3. User attempts to set tag expiration
      4. Backend correctly rejects with HTTP 503: "Repository is in read only or mirror mode: ORG_MIRROR"
      5. UI shows generic error: "Could not set expiration for tag tag9: an unexpected issue occurred. Please try again or contact support"

      Expected Behavior (Correct)

      1. UI detects repository state is ORG_MIRROR
      2. Tag expiration controls are disabled (grayed out)
      3. Informative tooltip explains: "Tag expiration is not supported for mirror repositories. Tags are managed by the source registry."
      4. User cannot attempt the action (prevented upfront)

      Evidence

      Screenshot shows:

      • Enabled expiration controls on org mirror repo quayqe/repo216
      • Generic error after backend rejection: "Could not set expiration for tag tag9"
      • All tags show "Never" in Expires column (correct)
      • User was able to click and attempt setting expiration (incorrect)

      Technical Details

      Backend (Working Correctly)

      File: endpoints/api/tag.py:201-252
      Endpoint: PUT /api/v1/repository/{namespace}/{repo}/tag/{tag}
      Decorator: @disallow_for_non_normal_repositories (line 202)
      Response: HTTP 503 with message "Repository is in read only or mirror mode: ORG_MIRROR"

      def disallow_for_non_normal_repositories(func):
          @wraps(func)
          def wrapped(self, namespace_name, repository_name, *args, **kwargs):
              repo = data_model.repository.get_repository(namespace_name, repository_name)
              if repo and repo.state != RepositoryState.NORMAL:
                  abort(503, message="Repository is in read only or mirror mode: %s" % repo.state)
              return func(self, namespace_name, repository_name, *args, **kwargs)
          return wrapped
      

      Frontend (Bug)

      Location: web/src/routes/RepositoryDetails/Tags/ (likely)
      Issue: UI does not check repository state before enabling expiration controls
      Impact: Poor UX - users attempt actions that will always fail

      Repository States Requiring Disabled Controls

      The following repository states should disable tag expiration controls:

      • ORG_MIRROR - Organization mirror repositories
      • MIRROR - Repository mirror
      • READ_ONLY - Read-only repositories
      • MARKED_FOR_DELETION - Deleted repositories

      All these states are blocked by the backend decorator.

      Recommended Fix

      Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      // Fetch repository details including state
      const repository = useRepository(namespace, repoName);
      
      // Disable expiration controls for non-NORMAL repos
      const expirationDisabled = repository.state !== 'NORMAL';
      
      // Show informative tooltip
      const expirationTooltip = repository.state === 'ORG_MIRROR' 
        ? "Tag expiration is not supported for mirror repositories. Tags are managed by the source registry."
        : repository.state === 'READ_ONLY'
        ? "Tag expiration cannot be modified on read-only repositories."
        : "Tag expiration controls are disabled for this repository.";
      

      Severity

      Medium - UX issue, not data corruption

      • Backend correctly prevents invalid operations
      • No data integrity risk
      • Poor user experience (confusing error messages)
      • Users may repeatedly attempt invalid actions

      Acceptance Criteria

      • UI detects repository state when loading Tags page
      • Tag expiration controls disabled for ORG_MIRROR repositories
      • Tag expiration controls disabled for MIRROR repositories
      • Tag expiration controls disabled for READ_ONLY repositories
      • Informative tooltip explains why controls are disabled
      • No generic error shown when user attempts (prevented upfront)
      • Behavior consistent across all repository types

      Related Issues

      • PROJQUAY-10040 - Organization mirror feature (original implementation)
      • Backend protection already exists in endpoints/api/tag.py:202

      Testing

      1. Create org mirror configuration
      2. Wait for repository discovery
      3. Navigate to Tags tab for mirrored repository
      4. Verify expiration controls are disabled
      5. Verify tooltip shows informative message
      6. Verify same behavior for MIRROR and READ_ONLY states

      Additional Context

      This bug was discovered during code review of organization mirror functionality. The backend correctly implements read-only enforcement for mirror repositories, but the UI allows users to attempt modifications that will always fail, creating a poor user experience.

              rh-ee-shossain Shaon Hossain
              lzha1981 luffy zhang
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: