Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15407152
D19793.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D19793.diff
View Options
diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php
--- a/src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php
+++ b/src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php
@@ -120,33 +120,71 @@
$repository->getDisplayName()));
}
- $bindings = $service->getActiveBindings();
- $bindings = mpull($bindings, null, 'getDevicePHID');
- if (empty($bindings[$device->getPHID()])) {
- throw new PhutilArgumentUsageException(
- pht(
- 'Repository "%s" has no active binding to device "%s". Only '.
- 'actively bound devices can be promoted or demoted.',
- $repository->getDisplayName(),
- $device->getName()));
- }
-
- $versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions(
- $repository->getPHID());
-
- $versions = mpull($versions, null, 'getDevicePHID');
- $versions = array_select_keys($versions, array_keys($bindings));
-
- if ($versions && $promote) {
- throw new PhutilArgumentUsageException(
- pht(
- 'Unable to promote "%s" for repository "%s": the leaders for '.
- 'this cluster are not ambiguous.',
- $device->getName(),
- $repository->getDisplayName()));
- }
-
if ($promote) {
+ // You can only promote active devices. (You may demote active or
+ // inactive devices.)
+ $bindings = $service->getActiveBindings();
+ $bindings = mpull($bindings, null, 'getDevicePHID');
+ if (empty($bindings[$device->getPHID()])) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Repository "%s" has no active binding to device "%s". Only '.
+ 'actively bound devices can be promoted.',
+ $repository->getDisplayName(),
+ $device->getName()));
+ }
+
+ $versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions(
+ $repository->getPHID());
+ $versions = mpull($versions, null, 'getDevicePHID');
+
+ // Before we promote, make sure there are no outstanding versions on
+ // devices with inactive bindings. If there are, you need to demote
+ // these first.
+ $inactive = array();
+ foreach ($versions as $device_phid => $version) {
+ if (isset($bindings[$device_phid])) {
+ continue;
+ }
+ $inactive[$device_phid] = $version;
+ }
+
+ if ($inactive) {
+ $handles = $viewer->loadHandles(array_keys($inactive));
+
+ $handle_list = iterator_to_array($handles);
+ $handle_list = mpull($handle_list, 'getName');
+ $handle_list = implode(', ', $handle_list);
+
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Repository "%s" has versions on inactive devices. Demote '.
+ '(or reactivate) these devices before promoting a new '.
+ 'leader: %s.',
+ $repository->getDisplayName(),
+ $handle_list));
+ }
+
+ // Now, make sure there are no outstanding versions on devices with
+ // active bindings. These also need to be demoted (or promoting is a
+ // mistake or already happened).
+ $active = array_select_keys($versions, array_keys($bindings));
+ if ($active) {
+ $handles = $viewer->loadHandles(array_keys($active));
+
+ $handle_list = iterator_to_array($handles);
+ $handle_list = mpull($handle_list, 'getName');
+ $handle_list = implode(', ', $handle_list);
+
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Unable to promote "%s" for repository "%s" because this '.
+ 'cluster already has one or more unambiguous leaders: %s.',
+ $device->getName(),
+ $repository->getDisplayName(),
+ $handle_list));
+ }
+
PhabricatorRepositoryWorkingCopyVersion::updateVersion(
$repository->getPHID(),
$device->getPHID(),
diff --git a/src/docs/user/cluster/cluster_repositories.diviner b/src/docs/user/cluster/cluster_repositories.diviner
--- a/src/docs/user/cluster/cluster_repositories.diviner
+++ b/src/docs/user/cluster/cluster_repositories.diviner
@@ -414,28 +414,24 @@
push logs.
If you are comfortable discarding these changes, you can instruct Phabricator
-that it can forget about the leaders in two ways: disable the service bindings
-to all of the leader devices so they are no longer part of the cluster, or use
-`bin/repository thaw` to `--demote` the leaders explicitly.
+that it can forget about the leaders by doing this:
-If you do this, **you will lose data**. Either action will discard any changes
-on the affected leaders which have not replicated to other devices in the
-cluster.
+ - Disable the service bindings to all of the leader devices so they are no
+ longer part of the cluster.
+ - Then, use `bin/repository thaw` to `--demote` the leaders explicitly.
-To remove a device from the cluster, disable all of the bindings to it
-in Almanac, using the web UI.
-
-{icon exclamation-triangle, color="red"} Any data which is only present on
-the disabled device will be lost.
-
-To demote a device without removing it from the cluster, run this command:
+To demote a device, run this command:
```
phabricator/ $ ./bin/repository thaw rXYZ --demote repo002.corp.net
```
{icon exclamation-triangle, color="red"} Any data which is only present on
-**this** device will be lost.
+the demoted device will be lost.
+
+If you do this, **you will lose unreplicated data**. You will discard any
+changes on the affected leaders which have not replicated to other devices
+in the cluster.
Ambiguous Leaders
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 19, 4:09 PM (1 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7396067
Default Alt Text
D19793.diff (6 KB)
Attached To
Mode
D19793: Make "bin/repository thaw" workflow more clear when devices are disabled
Attached
Detach File
Event Timeline
Log In to Comment