Partnership stacks are the owner's declaration, so a mirror must read them from the owner's conf
This commit is contained in:
@@ -88,27 +88,38 @@ if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|||||||
}
|
}
|
||||||
sort($containers, SORT_NATURAL | SORT_FLAG_CASE);
|
sort($containers, SORT_NATURAL | SORT_FLAG_CASE);
|
||||||
|
|
||||||
// Containers the partner already runs continuously, because onboard deployed them there.
|
// Stacks are declared by the PARTNERSHIP OWNER and deployed to everyone, so on a mirror they
|
||||||
// They cannot be failover material: there is nothing to start during an outage that is not
|
// are not in this host's conf at all — HOST2_PARTNERSHIP_AUTH_STACK is the shipped template,
|
||||||
// already up, and a tier assignment for one would be a delay applied to a running container.
|
// still commented out, while the eight auth containers it describes run there permanently
|
||||||
|
// because the owner put them there. Reading "this host's" stacks left the mirror's card
|
||||||
|
// showing every one of them as ordinary, selectable, uncovered.
|
||||||
//
|
//
|
||||||
// The stacks store XML template filenames, and their case does not have to agree with the
|
// Owner's conf first, then this host's, unioned: on the owner the two are the same file, and
|
||||||
// container's — this conf ships "my-prowlarr.xml" against a container named "Prowlarr" — so
|
// a host that declares extras of its own still has them honoured. The owner's copy reaches a
|
||||||
// the mapping is done case-insensitively, once, here.
|
// mirror through the conf_sync RAM cache, which vv_read_host_conf_raw() knows how to find.
|
||||||
|
$ownerSlot = strtolower(vv_parse_conf_scalar(vv_read_conf_raw('master.conf'), 'PARTNERSHIP_OWNER_HOST'));
|
||||||
|
$stackSrc = [];
|
||||||
|
foreach (array_unique(array_filter([$ownerSlot, $hostId])) as $slot) {
|
||||||
|
$stackSrc[strtoupper($slot)] = vv_read_host_conf_raw($slot);
|
||||||
|
}
|
||||||
|
|
||||||
$stackOf = [];
|
$stackOf = [];
|
||||||
$byLower = [];
|
$byLower = [];
|
||||||
foreach ($containers as $n) $byLower[strtolower($n)] = $n;
|
foreach ($containers as $n) $byLower[strtolower($n)] = $n;
|
||||||
|
foreach ($stackSrc as $id => $srcRaw) {
|
||||||
foreach ([
|
foreach ([
|
||||||
'auth' => "{$hostUp}_PARTNERSHIP_AUTH_STACK",
|
'auth' => "{$id}_PARTNERSHIP_AUTH_STACK",
|
||||||
'arrs' => "{$hostUp}_PARTNERSHIP_ARR_STACK",
|
'arrs' => "{$id}_PARTNERSHIP_ARR_STACK",
|
||||||
'services' => "{$hostUp}_PARTNERSHIP_SERVICES_STACK",
|
'services' => "{$id}_PARTNERSHIP_SERVICES_STACK",
|
||||||
] as $label => $var) {
|
] as $label => $var) {
|
||||||
foreach (vv_parse_conf_list($raw, $var) as $xml) {
|
foreach (vv_parse_conf_list($srcRaw, $var) as $xml) {
|
||||||
$n = preg_replace('/^my-|\.xml$/', '', trim($xml));
|
$n = preg_replace('/^my-|\.xml$/', '', trim($xml));
|
||||||
if ($n === '') continue;
|
if ($n === '') continue;
|
||||||
// The container's real name where this host has one, the template's otherwise: a
|
// Only what this host actually runs. The owner's stack lists everything it
|
||||||
// stack entry for something not installed here is still a stack entry.
|
// deploys mesh-wide; a name with no container here is not "always up" here.
|
||||||
$stackOf[$byLower[strtolower($n)] ?? $n] = $label;
|
if (!isset($byLower[strtolower($n)])) continue;
|
||||||
|
$stackOf[$byLower[strtolower($n)]] = $label;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,21 +162,28 @@ foreach ($TIERS as $t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Stack containers refused here, not only greyed out in the picker. The card disables their
|
// Stack containers refused here, not only greyed out in the picker. A disabled select is a
|
||||||
// selects, but a disabled input is a courtesy to the operator, not a constraint on the endpoint —
|
// courtesy to the operator, not a constraint on the endpoint.
|
||||||
// and a tier assignment for a container the partner already runs permanently is a delay attached
|
//
|
||||||
// to something that never stops.
|
// Sourced from the OWNER's conf as well as this host's, for the same reason the read path is: on
|
||||||
|
// a mirror the stack it runs is the owner's declaration, and checking only the local conf would
|
||||||
|
// have let a mirror assign a fallback tier to a container that never stops.
|
||||||
|
$ownerSlotW = strtolower(vv_parse_conf_scalar(vv_read_conf_raw('master.conf'), 'PARTNERSHIP_OWNER_HOST'));
|
||||||
$stackNames = [];
|
$stackNames = [];
|
||||||
|
foreach (array_unique(array_filter([$ownerSlotW, $hostId])) as $slot) {
|
||||||
|
$srcRaw = vv_read_host_conf_raw($slot);
|
||||||
|
$id = strtoupper($slot);
|
||||||
foreach ([
|
foreach ([
|
||||||
"{$hostUp}_PARTNERSHIP_AUTH_STACK",
|
"{$id}_PARTNERSHIP_AUTH_STACK",
|
||||||
"{$hostUp}_PARTNERSHIP_ARR_STACK",
|
"{$id}_PARTNERSHIP_ARR_STACK",
|
||||||
"{$hostUp}_PARTNERSHIP_SERVICES_STACK",
|
"{$id}_PARTNERSHIP_SERVICES_STACK",
|
||||||
] as $var) {
|
] as $var) {
|
||||||
foreach (vv_parse_conf_list($existingRaw, $var) as $xml) {
|
foreach (vv_parse_conf_list($srcRaw, $var) as $xml) {
|
||||||
$n = preg_replace('/^my-|\.xml$/', '', trim($xml));
|
$n = preg_replace('/^my-|\.xml$/', '', trim($xml));
|
||||||
if ($n !== '') $stackNames[strtolower($n)] = true;
|
if ($n !== '') $stackNames[strtolower($n)] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$map = json_decode((string)($_POST['tiers'] ?? ''), true);
|
$map = json_decode((string)($_POST['tiers'] ?? ''), true);
|
||||||
if (!is_array($map)) { echo json_encode(['ok' => false, 'error' => 'tiers must be an object']); exit; }
|
if (!is_array($map)) { echo json_encode(['ok' => false, 'error' => 'tiers must be an object']); exit; }
|
||||||
|
|
||||||
@@ -179,8 +197,11 @@ foreach ($map as $name => $tier) {
|
|||||||
echo json_encode(['ok' => false, 'error' => "No container named $name on this host"]); exit;
|
echo json_encode(['ok' => false, 'error' => "No container named $name on this host"]); exit;
|
||||||
}
|
}
|
||||||
if (isset($stackNames[strtolower((string)$name)])) {
|
if (isset($stackNames[strtolower((string)$name)])) {
|
||||||
|
// Direction-neutral wording: on the owner this container is deployed TO the partner, on a
|
||||||
|
// mirror it was deployed HERE by the owner. Both mean the same thing for coverage — it
|
||||||
|
// runs on both nodes continuously, so there is nothing for a tier to start.
|
||||||
echo json_encode(['ok' => false,
|
echo json_encode(['ok' => false,
|
||||||
'error' => "$name is deployed to the partner as part of a stack — it already runs there, so it cannot be given a fallback tier"]); exit;
|
'error' => "$name belongs to a partnership stack — it runs on both nodes continuously, so it cannot be given a fallback tier"]); exit;
|
||||||
}
|
}
|
||||||
$byTier[$t][] = $known[strtolower((string)$name)];
|
$byTier[$t][] = $known[strtolower((string)$name)];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user