@@ -41,14 +41,15 @@ type Pod struct {
4141
4242// Manager contains information about running containers in the host.
4343type Manager struct {
44- cgroups * cgroup.Cgroups
45- cgroupsMap map [uint32 ]CgroupDir
46- containerMap map [string ]Container
47- deleted []uint64
48- lock sync.RWMutex // protecting both cgroups and deleted fields
49- enricher runtime.Service
50- bpfMapName string
51- lastAccessNano atomic.Int64 // last datastore access time (Unix nano)
44+ cgroups * cgroup.Cgroups
45+ cgroupsMap map [uint32 ]CgroupDir
46+ containerMap map [string ]Container
47+ deleted []uint64
48+ lock sync.RWMutex // protecting both cgroups and deleted fields
49+ enricher runtime.Service
50+ enrichmentEnabled bool
51+ bpfMapName string
52+ lastAccessNano atomic.Int64 // last datastore access time (Unix nano)
5253}
5354
5455// CgroupDir represents a cgroup dir (which may be a container cgroup dir).
@@ -73,11 +74,12 @@ func New(
7374 error ,
7475) {
7576 containers := & Manager {
76- cgroups : cgroups ,
77- cgroupsMap : make (map [uint32 ]CgroupDir ),
78- containerMap : make (map [string ]Container ),
79- lock : sync.RWMutex {},
80- bpfMapName : mapName ,
77+ cgroups : cgroups ,
78+ cgroupsMap : make (map [uint32 ]CgroupDir ),
79+ containerMap : make (map [string ]Container ),
80+ lock : sync.RWMutex {},
81+ enrichmentEnabled : enrichmentEnabled ,
82+ bpfMapName : mapName ,
8183 }
8284
8385 // Attempt to register enrichers for all supported runtimes.
@@ -111,9 +113,11 @@ func New(
111113
112114// Close executes cleanup logic for Containers object.
113115func (c * Manager ) Close () error {
114- err := c .enricher .Close ()
115- if err != nil {
116- return errfmt .WrapError (err )
116+ if c .enrichmentEnabled {
117+ err := c .enricher .Close ()
118+ if err != nil {
119+ return errfmt .WrapError (err )
120+ }
117121 }
118122 return nil
119123}
@@ -129,7 +133,53 @@ func (c *Manager) GetCgroupVersion() cgroup.CgroupVersion {
129133// Initialize initializes the container manager by populating existing containers.
130134// This method is called automatically by the datastore registry during initialization.
131135func (c * Manager ) Initialize (ctx context.Context ) error {
132- return c .Populate ()
136+ // First, populate containers from cgroup filesystem
137+ if err := c .Populate (); err != nil {
138+ return err
139+ }
140+
141+ // If enrichment is enabled, proactively enrich all discovered containers
142+ if c .enrichmentEnabled {
143+ c .enrichExistingContainers ()
144+ }
145+
146+ return nil
147+ }
148+
149+ // enrichExistingContainers enriches all container root cgroups discovered during population.
150+ // This is called during initialization when enrichment is enabled to ensure containers
151+ // have full metadata (name, image, etc.) available immediately via ListContainers API.
152+ func (c * Manager ) enrichExistingContainers () {
153+ c .lock .RLock ()
154+ var cgroupsToEnrich []uint32
155+ for cgroupId , cgroupDir := range c .cgroupsMap {
156+ // Only enrich container root cgroups that are live
157+ if cgroupDir .ContainerRoot && cgroupDir .expiresAt .IsZero () {
158+ cgroupsToEnrich = append (cgroupsToEnrich , cgroupId )
159+ }
160+ }
161+ c .lock .RUnlock ()
162+
163+ logger .Debugw ("Enriching existing containers at startup" ,
164+ "count" , len (cgroupsToEnrich ))
165+
166+ // Enrich each container (don't hold read lock during enrichment)
167+ enrichedCount := 0
168+ for _ , cgroupId := range cgroupsToEnrich {
169+ _ , err := c .EnrichCgroupInfo (uint64 (cgroupId ))
170+ if err != nil {
171+ // Log but don't fail - some containers may not be enrichable
172+ logger .Debugw ("Failed to enrich existing container" ,
173+ "cgroup_id" , cgroupId ,
174+ "error" , err )
175+ } else {
176+ enrichedCount ++
177+ }
178+ }
179+
180+ logger .Debugw ("Container enrichment at startup completed" ,
181+ "enriched" , enrichedCount ,
182+ "total" , len (cgroupsToEnrich ))
133183}
134184
135185// Populate populates Containers struct by reading mounted proc and cgroups fs.
0 commit comments