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

F-27: enable vm config update #145

Merged
merged 5 commits into from
Oct 1, 2021
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ BUG FIXES:

ENHANCEMENTS:
* resources/opennebula_virtual_network: Enhance address range update
* resources/opennebula_virtual_machine: enable context, os, graphics sections update

## 0.3.0 (December 17, 2020)

Expand Down
102 changes: 93 additions & 9 deletions opennebula/resource_opennebula_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ func resourceOpennebulaVirtualMachineUpdate(d *schema.ResourceData, meta interfa

// TODO: fix it after 5.10 release
// Force the "decrypt" bool to false to keep ONE 5.8 behavior
vm, err := vmc.Info(false)
vmInfos, err := vmc.Info(false)
if err != nil {
return err
}
Expand All @@ -879,8 +879,8 @@ func resourceOpennebulaVirtualMachineUpdate(d *schema.ResourceData, meta interfa
}
// TODO: fix it after 5.10 release
// Force the "decrypt" bool to false to keep ONE 5.8 behavior
vm, err := vmc.Info(false)
log.Printf("[INFO] Successfully updated name (%s) for VM ID %x\n", vm.Name, vm.ID)
vmInfos, err := vmc.Info(false)
log.Printf("[INFO] Successfully updated name (%s) for VM ID %x\n", vmInfos.Name, vmInfos.ID)
}

if d.HasChange("permissions") && d.Get("permissions") != "" {
Expand All @@ -890,28 +890,36 @@ func resourceOpennebulaVirtualMachineUpdate(d *schema.ResourceData, meta interfa
return err
}
}
log.Printf("[INFO] Successfully updated Permissions VM %s\n", vm.Name)
log.Printf("[INFO] Successfully updated Permissions VM %s\n", vmInfos.Name)
}

if d.HasChange("group") {
err := changeVmGroup(d, meta)
if err != nil {
return err
}
log.Printf("[INFO] Successfully updated group for VM %s\n", vm.Name)
log.Printf("[INFO] Successfully updated group for VM %s\n", vmInfos.Name)
}

if d.HasChange("tags") {
tagsInterface := d.Get("tags").(map[string]interface{})
for k, v := range tagsInterface {
vm.UserTemplate.Del(strings.ToUpper(k))
vm.UserTemplate.AddPair(strings.ToUpper(k), v.(string))
vmInfos.UserTemplate.Del(strings.ToUpper(k))
vmInfos.UserTemplate.AddPair(strings.ToUpper(k), v.(string))
}

err = vmc.Update(vm.UserTemplate.String(), 1)
err = vmc.Update(vmInfos.UserTemplate.String(), 1)
if err != nil {
return err
}

timeout := d.Get("timeout").(int)

_, err = waitForVMState(vmc, timeout, "RUNNING")
if err != nil {
return fmt.Errorf(
"waiting for virtual machine (ID:%d) to be in state %s: %s", vmc.ID, strings.Join(vmDiskUpdateReadyStates, " "), err)
}
}

