You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Continue of #16599, #16613 - manage and group dynamic containers in Dynamic Grid under a compose stack (compatible when running with Docker Compose, Podman, or other platforms based on grouping labels defined by the user).
Enhanced filtering to support multiple orchestration systems:
Docker Compose: com.docker.compose.project
Podman Compose: io.podman.compose.project
User-defined grouping labels via CLI --docker-grouping-labels or TOML config key grouping-labels
✅ Platform agnostic - Works with any container orchestration system
✅ User configurable - No code changes needed for new platforms
✅ Backward compatible - Existing setups continue to work
✅ Flexible - Supports multiple custom labels simultaneously
✅ Safe - Only project labels are copied, service labels are excluded
Makes the Dynamic Grid Docker integration truly platform-independent and ready for any container orchestration system.
🔧 Implementation Notes
💡 Additional Considerations
🔄 Types of changes
Cleanup (formatting, renaming)
Bug fix (backwards compatible)
New feature (non-breaking change which adds functionality and tests!)
Breaking change (fix or feature that would cause existing functionality to change)
PR Type
Enhancement
Description
Add configurable grouping labels for Docker containers
Support multiple orchestration systems (Docker Compose, Podman Compose)
Allow user-defined custom labels via CLI and TOML config
Filter and apply only project-level labels to containers
Diagram Walkthrough
flowchart LR
A["DockerFlags"] -->|"adds grouping-labels parameter"| B["DockerOptions"]
B -->|"reads custom labels from config"| C["getGroupingLabels"]
C -->|"filters Docker/Podman/custom labels"| D["DockerSessionFactory"]
D -->|"applies labels to containers"| E["Browser & Video Containers"]
Below is a summary of compliance checks for this PR:
Security Compliance
⚪
Label injection risk
Description: User-supplied label keys from configuration are copied directly to container labels, which could enable label injection to unintentionally join containers to existing compose/podman projects or leak sensitive grouping metadata; consider validating/whitelisting allowed keys or scoping with a Selenium-specific prefix. DockerOptions.java [270-289]
Referred Code
List<String> customLabelKeys =
config.getAll(DOCKER_SECTION, "grouping-labels").orElseGet(Collections::emptyList);
Map<String, String> allLabels = info.get().getLabels();
// Filter for project/grouping labels that work across orchestration systems// Keep only project identifiers, exclude service-specific labels to prevent// exit monitoring in Docker Compose, Podman Compose, etc.returnallLabels.entrySet().stream()
.filter(
entry -> {
Stringkey = entry.getKey();
// Docker Compose project labelif (key.equals("com.docker.compose.project")) returntrue;
// Podman Compose project labelif (key.equals("io.podman.compose.project")) returntrue;
// Custom user-defined grouping labelsif (customLabelKeys.contains(key)) returntrue;
returnfalse;
})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Objective: To create a detailed and reliable record of critical system actions for security analysis and compliance.
Status: Missing auditing: New logic that reads and applies container grouping labels is not accompanied by any logging to audit which labels were used or applied, which could hinder reconstructing actions.
Referred Code
// Get custom grouping labels from configurationList<String> customLabelKeys =
config.getAll(DOCKER_SECTION, "grouping-labels").orElseGet(Collections::emptyList);
Map<String, String> allLabels = info.get().getLabels();
// Filter for project/grouping labels that work across orchestration systems// Keep only project identifiers, exclude service-specific labels to prevent// exit monitoring in Docker Compose, Podman Compose, etc.returnallLabels.entrySet().stream()
.filter(
entry -> {
Stringkey = entry.getKey();
// Docker Compose project labelif (key.equals("com.docker.compose.project")) returntrue;
// Podman Compose project labelif (key.equals("io.podman.compose.project")) returntrue;
// Custom user-defined grouping labelsif (customLabelKeys.contains(key)) returntrue;
returnfalse;
})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Generic: Robust Error Handling and Edge Case Management
Objective: Ensure comprehensive error handling that provides meaningful context and graceful degradation
Status: Input validation: The code consumes user-provided grouping label keys from configuration without validating for emptiness, duplicates, or malformed values, and proceeds silently with an empty set if absent.
Referred Code
List<String> customLabelKeys =
config.getAll(DOCKER_SECTION, "grouping-labels").orElseGet(Collections::emptyList);
Map<String, String> allLabels = info.get().getLabels();
// Filter for project/grouping labels that work across orchestration systems// Keep only project identifiers, exclude service-specific labels to prevent// exit monitoring in Docker Compose, Podman Compose, etc.returnallLabels.entrySet().stream()
.filter(
entry -> {
Stringkey = entry.getKey();
// Docker Compose project labelif (key.equals("com.docker.compose.project")) returntrue;
// Podman Compose project labelif (key.equals("io.podman.compose.project")) returntrue;
// Custom user-defined grouping labelsif (customLabelKeys.contains(key)) returntrue;
returnfalse;
Generic: Security-First Input Validation and Data Handling
Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent vulnerabilities
Status: Unvalidated labels: User-configurable grouping labels from configuration are passed directly to container label sets without normalization or validation, which could allow unintended or conflicting labels.
✅ Improve filtering logic for performanceSuggestion Impact:The commit introduced a HashSet of grouping keys and replaced the multi-branch filter logic with a contains check against the Set, matching the suggested optimization.
code diff:
@@ -270,22 +272,14 @@
List<String> customLabelKeys =
config.getAll(DOCKER_SECTION, "grouping-labels").orElseGet(Collections::emptyList);
+ Set<String> groupingKeys = new HashSet<>(customLabelKeys);+ groupingKeys.add("com.docker.compose.project");+ groupingKeys.add("io.podman.compose.project");+
Map<String, String> allLabels = info.get().getLabels();
- // Filter for project/grouping labels that work across orchestration systems- // Keep only project identifiers, exclude service-specific labels to prevent- // exit monitoring in Docker Compose, Podman Compose, etc.+ // Filter for grouping labels that work across orchestration systems
return allLabels.entrySet().stream()
- .filter(- entry -> {- String key = entry.getKey();- // Docker Compose project label- if (key.equals("com.docker.compose.project")) return true;- // Podman Compose project label- if (key.equals("io.podman.compose.project")) return true;- // Custom user-defined grouping labels- if (customLabelKeys.contains(key)) return true;- return false;- })+ .filter(entry -> groupingKeys.contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Refactor the label filtering logic to use a Set for grouping keys instead of a List and multiple if conditions, improving lookup performance and code clarity.
// Get custom grouping labels from configuration
List<String> customLabelKeys =
config.getAll(DOCKER_SECTION, "grouping-labels").orElseGet(Collections::emptyList);
++Set<String> groupingKeys = new HashSet<>(customLabelKeys);+groupingKeys.add("com.docker.compose.project");+groupingKeys.add("io.podman.compose.project");
Map<String, String> allLabels = info.get().getLabels();
// Filter for project/grouping labels that work across orchestration systems
// Keep only project identifiers, exclude service-specific labels to prevent
// exit monitoring in Docker Compose, Podman Compose, etc.
return allLabels.entrySet().stream()
- .filter(- entry -> {- String key = entry.getKey();- // Docker Compose project label- if (key.equals("com.docker.compose.project")) return true;- // Podman Compose project label- if (key.equals("io.podman.compose.project")) return true;- // Custom user-defined grouping labels- if (customLabelKeys.contains(key)) return true;- return false;- })+ .filter(entry -> groupingKeys.contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
[Suggestion processed]
Suggestion importance[1-10]: 6
__
Why: The suggestion correctly proposes using a Set for more efficient lookups, which improves performance and code readability, aligning with best practices.
Low
Learned best practice
Validate custom grouping labels
Validate that configured grouping-labels are non-empty strings and reject invalid entries with a clear message to avoid silent misconfiguration.
Why:
Relevant best practice - Guard external configuration values with validation and clear errors before use.
Low
Clarify groupingLabels purpose
Add a concise field-level comment clarifying that groupingLabels are non-service-specific labels used to group dynamic containers across orchestrators.
+// Labels that identify a project/group across orchestrators (e.g., Docker/Podman Compose, custom),+// excluding service-specific labels. Used to group dynamic containers for lifecycle handling.
private final Map<String, String> groupingLabels;
Apply / Chat
Suggestion importance[1-10]: 5
__
Why:
Relevant best practice - Enforce accurate and consistent naming/documentation to match behavior and aid maintainability.
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
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.
User description
🔗 Related Issues
💥 What does this PR do?
Continue of #16599, #16613 - manage and group dynamic containers in Dynamic Grid under a compose stack (compatible when running with Docker Compose, Podman, or other platforms based on grouping labels defined by the user).
Enhanced filtering to support multiple orchestration systems:
com.docker.compose.projectio.podman.compose.project--docker-grouping-labelsor TOML config keygrouping-labels✅ Platform agnostic - Works with any container orchestration system
✅ User configurable - No code changes needed for new platforms
✅ Backward compatible - Existing setups continue to work
✅ Flexible - Supports multiple custom labels simultaneously
✅ Safe - Only project labels are copied, service labels are excluded
Makes the Dynamic Grid Docker integration truly platform-independent and ready for any container orchestration system.
🔧 Implementation Notes
💡 Additional Considerations
🔄 Types of changes
PR Type
Enhancement
Description
Add configurable grouping labels for Docker containers
Support multiple orchestration systems (Docker Compose, Podman Compose)
Allow user-defined custom labels via CLI and TOML config
Filter and apply only project-level labels to containers
Diagram Walkthrough
File Walkthrough
DockerFlags.java
Add CLI parameter for custom grouping labelsjava/src/org/openqa/selenium/grid/node/docker/DockerFlags.java
--docker-grouping-labelsCLI parametergrouping-labelsazure.container.group,aws.ecs.clusterDockerOptions.java
Enhance label filtering for multiple orchestration systemsjava/src/org/openqa/selenium/grid/node/docker/DockerOptions.java
getComposeLabels()togetGroupingLabels()for claritycustom labels
service-specific labels
DockerSessionFactory.java
Refactor to use generic grouping labelsjava/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java
composeLabelsfield togroupingLabelsthroughout classcom.docker.compose.oneoff=Falselabel logic