|
7 | 7 | "fmt"
|
8 | 8 | "path/filepath"
|
9 | 9 | "regexp"
|
| 10 | + "sort" |
10 | 11 | "strings"
|
11 | 12 | )
|
12 | 13 |
|
@@ -78,17 +79,65 @@ func containerInfoFromProc(proc procInfo) (*Container, error) {
|
78 | 79 | return c, nil
|
79 | 80 | }
|
80 | 81 |
|
81 |
| -// containerInfoFromCgroupPaths looks for container IDs in cgroup paths |
| 82 | +// matchResult stores information about a successful regex match. |
| 83 | +type matchResult struct { |
| 84 | + Runtime ContainerRuntime |
| 85 | + ID string |
| 86 | + StartIdx int // The starting index of the match in the original string |
| 87 | + MatchLen int // The length of the overall matched string |
| 88 | +} |
| 89 | + |
| 90 | +// containerInfoFromCgroupPaths iterates through cgroup paths, finds all possible matches, |
| 91 | +// and selects the "deepest" match (i.e., the one that starts latest in the string). |
82 | 92 | func containerInfoFromCgroupPaths(paths []string) (ContainerRuntime, string) {
|
| 93 | + var bestMatch *matchResult |
| 94 | + |
83 | 95 | for _, path := range paths {
|
| 96 | + var currentPathMatches []matchResult |
| 97 | + |
| 98 | + // Find all matches for the current path |
84 | 99 | for pattern, runtime := range containerPatterns {
|
85 |
| - if matches := pattern.FindStringSubmatch(path); len(matches) > 1 { |
86 |
| - return runtime, matches[1] |
| 100 | + // FindAllStringSubmatchIndex returns all successive matches of the expression, |
| 101 | + // returning the start and end indices of the match and its subexpressions. |
| 102 | + matches := pattern.FindAllStringSubmatchIndex(path, -1) |
| 103 | + if len(matches) > 0 { |
| 104 | + for _, match := range matches { |
| 105 | + // match[0] is start index of overall match, match[1] is end index of overall match |
| 106 | + // match[2] is start index of first capturing group, match[3] is end index of first capturing group |
| 107 | + if len(match) >= 4 { // Ensure there's a capturing group |
| 108 | + id := path[match[2]:match[3]] |
| 109 | + currentPathMatches = append(currentPathMatches, matchResult{ |
| 110 | + Runtime: runtime, |
| 111 | + ID: id, |
| 112 | + StartIdx: match[0], |
| 113 | + MatchLen: match[1] - match[0], |
| 114 | + }) |
| 115 | + } |
| 116 | + } |
87 | 117 | }
|
88 | 118 | }
|
| 119 | + |
| 120 | + // If multiple matches are found for the current path, pick the "deepest" one. |
| 121 | + // "Deepest" is defined as the match with the highest starting index. |
| 122 | + if len(currentPathMatches) > 0 { |
| 123 | + sort.Slice(currentPathMatches, func(i, j int) bool { |
| 124 | + // Sort by StartIdx in descending order to get the deepest match first. |
| 125 | + return currentPathMatches[i].StartIdx > currentPathMatches[j].StartIdx |
| 126 | + }) |
| 127 | + |
| 128 | + // The first element after sorting will be the deepest match for this path. |
| 129 | + // Compare it with the overall bestMatch found so far across all paths. |
| 130 | + if bestMatch == nil || currentPathMatches[0].StartIdx > bestMatch.StartIdx { |
| 131 | + bestMatch = ¤tPathMatches[0] |
| 132 | + } |
| 133 | + } |
| 134 | + } |
| 135 | + |
| 136 | + if bestMatch != nil { |
| 137 | + return bestMatch.Runtime, bestMatch.ID |
89 | 138 | }
|
90 | 139 |
|
91 |
| - return UnknownRuntime, "" |
| 140 | + return UnknownRuntime, "" // No match found |
92 | 141 | }
|
93 | 142 |
|
94 | 143 | // containerNameFromEnv extracts container metadata from environment variables
|
|
0 commit comments