Add a Repository Status page and surface read-only status across the web UI - #1327
Merged
Conversation
Motivation: Central Dogma can put an individual repository or a whole project into read-only mode (scoped replication-failure read-only, line#1305), but there was no way to see which repositories or projects are currently read-only, nor to set or clear that status, from the web UI. Modifications: - Add `GET /api/v1/status/repos/read-only` (system administrator only) that returns the projects and repositories that are currently read-only. A project-scoped entry uses `dogma` as its repository name. - Serialize `RepositoryState.updatedAt` as an ISO-8601 string via `@JsonFormat` so clients render the real timestamp instead of an epoch number. - Expose read-only scope metrics: a `repository.read.only.count` gauge and a `repository.read.only` multi-gauge tagged by project, repo and scope. - Add a "Repository Status" settings tab (system administrator only) that - lists the read-only projects and repositories with their scope, status and last-updated time; - offers a form to make a repository read-only, with project and repository auto-complete; and - offers a per-row action to revert a repository or project to writable. Both changes require re-typing the full `project/repository` name to confirm, to guard against accidental clicks. - Add the `updateRepositoryStatus` mutation and a `RepoStatus` cache tag so the list refreshes after a change. - Add unit tests, a Playwright e2e test and a server test for the new endpoint. Result: - A system administrator can now view all read-only repositories and projects and toggle read-only status from the web UI, with a type-to-confirm safeguard against mistakes.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Motivation: A project or a repository can be put into read-only mode, but the web UI neither showed that status nor stopped a user from attempting a write that the server would reject. Modifications: - Add `status` to `ProjectDto` so that `GET /api/v1/projects` reports the read-only status of a project, which is stored in its `dogma` repository. - Add a `useReadOnly()` hook that resolves the effective read-only status of a project and a repository. It prefers the project-scoped hint when both are read-only, and reports writable while the status is still being fetched so that a write action is never disabled by a transient error. - Show a `Read-only` / `Writable` tag on the project list, the project detail page, the repository list and the repository tree page. - Disable the write actions of a read-only project or repository, each with a tooltip that explains why: New Repository, New File, Edit, Delete, Revert, Project Settings and Repository Settings. A disabled anchor is still clickable, so the link is dropped rather than disabled. `New Repository` is a `PopoverTrigger` child, which cannot be wrapped, so the popover is replaced with a tooltipped disabled button while the project is read-only. - Warn in the confirmation modal that making the internal `dogma` repository read-only blocks writes to every repository in the project, and that reverting it leaves individually read-only repositories read-only. - Invalidate the `Project` and `Repo` cache tags when a repository status changes. Both lists now carry the status, so they otherwise keep showing the previous one until the cache entry is dropped. - Make a long error message scrollable inside the toast so that the close button stays reachable. - Fix a checkstyle violation in `RepoStatusManager` and stabilize two tests. `RepoStatusManagerTest` awaits the status cache, because a commit notifies the status listener inline but the listener itself is registered asynchronously on the repository worker, so an update committed before the registration lands is only picked up by the initial snapshot. `ZooKeeperScopedReadonlyIntegrationTest` resets the server status with `Scope.ALL`, so that a replica which has not replayed the previous `REPLICATION_ONLY` entry cannot apply it in the middle of the test. Result: - A user can now see whether a project or a repository is read-only, and the write actions that would fail are disabled with an explanation of why.
Motivation: The file list of the repository tree page offers a Delete button for every file, and it stayed enabled while the repository or its project was read-only. Pressing it opened the confirmation modal and the delete only failed once the server rejected it. Modifications: - Disable the Delete button of `FileList` when the repository is read-only, and explain why on hover, like the other write actions. - Keep the copy actions available, as they do not write. Result: - A read-only repository no longer offers a delete that is bound to fail.
ikhoon
force-pushed
the
scoped-readonly-ui
branch
from
July 10, 2026 04:22
69e6014 to
32cd3e3
Compare
Motivation: The `repository.read.only` gauge carried a `scope` tag that only restated its `repo` tag: a project-scoped entry is exactly the one whose repository is the internal `dogma` repository. Modifications: - Remove the `scope` tag from the `repository.read.only` multi-gauge. - Assert the exact tag set in the test, so a stray tag fails it. Result: - The gauge is tagged by project and repository only. A project-wide read-only entry is still identified by its `dogma` repository.
Motivation: The Repository Status page hid the repository name of a project-scoped entry behind a dash and restated the same fact in a Scope column. Modifications: - Show the internal `dogma` repository name, linked like any other repository. - Remove the Scope column, which the repository name already tells apart. Result: - A project-scoped read-only entry reads as `project` / `dogma`, and the table is one column narrower.
Motivation: `webapp-e2e` failed: the confirm-form test still expected the row to contain the Scope badge, which the previous commit removed. Modifications: - Assert the row names its project instead of the removed badge. Result: - The Repository Status e2e suite passes again.
Contributor
Author
Motivation: A replica in `REPLICATION_ONLY` mode rejected replayed commands because the server-level read-only check did not distinguish a replayed command from a client request. A replay failure is treated as a poisoned log entry and skipped, so a read-only replica silently dropped every replicated write, permanently diverged from the cluster and escalated an unrelated read-only status. Modifications: - Exempt a replayed command from the server-level read-only check in `AbstractCommandExecutor`, matching the existing repository-level exemption. - Document the exemption on `ExecutionContext.isReplay()`. - Add a unit test that a rejected client push is still applied when replayed under `REPLICATION_ONLY`. - Add integration tests that a locally read-only replica keeps replaying pushes and project creations while the rest of the cluster stays writable. - Assert in `afterEach()` that all replicas converge on the same `dogma/dogma` head revision, and wait for the seed commit replay in `injectFault()` to remove a race. Result: - A `REPLICATION_ONLY` replica keeps applying the replication log and no longer diverges from the cluster. - Putting a single replica into `REPLICATION_ONLY` no longer risks a cluster-wide read-only escalation triggered by an unrelated write.
ikhoon
marked this pull request as ready for review
July 10, 2026 16:18
Motivation: READ_ONLY and REPLICATION_ONLY both reject client writes, but only the latter keeps replaying the replication log. The distinction decides whether a replica stays in sync with the cluster or must be re-synced manually, and it was undocumented. Modifications: - Document each ServerStatus constant with its writable/replicating semantics and its operational consequence. Result: - Operators can tell which read-only status keeps a replica following the cluster. No functional change.
…startup Motivation: When a replicated server starts, the persisted server status was applied only to the outer ZooKeeperCommandExecutor. A status update applied at runtime reaches the inner delegate as well, so a replica restarted in a read-only status came back with a writable delegate, unlike the state the runtime path produces. Modifications: - Propagate the persisted `writable` flag to the delegate of `ZooKeeperCommandExecutor` in `CentralDogma.start()`. - Add `ReplicationOnlyRestartTest`, which fails without the fix: after a cluster-wide `REPLICATION_ONLY` and a restart, every replica's delegate must come back read-only. Result: - A replica restarted in a read-only status now has the same executor state as one that entered it at runtime.
Motivation: A REPLICATION_ONLY replica keeps replaying the replication log, but no test covered that server-level gate overlapping with a repository-level READ_ONLY on the same replica. A refactor merging the two read-only checks could silently drop replayed entries again. Modifications: - Add an integration test that pushes to a writable sibling repository and asserts a replica replays it while both a repository-scope READ_ONLY and a local REPLICATION_ONLY are active, without flipping either status. - Extract `enterReplicationOnly()` and `driveRepoIntoReadOnly()` helpers. - Add a 1-based `serverById()` to `CentralDogmaReplicationExtension`, matching the 1-based `serverId` of `configureEach()` to remove the off-by-one against the 0-based `servers()`. Result: - Log replay under overlapping read-only scopes is guarded by a regression test. No functional change.
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.





Motivation:
Central Dogma can put an individual repository or a whole project into read-only mode (#1305), but the web UI neither showed that status nor acted on it. Every write button stayed enabled, so a user discovered the read-only state only by having the server reject the write, and there was no way to see or change the status from the UI.
Modifications:
statustoProjectDtoso thatGET /api/v1/projectsreports whether a project is read-only.Read-only/Writabletag on the project list, the project detail page, the repository list and the repository tree page.project/repositoryname. Selecting the internaldogmarepository changes the whole project, and the confirmation now says so.GET /api/v1/status/repos/read-only, serializeRepositoryState.updatedAtas an ISO-8601 string, and exposerepository.read.only.countandrepository.read.onlymetrics.Result: