Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add source image url #59

Merged
merged 7 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion builder/nutanix/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type Config struct {
ClusterConfig `mapstructure:",squash"`
VmConfig `mapstructure:",squash"`
ForceDeregister bool `mapstructure:"force_deregister" json:"force_deregister" required:"false"`


ctx interpolate.Context
}
Expand All @@ -52,6 +52,7 @@ type VmDisk struct {
ImageType string `mapstructure:"image_type" json:"image_type" required:"false"`
SourceImageName string `mapstructure:"source_image_name" json:"source_image_name" required:"false"`
SourceImageUUID string `mapstructure:"source_image_uuid" json:"source_image_uuid" required:"false"`
SourceImageURI string `mapstructure:"source_image_uri" json:"source_image_uri" required:"false"`
DiskSizeGB int64 `mapstructure:"disk_size_gb" json:"disk_size_gb" required:"false"`
}

Expand Down
2 changes: 2 additions & 0 deletions builder/nutanix/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 90 additions & 17 deletions builder/nutanix/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ type Driver interface {
//GetImage(string) (*nutanixImage, error)
GetHost(string) (*nutanixHost, error)
PowerOff(string) error
UploadImage(string, VmConfig) (*nutanixImage, error)
UploadImage(string, string, string, VmConfig) (*nutanixImage, error)
DeleteImage(string) error
GetImage(string) (*nutanixImage, error)
SaveVMDisk(string, string, bool) (*nutanixImage, error)
WaitForShutdown(string, <-chan struct{}) bool
}
Expand Down Expand Up @@ -106,6 +107,31 @@ func findSubnetByName(conn *v3.Client, name string) (*v3.SubnetIntentResponse, e

return found[0], nil
}
func sourceImageExists(conn *v3.Client, name string, uri string) (*v3.ImageIntentResponse, error) {
filter := fmt.Sprintf("name==%s", name)
resp, err := conn.V3.ListAllImage(filter)
if err != nil {
return nil, err
}

entities := resp.Entities

found := make([]*v3.ImageIntentResponse, 0)
for _, v := range entities {
if (*v.Spec.Name == name) && (*v.Status.Resources.SourceURI == uri) {
found = append(found, v)
}
}

if len(found) > 1 {
return nil, fmt.Errorf("your query returned more than one result with same Name/URI")
}

if len(found) == 0 {
return nil, nil
}
return found[0], nil
}

func findImageByUUID(conn *v3.Client, uuid string) (*v3.ImageIntentResponse, error) {
return conn.V3.GetImage(uuid)
Expand Down Expand Up @@ -210,6 +236,13 @@ func (d *NutanixDriver) CreateRequest(vm VmConfig) (*v3.VMIntentInput, error) {
for _, disk := range vm.VmDisks {
if disk.ImageType == "DISK_IMAGE" {
image := &v3.ImageIntentResponse{}
if disk.SourceImageURI !="" {
image, err := d.UploadImage(disk.SourceImageURI, "URI", disk.ImageType,vm)
if err != nil {
return nil, fmt.Errorf("error while findImageByUUID, Error %s", err.Error())
}
disk.SourceImageUUID= *image.image.Metadata.UUID
}
if disk.SourceImageUUID != "" {
image, err = findImageByUUID(conn, disk.SourceImageUUID)
if err != nil {
Expand Down Expand Up @@ -260,6 +293,13 @@ func (d *NutanixDriver) CreateRequest(vm VmConfig) (*v3.VMIntentInput, error) {
}
if disk.ImageType == "ISO_IMAGE" {
image := &v3.ImageIntentResponse{}
if disk.SourceImageURI !="" {
image, err := d.UploadImage(disk.SourceImageURI, "URI", disk.ImageType,vm)
if err != nil {
return nil, fmt.Errorf("error while findImageByUUID, Error %s", err.Error())
}
disk.SourceImageUUID= *image.image.Metadata.UUID
}
if disk.SourceImageUUID != "" {
image, err = findImageByUUID(conn, disk.SourceImageUUID)
if err != nil {
Expand Down Expand Up @@ -448,7 +488,7 @@ func (d *NutanixDriver) Delete(vmUUID string) error {
}

//UploadImage (string, VmConfig) (*nutanixImage, error)
func (d *NutanixDriver) UploadImage(imagePath string, vm VmConfig) (*nutanixImage, error) {
func (d *NutanixDriver) UploadImage(imagePath string, sourceType string, imageType string, vm VmConfig) (*nutanixImage, error) {
configCreds := client.Credentials{
URL: fmt.Sprintf("%s:%d", d.ClusterConfig.Endpoint, d.ClusterConfig.Port),
Endpoint: d.ClusterConfig.Endpoint,
Expand Down Expand Up @@ -484,15 +524,24 @@ func (d *NutanixDriver) UploadImage(imagePath string, vm VmConfig) (*nutanixImag
Spec: &v3.Image{
Name: &file,
Resources: &v3.ImageResources{
ImageType: StringPtr("ISO_IMAGE"),
ImageType: &imageType,
InitialPlacementRefList: InitialPlacementRef,
},
},
Metadata: &v3.Metadata{
Kind: StringPtr("image"),
},
}

if sourceType=="URI" {
image, err:=sourceImageExists(conn, file, imagePath)
if err != nil {
return nil, fmt.Errorf("error while check if Image exists, %s", err.Error())
}
if image !=nil {
return &nutanixImage{image: *image}, nil
}
req.Spec.Resources.SourceURI=&imagePath
}
image, err := conn.V3.CreateImage(req)
if err != nil {
return nil, fmt.Errorf("error while Image Create, %s", err.Error())
Expand All @@ -510,24 +559,27 @@ func (d *NutanixDriver) UploadImage(imagePath string, vm VmConfig) (*nutanixImag
time.Sleep(5 * time.Second)
}

err = conn.V3.UploadImage(*image.Metadata.UUID, imagePath)
if err != nil {
return nil, fmt.Errorf("error while upload, %s", err.Error())
}
for {
running, err := conn.V3.GetImage(*image.Metadata.UUID)
if sourceType=="PATH" {
err = conn.V3.UploadImage(*image.Metadata.UUID, imagePath)
if err != nil {
return nil, fmt.Errorf("error while upload status, %s", err.Error())
return nil, fmt.Errorf("error while upload, %s", err.Error())
}
if *running.Status.State == "COMPLETE" {
break
}
time.Sleep(5 * time.Second)
for {
running, err := conn.V3.GetImage(*image.Metadata.UUID)
if err != nil {
return nil, fmt.Errorf("error while upload status, %s", err.Error())
}
if *running.Status.State == "COMPLETE" {
break
}
time.Sleep(5 * time.Second)
}
}
return &nutanixImage{image: *image}, nil

}


func (d *NutanixDriver) DeleteImage(imageUUID string) error {
configCreds := client.Credentials{
URL: fmt.Sprintf("%s:%d", d.ClusterConfig.Endpoint, d.ClusterConfig.Port),
Expand All @@ -549,6 +601,28 @@ func (d *NutanixDriver) DeleteImage(imageUUID string) error {
return nil
}

func (d *NutanixDriver) GetImage(imagename string) (*nutanixImage, error) {
configCreds := client.Credentials{
URL: fmt.Sprintf("%s:%d", d.ClusterConfig.Endpoint, d.ClusterConfig.Port),
Endpoint: d.ClusterConfig.Endpoint,
Username: d.ClusterConfig.Username,
Password: d.ClusterConfig.Password,
Port: string(d.ClusterConfig.Port),
Insecure: d.ClusterConfig.Insecure,
}

conn, err := v3.NewV3Client(configCreds)
if err != nil {
return nil, fmt.Errorf("error while NewV3Client, %s", err.Error())
}

image, err := findImageByName(conn,imagename)
if err != nil {
return nil, fmt.Errorf("error while GetImage, %s", err.Error())
}
return &nutanixImage{image: *image}, nil
}

func (d *NutanixDriver) GetVM(vmUUID string) (*nutanixInstance, error) {

configCreds := client.Credentials{
Expand Down Expand Up @@ -669,6 +743,7 @@ func (d *NutanixDriver) SaveVMDisk(diskUUID string, imageName string, ForceDereg
log.Println("More than one image with given Name found, will not deregister")
} else if *ImageList.Metadata.TotalMatches==1 {
log.Println("Exactly one image with given Name found, will deregister")

resp,err:= conn.V3.DeleteImage(*ImageList.Entities[0].Metadata.UUID)
if err != nil {
return nil, fmt.Errorf("error while DeleteImage, %s", err.Error())
Expand All @@ -687,8 +762,6 @@ func (d *NutanixDriver) SaveVMDisk(diskUUID string, imageName string, ForceDereg
}
return nil, fmt.Errorf("error while Image Delete getting Task Status, %s", err.Error())
}


}
}
req := &v3.ImageIntentInput{
Expand Down
2 changes: 1 addition & 1 deletion builder/nutanix/step_build_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (s *stepBuildVM) Run(ctx context.Context, state multistep.StateBag) multist
if cdPathRaw, ok := state.GetOk("cd_path"); ok {
cdFilesPath := cdPathRaw.(string)
log.Println("temporary iso found, " + cdFilesPath)
cdfilesImage, err := d.UploadImage(cdFilesPath, config.VmConfig)
cdfilesImage, err := d.UploadImage(cdFilesPath, "PATH", "ISO_IMAGE",config.VmConfig)
if err != nil {
ui.Error("Error uploading temporary image:")
ui.Error(err.Error())
Expand Down