Skip to content

Commit 1ce4c99

Browse files
Add update url logic in build method
Signed-off-by: michal.gubricky <michal.gubricky@dnation.cloud>
1 parent ba5fc42 commit 1ce4c99

File tree

4 files changed

+135
-28
lines changed

4 files changed

+135
-28
lines changed

csctlopenstack/csctlopenstack_main.go

Lines changed: 126 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4767
func 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+
}

csctlopenstack/example/cluster-stacks/openstack/ferrol/node-images/control-plane-ubuntu-2204/image.json.pkr.hcl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ packer {
88
}
99

1010
locals {
11-
output_directory = "./output"
1211
scripts = "${path.root}/scripts"
1312
http_directory = "${path.root}/http"
14-
vm_name = "${var.build_name}"
1513
}
1614

1715
source "qemu" "ubuntu" {
@@ -31,13 +29,13 @@ source "qemu" "ubuntu" {
3129
iso_url = "${var.image_url}"
3230
memory = "${var.memory}"
3331
net_device = "virtio-net"
34-
output_directory = "${local.output_directory}"
32+
output_directory = "${var.output_directory}"
3533
qemu_binary = "${var.qemu_binary}"
3634
shutdown_command = "echo '${var.ssh_password}' | sudo -S -E sh -c 'usermod -L ${var.ssh_username} && ${var.shutdown_command}'"
3735
ssh_password = "${var.ssh_password}"
3836
ssh_username = "${var.ssh_username}"
3937
ssh_wait_timeout = "30m"
40-
vm_name = "${local.vm_name}"
38+
vm_name = "${var.build_name}"
4139
}
4240

4341
build {

csctlopenstack/example/cluster-stacks/openstack/ferrol/node-images/control-plane-ubuntu-2204/variables.pkr.hcl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ variable "boot_wait" {
1111

1212
variable "build_name" {
1313
type = string
14-
default = "control-plane-ubuntu-2204"
14+
default = ""
1515
}
1616

1717
variable "cpus" {
@@ -64,6 +64,11 @@ variable "os" {
6464
default = "ubuntu-22.04"
6565
}
6666

67+
variable "output_directory" {
68+
type = string
69+
default = ""
70+
}
71+
6772
variable "qemu_binary" {
6873
type = string
6974
default = "qemu-system-x86_64"

csctlopenstack/example/cluster-stacks/openstack/ferrol/node-images/registry.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ config:
33
endpoint: <endpoint>
44
bucket: <bucket_name>
55
accessKey: <access_key>
6-
secretKey: <secret_key>
6+
secretKey: <secret_key>

0 commit comments

Comments
 (0)