-
Notifications
You must be signed in to change notification settings - Fork 2
fix: match autostart membership to what the UI renders #54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -314,24 +314,60 @@ function syncContainerOrder(string $type): void { | |
| return; | ||
| } | ||
|
|
||
| // `folder.view3: <name>` label claims, keyed by container name. getDockerContainers() | ||
| // carries no Labels, so read them from the same raw endpoint readInfo() uses. | ||
| $ctLabels = []; | ||
| $rawCts = $dockerClient->getDockerJSON("/containers/json?all=1"); | ||
| // Fail closed. A failed or partial read yields no label claims, and the order below would | ||
| // then write label-assigned containers back out as unassigned — the same hazard $ctListComplete | ||
| // guards against above, so abort rather than fall through to the permissive path. | ||
| if (!is_array($rawCts) || count($rawCts) < count($allContainerNames)) { | ||
| fv3_debug_log("syncContainerOrder: label read unavailable or incomplete, aborting before write"); | ||
| return; | ||
| } | ||
| foreach ($rawCts as $rc) { | ||
| $rcName = is_array($rc) ? ltrim($rc['Names'][0] ?? '', '/') : ''; | ||
| if ($rcName === '') { | ||
| fv3_debug_log("syncContainerOrder: unnamed container in label read, aborting before write"); | ||
| return; | ||
| } | ||
| $rcLabel = $rc['Labels']['folder.view3'] ?? ''; | ||
| if (is_string($rcLabel) && $rcLabel !== '') { $ctLabels[$rcName] = $rcLabel; } | ||
| } | ||
| $folderNameSet = []; | ||
| foreach ($folders as $folder) { | ||
| if (isset($folder['name'])) { $folderNameSet[$folder['name']] = true; } | ||
| } | ||
|
|
||
| $folderContainers = []; | ||
| $folderNames = []; | ||
| $assignedContainers = []; | ||
| // Explicit members of any folder beat regex matches elsewhere (issue #46) | ||
| // Explicit members and label claims of any folder beat regex matches elsewhere (issue #46) | ||
| $explicitAssigned = []; | ||
| foreach ($folders as $folder) { | ||
| $explicitAssigned = array_merge($explicitAssigned, $folder['containers'] ?? []); | ||
| } | ||
| foreach ($ctLabels as $ctName => $ctLabel) { | ||
| if (isset($folderNameSet[$ctLabel])) { $explicitAssigned[] = $ctName; } | ||
| } | ||
|
Comment on lines
346
to
+352
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Preserve explicit membership over label membership.
If container Proposed fix- $explicitAssigned = [];
+ $explicitMembers = [];
foreach ($folders as $folder) {
- $explicitAssigned = array_merge($explicitAssigned, $folder['containers'] ?? []);
+ $explicitMembers = array_merge($explicitMembers, $folder['containers'] ?? []);
}
+ $explicitAssigned = $explicitMembers;
foreach ($ctLabels as $ctName => $ctLabel) {
- if (isset($folderNameSet[$ctLabel])) { $explicitAssigned[] = $ctName; }
+ if (isset($folderNameSet[$ctLabel]) && !in_array($ctName, $explicitMembers, true)) {
+ $explicitAssigned[] = $ctName;
+ }
}
- if ($ctLabel === ($folder['name'] ?? null) && !in_array($ctName, $members)) {
+ if ($ctLabel === ($folder['name'] ?? null)
+ && !in_array($ctName, $members, true)
+ && !in_array($ctName, $explicitMembers, true)) {Also applies to: 356-358 🤖 Prompt for AI Agents
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Declining this one for the scope of this PR, and tracking it separately. The conflict is real and reachable — The reason not to fix it here: Worth noting the two also iterate differently — PHP walks Explicit membership beating a label is the better rule; it just needs applying to both sides in one change. Filed separately. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The follow-up should define the same explicit-membership precedence in both 🐇 ✏️ Learnings added
You are interacting with an AI system. |
||
| foreach ($folders as $folderId => $folder) { | ||
| $members = $folder['containers'] ?? []; | ||
| if (!empty($folder['regex'])) { | ||
| // is_string + trim, not empty(): empty("0") is true in PHP, so a regex of "0" was | ||
| // silently dropped while docker.js applied it. The type check mirrors docker.js and | ||
| // keeps a non-string regex from fataling trim() (TypeError on PHP 8). | ||
| if (is_string($folder['regex'] ?? null) && trim($folder['regex']) !== '') { | ||
| $regex = '/' . str_replace('/', '\/', $folder['regex']) . '/'; | ||
| foreach ($allContainerNames as $name) { | ||
| if (@preg_match($regex, $name) && !in_array($name, $members) && !in_array($name, $explicitAssigned)) { | ||
| $members[] = $name; | ||
| } | ||
| } | ||
| } | ||
| foreach ($ctLabels as $ctName => $ctLabel) { | ||
| if ($ctLabel === ($folder['name'] ?? null) && !in_array($ctName, $members)) { | ||
| $members[] = $ctName; | ||
| } | ||
| } | ||
| $members = array_values(array_filter($members, function($m) use ($allContainerNames, $assignedContainers) { | ||
| return in_array($m, $allContainerNames) && !in_array($m, $assignedContainers); | ||
| })); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.