@@ -42,7 +42,27 @@ type RegistryConfig struct {
4242 } `yaml:"config"`
4343}
4444
45- const provider = "openstack"
45+ // OpenStackNodeImage represents the structure of the OpenStackNodeImages.
46+ type OpenStackNodeImage struct {
47+ URL string `yaml:"url"`
48+ CreateOpts struct {
49+ Name string `yaml:"name"`
50+ DiskFormat string `yaml:"disk_format"` //nolint:tagliatelle // The `DiskFormat` field in this struct corresponds to the `disk_format` YAML tag
51+ ContainerFormat string `yaml:"container_format"` //nolint:tagliatelle // The `ContainerFormat` field in this struct corresponds to the `container_format` YAML tag
52+ Visibility string `yaml:"visibility"`
53+ } `yaml:"createOpts"`
54+ }
55+
56+ // NodeImages represents the structure of the config.yaml file.
57+ type NodeImages struct {
58+ APIVersion string `yaml:"apiVersion"`
59+ OpenStackNodeImages []OpenStackNodeImage `yaml:"openStackNodeImages"`
60+ }
61+
62+ const (
63+ provider = "openstack"
64+ outputDirectory = "./output"
65+ )
4666
4767func usage () {
4868 fmt .Printf (`%s create-node-images cluster-stack-directory cluster-stack-release-directory
@@ -61,6 +81,7 @@ func main() {
6181 os .Exit (1 )
6282 }
6383 clusterStackPath := os .Args [2 ]
84+ configFilePath := filepath .Join (clusterStackPath , "node-images" , "config.yaml" )
6485 config , err := csctlclusterstack .GetCsctlConfig (clusterStackPath )
6586 if err != nil {
6687 fmt .Println (err .Error ())
@@ -79,17 +100,13 @@ func main() {
79100 method := config .Config .Provider .Config .Method
80101 switch strings .ToLower (method ) {
81102 case "get" :
82- // #nosec G304
83- nodeImageData , err := os .ReadFile (filepath .Join (clusterStackPath , "node-images" , "config.yaml" ))
84- if err != nil {
85- fmt .Printf ("failed to read config.yaml: %v\n " , err )
86- os .Exit (1 )
87- }
88-
89- if err := os .WriteFile (filepath .Join (releaseDir , "node-images.yaml" ), nodeImageData , os .FileMode (0o644 )); err != nil {
90- fmt .Printf ("failed to write config.yaml: %v\n " , err )
103+ // Copy config.yaml to releaseDir as node-images.yaml
104+ dest := filepath .Join (releaseDir , "node-images.yaml" )
105+ if err := copyFile (configFilePath , dest ); err != nil {
106+ fmt .Printf ("Error copying config.yaml to releaseDir: %v\n " , err )
91107 os .Exit (1 )
92108 }
109+ fmt .Println ("config.yaml copied to releaseDir as node-images.yaml successfully!" )
93110 case "build" :
94111 if len (config .Config .Provider .Config .Images ) > 0 {
95112 for _ , image := range config .Config .Provider .Config .Images {
@@ -99,7 +116,7 @@ func main() {
99116 if _ , err := os .Stat (packerImagePath ); err == nil {
100117 fmt .Println ("Running packer build..." )
101118 // #nosec G204
102- cmd := exec .Command ("packer" , "build" , packerImagePath )
119+ cmd := exec .Command ("packer" , "build" , "-var" , "build_name=" + * image , "-var" , "output_directory=" + outputDirectory , packerImagePath )
103120 cmd .Stdout = os .Stdout
104121 cmd .Stderr = os .Stderr
105122 if err := cmd .Run (); err != nil {
@@ -108,7 +125,7 @@ func main() {
108125 }
109126 fmt .Println ("Packer build completed successfully." )
110127
111- registryConfig := filepath .Join (clusterStackPath , "node-images" , "registry.yaml" )
128+ registryConfigPath := filepath .Join (clusterStackPath , "node-images" , "registry.yaml" )
112129
113130 // Get the current working directory
114131 currentDir , err := os .Getwd ()
@@ -118,16 +135,27 @@ func main() {
118135 }
119136
120137 // Path to the image created by the packer
121- // TODO: "output" directory where packer built image should be some variable(registry.yaml?)
122138 // Warning: name of the image created by packer should have same name as the name of the image folder in node-images
123- ouputImagePath := filepath .Join (currentDir , "output" , * image )
139+ ouputImagePath := filepath .Join (currentDir , outputDirectory , * image )
124140
125141 // Push the built image to S3
126- if err := pushToS3 (ouputImagePath , * image , registryConfig ); err != nil {
142+ if err := pushToS3 (ouputImagePath , * image , registryConfigPath ); err != nil {
127143 fmt .Printf ("Error pushing image to S3: %v\n " , err )
128144 os .Exit (1 )
129145 }
130146 // TODO: create node-images.yaml in releaseDir after building and pushing image to registry were successful
147+ // Update URL in config.yaml if it is necessary
148+ if err := updateURLNodeImages (configFilePath , registryConfigPath ); err != nil {
149+ fmt .Printf ("Error updating URL in config.yaml: %v\n " , err )
150+ os .Exit (1 )
151+ }
152+ // Copy config.yaml to releaseDir as node-images.yaml
153+ dest := filepath .Join (releaseDir , "node-images.yaml" )
154+ if err := copyFile (configFilePath , dest ); err != nil {
155+ fmt .Printf ("Error copying config.yaml to releaseDir: %v\n " , err )
156+ os .Exit (1 )
157+ }
158+ fmt .Println ("config.yaml copied to releaseDir as node-images.yaml successfully!" )
131159 } else {
132160 fmt .Printf ("Image folder %s does not exist\n " , packerImagePath )
133161 }
@@ -140,19 +168,19 @@ func main() {
140168 }
141169}
142170
143- func pushToS3 (filePath , fileName , configFilePath string ) error {
144- // Load configuration from YAML file
171+ func pushToS3 (filePath , fileName , registryConfigPath string ) error {
172+ // Load registry configuration from YAML file
145173 // #nosec G304
146- configFile , err := os .Open (configFilePath )
174+ registryConfigFile , err := os .Open (registryConfigPath )
147175 if err != nil {
148- return fmt .Errorf ("error opening config file: %w" , err )
176+ return fmt .Errorf ("error opening registry config file: %w" , err )
149177 }
150- defer configFile .Close ()
178+ defer registryConfigFile .Close ()
151179
152180 var registryConfig RegistryConfig
153- decoder := yaml .NewDecoder (configFile )
181+ decoder := yaml .NewDecoder (registryConfigFile )
154182 if err := decoder .Decode (& registryConfig ); err != nil {
155- return fmt .Errorf ("error decoding config file: %w" , err )
183+ return fmt .Errorf ("error decoding registry config file: %w" , err )
156184 }
157185
158186 // Initialize Minio client
@@ -185,3 +213,79 @@ func pushToS3(filePath, fileName, configFilePath string) error {
185213 }
186214 return nil
187215}
216+
217+ func updateURLNodeImages (configFilePath , registryConfigPath string ) error {
218+ // Read the config.yaml file
219+ // #nosec G304
220+ nodeImageData , err := os .ReadFile (configFilePath )
221+ if err != nil {
222+ return fmt .Errorf ("failed to read config.yaml: %w" , err )
223+ }
224+
225+ // Unmarshal YAML data into NodeImages struct
226+ var nodeImages NodeImages
227+ if err := yaml .Unmarshal (nodeImageData , & nodeImages ); err != nil {
228+ return fmt .Errorf ("failed to unmarshal YAML: %w" , err )
229+ }
230+
231+ // Check if the URL already exists for the given image
232+ var imageURLExists bool
233+ for _ , image := range nodeImages .OpenStackNodeImages {
234+ if image .URL != "" {
235+ imageURLExists = true
236+ break
237+ }
238+ }
239+ // If the URL doesn't exist, update it for the image
240+ if ! imageURLExists {
241+ // Load registry configuration from YAML file
242+ // #nosec G304
243+ registryConfigFile , err := os .Open (registryConfigPath )
244+ if err != nil {
245+ return fmt .Errorf ("error opening registry config file: %w" , err )
246+ }
247+ defer registryConfigFile .Close ()
248+
249+ var registryConfig RegistryConfig
250+ decoder := yaml .NewDecoder (registryConfigFile )
251+ if err := decoder .Decode (& registryConfig ); err != nil {
252+ return fmt .Errorf ("error decoding registry config file: %w" , err )
253+ }
254+ // Generate URL
255+ newURL := fmt .Sprintf ("%s%s/%s/%s" , "https://" , registryConfig .Config .Endpoint , registryConfig .Config .Bucket , "star-wars" )
256+ for i := range nodeImages .OpenStackNodeImages {
257+ nodeImages .OpenStackNodeImages [i ].URL = newURL
258+ break
259+ }
260+
261+ // Marshal the updated struct back to YAML
262+ updatedNodeImageData , err := yaml .Marshal (& nodeImages )
263+ if err != nil {
264+ return fmt .Errorf ("failed to marshal YAML: %w" , err )
265+ }
266+
267+ // Write the updated YAML data back to the file
268+ if err := os .WriteFile (configFilePath , updatedNodeImageData , os .FileMode (0o644 )); err != nil {
269+ return fmt .Errorf ("failed to write config.yaml: %w" , err )
270+ }
271+
272+ fmt .Printf ("URL updated for image: %s\n " , newURL )
273+ } else {
274+ fmt .Printf ("URL already exists for the image\n " )
275+ }
276+ return nil
277+ }
278+
279+ func copyFile (src , dest string ) error {
280+ // #nosec G304
281+ data , err := os .ReadFile (src )
282+ if err != nil {
283+ return fmt .Errorf ("error reading source file: %w" , err )
284+ }
285+
286+ if err := os .WriteFile (dest , data , os .FileMode (0o644 )); err != nil {
287+ return fmt .Errorf ("error writing to destination file: %w" , err )
288+ }
289+
290+ return nil
291+ }
0 commit comments