@@ -9,9 +9,11 @@ import (
99 "bufio"
1010 "bytes"
1111 "context"
12+ "encoding/json"
1213 "errors"
1314 "fmt"
1415 "io"
16+ "net/http"
1517 "os"
1618 "regexp"
1719 "strings"
@@ -31,6 +33,8 @@ const (
3133 mountInfoLocation = "/proc/self/mountinfo"
3234 osReleaseLocation = "/etc/os-release"
3335
36+ ecsMetadataEnvV4 = "ECS_CONTAINER_METADATA_URI_V4"
37+
3438 k8sKind = "kubepods"
3539 docker = "docker"
3640 containerd = "containerd"
@@ -112,7 +116,20 @@ func (i *Info) IsContainer() (bool, error) {
112116 }
113117 }
114118
115- return containsContainerReference (i .selfCgroupLocation )
119+ ref , err := containsContainerReference (i .selfCgroupLocation )
120+ if ref {
121+ return true , nil
122+ }
123+
124+ if os .Getenv (ecsMetadataEnvV4 ) != "" {
125+ return true , nil
126+ }
127+
128+ if err != nil {
129+ return false , err
130+ }
131+
132+ return false , nil
116133}
117134
118135// ResourceID returns a unique identifier for the resource.
@@ -121,7 +138,7 @@ func (i *Info) IsContainer() (bool, error) {
121138func (i * Info ) ResourceID (ctx context.Context ) (string , error ) {
122139 isContainer , _ := i .IsContainer ()
123140 if isContainer {
124- return i .containerID ()
141+ return i .containerID (ctx )
125142 }
126143
127144 return i .hostID (ctx )
@@ -134,7 +151,7 @@ func (i *Info) ContainerInfo(ctx context.Context) (*v1.Resource_ContainerInfo, e
134151 if err != nil {
135152 return nil , err
136153 }
137- containerId , err := i .containerID ()
154+ containerId , err := i .containerID (ctx )
138155 if err != nil {
139156 return nil , err
140157 }
@@ -203,9 +220,34 @@ func (i *Info) releaseInfo(ctx context.Context, osReleaseLocation string) (*v1.R
203220}
204221
205222// containerID returns the container ID of the current running environment.
206- func (i * Info ) containerID () (string , error ) {
207- containerID , err := containerIDFromMountInfo (i .mountInfoLocation )
208- return uuid .NewMD5 (uuid .NameSpaceDNS , []byte (containerID )).String (), err
223+ func (i * Info ) containerID (ctx context.Context ) (string , error ) {
224+ var (
225+ containerIDMount string
226+ errMount error
227+ )
228+
229+ containerIDMount , errMount = containerIDFromMountInfo (i .mountInfoLocation )
230+ if containerIDMount != "" {
231+ return uuid .NewMD5 (uuid .NameSpaceDNS , []byte (containerIDMount )).String (), nil
232+ }
233+
234+ if metadataURI := os .Getenv (ecsMetadataEnvV4 ); metadataURI != "" {
235+ if cid , errEcs := i .containerIDFromECS (ctx , metadataURI ); errEcs == nil && cid != "" {
236+ return uuid .NewMD5 (uuid .NameSpaceDNS , []byte (cid )).String (), nil
237+ } else if errEcs != nil {
238+ if errMount != nil {
239+ return "" , errMount
240+ }
241+
242+ return "" , errEcs
243+ }
244+ }
245+
246+ if errMount != nil {
247+ return "" , errMount
248+ }
249+
250+ return "" , errors .New ("container ID not found" )
209251}
210252
211253// containsContainerReference checks if the cgroup file contains references to container runtimes.
@@ -367,3 +409,30 @@ func mergeHostAndOsReleaseInfo(
367409 Id : osReleaseInfo [id ],
368410 }
369411}
412+
413+ func (i * Info ) containerIDFromECS (ctx context.Context , uri string ) (string , error ) {
414+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , uri , nil )
415+ if err != nil {
416+ return "" , err
417+ }
418+
419+ resp , err := http .DefaultClient .Do (req )
420+ if err != nil {
421+ return "" , err
422+ }
423+ defer resp .Body .Close ()
424+
425+ if resp .StatusCode != http .StatusOK {
426+ return "" , fmt .Errorf ("metadata endpoint returned status %d" , resp .StatusCode )
427+ }
428+
429+ var metadata struct {
430+ DockerId string `json:"DockerId"`
431+ }
432+
433+ if err = json .NewDecoder (resp .Body ).Decode (& metadata ); err != nil {
434+ return "" , err
435+ }
436+
437+ return metadata .DockerId , nil
438+ }
0 commit comments