if d.HasChange("disk") {
Expand Down Expand Up @@ -1045,6 +1053,7 @@ func resourceOpennebulaVirtualMachineUpdate(d *schema.ResourceData, meta interfa

// Attach the nics
for _, nicIf := range toAttach {

nicConfig := nicIf.(map[string]interface{})

nicTpl := makeNICVector(nicConfig)
Expand All @@ -1056,6 +1065,72 @@ func resourceOpennebulaVirtualMachineUpdate(d *schema.ResourceData, meta interfa
}
}

updateConf := false
tpl := vm.NewTemplate()

if d.HasChange("os") {
updateConf = true

log.Printf("[DEBUG] Update os")

//Generate OS definition
addOS(tpl, d.Get("os").([]interface{}))

}

if d.HasChange("graphics") {
updateConf = true

log.Printf("[DEBUG] Update graphics")

//Generate GRAPHICS definition
addGraphic(tpl, d.Get("graphics").([]interface{}))

}

if d.HasChange("context") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also should update Provider doc as this is only possible from release 5.10 of OpenNebula.
Chaning context on oldest release won't have effect

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updateconf method seems a bit older than that.
It seems to be introduced by this commit: OpenNebula/one@32e1560

From version 5.0 of OpenNebula


updateConf = true

log.Printf("[DEBUG] Update context")

contextVec := tpl.AddVector("CONTEXT")

//Generate CONTEXT definition
context := d.Get("context").(map[string]interface{})

// Add new context elements to the template
for key, value := range context {
keyUp := strings.ToUpper(key)
contextVec.AddPair(keyUp, fmt.Sprint(value))
}

}

if updateConf == true {

timeout := d.Get("timeout").(int)

_, err = waitForVMState(vmc, timeout, "RUNNING")
if err != nil {
return fmt.Errorf(
"waiting for virtual machine (ID:%d) to be in state %s: %s", vmc.ID, strings.Join(vmDiskUpdateReadyStates, " "), err)
}

log.Printf("[INFO] Update VM configuration: %s", tpl.String())

err := vmc.UpdateConf(tpl.String())
if err != nil {
return fmt.Errorf("vm updateconf: %s", err)
}

_, err = waitForVMState(vmc, timeout, "RUNNING")
if err != nil {
return fmt.Errorf(
"waiting for virtual machine (ID:%d) to be in state %s: %s", vmc.ID, strings.Join(vmDiskUpdateReadyStates, " "), err)
}
}

return resourceOpennebulaVirtualMachineRead(d, meta)
}

Expand All @@ -1071,11 +1146,20 @@ func resourceOpennebulaVirtualMachineDelete(d *schema.ResourceData, meta interfa
return err
}

// wait state to be ready
timeout := d.Get("timeout").(int)

_, err = waitForVMState(vmc, timeout, "RUNNING")
if err != nil {
return fmt.Errorf(
"waiting for virtual machine (ID:%d) to be in state %s: %s", vmc.ID, strings.Join(vmDiskUpdateReadyStates, " "), err)
}

if err = vmc.TerminateHard(); err != nil {
return err
}

