11package cloud
22
33import (
4+ "bufio"
45 "context"
56 "encoding/json"
67 "fmt"
7- "log/slog"
88 "os"
99 "strings"
1010
@@ -13,9 +13,12 @@ import (
1313
1414const (
1515 cloudInitInstanceFilePath = "/run/cloud-init/instance-data.json"
16+ ignitionMetadataFilePath = "/run/metadata/coreos"
1617 cloudStackCloudName = "cloudstack"
1718)
1819
20+ // metadataInstanceID tries to find the instance ID from either the environment variable NODE_ID,
21+ // or cloud-init or ignition metadata. Returns empty string if not found in any of these sources.
1922func (c * client ) metadataInstanceID (ctx context.Context ) string {
2023 logger := klog .FromContext (ctx )
2124 logger .V (4 ).Info ("Attempting to retrieve metadata from envvar NODE_ID" )
@@ -39,13 +42,32 @@ func (c *client) metadataInstanceID(ctx context.Context) string {
3942
4043 return ciData .V1 .InstanceID
4144 }
42- slog .Error ("cloud-init instance ID is not provided" )
45+ logger .Error (nil , "cloud-init instance ID is not provided" )
4346 } else if os .IsNotExist (err ) {
4447 logger .V (4 ).Info ("File " + cloudInitInstanceFilePath + " does not exist" )
4548 } else {
4649 logger .Error (err , "Cannot read file " + cloudInitInstanceFilePath )
4750 }
4851
52+ // Try Ignition (CoreOS / Flatcar)
53+ logger .V (4 ).Info ("Trying with ignition" )
54+ if _ , err := os .Stat (ignitionMetadataFilePath ); err == nil {
55+ logger .V (4 ).Info ("File " + ignitionMetadataFilePath + " exists" )
56+ instanceID , err := c .readIgnition (ctx , ignitionMetadataFilePath )
57+ if err != nil {
58+ logger .Error (err , "Cannot read ignition metadata" )
59+ } else if instanceID != "" {
60+ logger .V (4 ).Info ("Found CloudStack VM ID from ignition" , "nodeID" , instanceID )
61+
62+ return instanceID
63+ }
64+ logger .Error (nil , "Failed to find instance ID in ignition metadata" )
65+ } else if os .IsNotExist (err ) {
66+ logger .V (4 ).Info ("File " + ignitionMetadataFilePath + " does not exist" )
67+ } else {
68+ logger .Error (err , "Cannot read file " + ignitionMetadataFilePath )
69+ }
70+
4971 logger .V (4 ).Info ("CloudStack VM ID not found in meta-data" )
5072
5173 return ""
@@ -87,3 +109,34 @@ func (c *client) readCloudInit(ctx context.Context, instanceFilePath string) (*c
87109
88110 return & data , nil
89111}
112+
113+ // readIgnition reads the ignition metadata file and returns the instance ID, or empty string if not found.
114+ func (c * client ) readIgnition (ctx context.Context , instanceFilePath string ) (string , error ) {
115+ logger := klog .FromContext (ctx )
116+
117+ f , err := os .Open (instanceFilePath )
118+ if err != nil {
119+ logger .Error (err , "Cannot read file " + instanceFilePath )
120+
121+ return "" , err
122+ }
123+ defer f .Close ()
124+
125+ instanceID := ""
126+ scanner := bufio .NewScanner (f )
127+ for scanner .Scan () {
128+ line := scanner .Text ()
129+ if strings .Contains (line , "COREOS_CLOUDSTACK_INSTANCE_ID" ) {
130+ lineSplit := strings .SplitAfter (line , "=" )
131+ if len (lineSplit ) == 2 {
132+ instanceID = strings .SplitAfter (line , "=" )[1 ]
133+ }
134+ }
135+ }
136+
137+ if err := scanner .Err (); err != nil {
138+ logger .Error (err , "Error scanning ignition metadata" )
139+ }
140+
141+ return instanceID , nil
142+ }
0 commit comments