timeout := d.Get("timeout").(int)
//timeout := d.Get("timeout").(int)
ret, err := waitForVMState(vmc, timeout, "DONE")
if err != nil {

Expand Down
88 changes: 86 additions & 2 deletions opennebula/resource_opennebula_virtual_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ func TestAccVirtualMachine(t *testing.T) {
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "permissions", "642"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "memory", "128"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "cpu", "0.1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.%", "3"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.NETWORK", "YES"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.TESTVAR", "TEST"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.keymap", "en-us"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.listen", "0.0.0.0"),
Expand Down Expand Up @@ -63,6 +66,48 @@ func TestAccVirtualMachine(t *testing.T) {
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "group", "oneadmin"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "memory", "196"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "cpu", "0.2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.%", "4"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.NETWORK", "YES"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.TESTVAR", "TEST"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.TESTVAR2", "TEST2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.keymap", "en-us"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.listen", "0.0.0.0"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.type", "VNC"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "os.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "os.0.arch", "x86_64"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "os.0.boot", ""),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "disk.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "tags.%", "3"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "tags.env", "dev"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "tags.customer", "test"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "tags.version", "2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "timeout", "4"),
resource.TestCheckResourceAttrSet("opennebula_virtual_machine.test", "uid"),
resource.TestCheckResourceAttrSet("opennebula_virtual_machine.test", "gid"),
resource.TestCheckResourceAttrSet("opennebula_virtual_machine.test", "uname"),
resource.TestCheckResourceAttrSet("opennebula_virtual_machine.test", "gname"),
testAccCheckVirtualMachinePermissions(&shared.Permissions{
OwnerU: 1,
OwnerM: 1,
OwnerA: 0,
GroupU: 1,
GroupM: 1,
}),
),
},
{
Config: testAccVirtualMachineContextUpdate,
Check: resource.ComposeTestCheckFunc(
testAccSetDSdummy(),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "name", "test-virtual_machine-renamed"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "permissions", "660"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "group", "oneadmin"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "memory", "196"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "cpu", "0.2"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.%", "3"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.NETWORK", "YES"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "context.TESTVAR", "UPDATE"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.#", "1"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.keymap", "en-us"),
resource.TestCheckResourceAttr("opennebula_virtual_machine.test", "graphics.0.listen", "0.0.0.0"),
Expand Down Expand Up @@ -465,8 +510,9 @@ resource "opennebula_virtual_machine" "test" {
cpu = 0.1

context = {
NETWORK = "YES"
SET_HOSTNAME = "$NAME"
TESTVAR = "TEST"
NETWORK = "YES"
SET_HOSTNAME = "$NAME"
}

graphics {
Expand Down Expand Up @@ -539,6 +585,44 @@ resource "opennebula_virtual_machine" "test" {
cpu = 0.2

context = {
TESTVAR = "TEST"
TESTVAR2 = "TEST2"
NETWORK = "YES"
SET_HOSTNAME = "$NAME"
}

graphics {
type = "VNC"
listen = "0.0.0.0"
keymap = "en-us"
}

disk {}

os {
arch = "x86_64"
boot = ""
}

tags = {
env = "dev"
customer = "test"
version = "2"
}
timeout = 4
}
`

var testAccVirtualMachineContextUpdate = `
resource "opennebula_virtual_machine" "test" {
name = "test-virtual_machine-renamed"
group = "oneadmin"
permissions = "660"
memory = 196
cpu = 0.2

context = {
TESTVAR = "UPDATE"
NETWORK = "YES"
SET_HOSTNAME = "$NAME"
}
Expand Down
68 changes: 39 additions & 29 deletions opennebula/shared_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,43 @@ func makeNICVector(nicConfig map[string]interface{}) *shared.NIC {
return nic
}

func addOS(tpl *vm.Template, os []interface{}) {

for i := 0; i < len(os); i++ {
osconfig := os[i].(map[string]interface{})
tpl.AddOS(vmk.Arch, osconfig["arch"].(string))
tpl.AddOS(vmk.Boot, osconfig["boot"].(string))
}

}

func addGraphic(tpl *vm.Template, graphics []interface{}) {

for i := 0; i < len(graphics); i++ {
graphicsconfig := graphics[i].(map[string]interface{})

for k, v := range graphicsconfig {

if isEmptyValue(reflect.ValueOf(v)) {
continue
}

switch k {
case "listen":
tpl.AddIOGraphic(vmk.Listen, v.(string))
case "type":
tpl.AddIOGraphic(vmk.GraphicType, v.(string))
case "port":
tpl.AddIOGraphic(vmk.Port, v.(string))
case "keymap":
tpl.AddIOGraphic(vmk.Keymap, v.(string))
}

}

}
}

func generateVMTemplate(d *schema.ResourceData, tpl *vm.Template) {

//Generate NIC definition
Expand Down Expand Up @@ -327,37 +364,10 @@ func generateVMTemplate(d *schema.ResourceData, tpl *vm.Template) {
}

//Generate GRAPHICS definition
graphics := d.Get("graphics").([]interface{})
for i := 0; i < len(graphics); i++ {
graphicsconfig := graphics[i].(map[string]interface{})

for k, v := range graphicsconfig {

if isEmptyValue(reflect.ValueOf(v)) {
continue
}

switch k {
case "listen":
tpl.AddIOGraphic(vmk.Listen, v.(string))
case "type":
tpl.AddIOGraphic(vmk.GraphicType, v.(string))
case "port":
tpl.AddIOGraphic(vmk.Port, v.(string))
case "keymap":
tpl.AddIOGraphic(vmk.Keymap, v.(string))
}

}
}
addGraphic(tpl, d.Get("graphics").([]interface{}))

//Generate OS definition
os := d.Get("os").([]interface{})
for i := 0; i < len(os); i++ {
osconfig := os[i].(map[string]interface{})
tpl.AddOS(vmk.Arch, osconfig["arch"].(string))
tpl.AddOS(vmk.Boot, osconfig["boot"].(string))
}
addOS(tpl, d.Get("os").([]interface{}))

//Generate CPU Model definition
cpumodel := d.Get("cpumodel").([]interface{})
Expand Down