mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-05 21:43:59 +00:00
feat(vm): support for migration when the node name is modified (#501)
* feat(vm): support for migration when the node name is modified * Added a `migrate` VM flag which changes the provider's behaviour when the VM's `node_name` is updated. If `true`, the VM will be migrated to the specified node instead of being re-created. * Added a `timeout_migrate` setting to control the timeout for VM migration. * Fixed a bug in the API's migration data structure that prevented the online migration flag to be set. * fix: update description --------- Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
e6c15eccc6
commit
a2853606ad
@ -365,6 +365,8 @@ output "ubuntu_vm_public_key" {
|
|||||||
- `floating` - (Optional) The floating memory in megabytes (defaults
|
- `floating` - (Optional) The floating memory in megabytes (defaults
|
||||||
to `0`).
|
to `0`).
|
||||||
- `shared` - (Optional) The shared memory in megabytes (defaults to `0`).
|
- `shared` - (Optional) The shared memory in megabytes (defaults to `0`).
|
||||||
|
- `migrate` - (Optional) Migrate the VM on node change instead of re-creating
|
||||||
|
it (defaults to `false`).
|
||||||
- `name` - (Optional) The virtual machine name.
|
- `name` - (Optional) The virtual machine name.
|
||||||
- `network_device` - (Optional) A network device (multiple blocks supported).
|
- `network_device` - (Optional) A network device (multiple blocks supported).
|
||||||
- `bridge` - (Optional) The name of the network bridge (defaults
|
- `bridge` - (Optional) The name of the network bridge (defaults
|
||||||
@ -446,6 +448,8 @@ output "ubuntu_vm_public_key" {
|
|||||||
1800).
|
1800).
|
||||||
- `timeout_move_disk` - (Optional) Timeout for moving the disk of a VM in
|
- `timeout_move_disk` - (Optional) Timeout for moving the disk of a VM in
|
||||||
seconds (defaults to 1800).
|
seconds (defaults to 1800).
|
||||||
|
- `timeout_migrate` - (Optional) Timeout for migrating the VM (defaults to
|
||||||
|
1800).
|
||||||
- `timeout_reboot` - (Optional) Timeout for rebooting a VM in seconds (defaults
|
- `timeout_reboot` - (Optional) Timeout for rebooting a VM in seconds (defaults
|
||||||
to 1800).
|
to 1800).
|
||||||
- `timeout_shutdown_vm` - (Optional) Timeout for shutting down a VM in seconds (
|
- `timeout_shutdown_vm` - (Optional) Timeout for shutting down a VM in seconds (
|
||||||
|
@ -104,6 +104,7 @@ resource "proxmox_virtual_environment_vm" "example_template" {
|
|||||||
resource "proxmox_virtual_environment_vm" "example" {
|
resource "proxmox_virtual_environment_vm" "example" {
|
||||||
name = "terraform-provider-proxmox-example"
|
name = "terraform-provider-proxmox-example"
|
||||||
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
||||||
|
migrate = true // migrate the VM on node change
|
||||||
pool_id = proxmox_virtual_environment_pool.example.id
|
pool_id = proxmox_virtual_environment_pool.example.id
|
||||||
vm_id = 2041
|
vm_id = 2041
|
||||||
tags = ["terraform", "ubuntu"]
|
tags = ["terraform", "ubuntu"]
|
||||||
|
@ -526,7 +526,7 @@ type ListResponseData struct {
|
|||||||
|
|
||||||
// MigrateRequestBody contains the body for a VM migration request.
|
// MigrateRequestBody contains the body for a VM migration request.
|
||||||
type MigrateRequestBody struct {
|
type MigrateRequestBody struct {
|
||||||
OnlineMigration *types.CustomBool `json:"online,omitempty" url:"online,omitempty"`
|
OnlineMigration *types.CustomBool `json:"online,omitempty" url:"online,omitempty,int"`
|
||||||
TargetNode string `json:"target" url:"target"`
|
TargetNode string `json:"target" url:"target"`
|
||||||
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
|
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
|
||||||
WithLocalDisks *types.CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
|
WithLocalDisks *types.CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
|
||||||
|
@ -98,6 +98,7 @@ const (
|
|||||||
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
|
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
|
||||||
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
||||||
dvResourceVirtualEnvironmentVMMemoryShared = 0
|
dvResourceVirtualEnvironmentVMMemoryShared = 0
|
||||||
|
dvResourceVirtualEnvironmentVMMigrate = false
|
||||||
dvResourceVirtualEnvironmentVMName = ""
|
dvResourceVirtualEnvironmentVMName = ""
|
||||||
dvResourceVirtualEnvironmentVMNetworkDeviceBridge = "vmbr0"
|
dvResourceVirtualEnvironmentVMNetworkDeviceBridge = "vmbr0"
|
||||||
dvResourceVirtualEnvironmentVMNetworkDeviceEnabled = true
|
dvResourceVirtualEnvironmentVMNetworkDeviceEnabled = true
|
||||||
@ -123,6 +124,7 @@ const (
|
|||||||
dvResourceVirtualEnvironmentVMTemplate = false
|
dvResourceVirtualEnvironmentVMTemplate = false
|
||||||
dvResourceVirtualEnvironmentVMTimeoutClone = 1800
|
dvResourceVirtualEnvironmentVMTimeoutClone = 1800
|
||||||
dvResourceVirtualEnvironmentVMTimeoutMoveDisk = 1800
|
dvResourceVirtualEnvironmentVMTimeoutMoveDisk = 1800
|
||||||
|
dvResourceVirtualEnvironmentVMTimeoutMigrate = 1800
|
||||||
dvResourceVirtualEnvironmentVMTimeoutReboot = 1800
|
dvResourceVirtualEnvironmentVMTimeoutReboot = 1800
|
||||||
dvResourceVirtualEnvironmentVMTimeoutShutdownVM = 1800
|
dvResourceVirtualEnvironmentVMTimeoutShutdownVM = 1800
|
||||||
dvResourceVirtualEnvironmentVMTimeoutStartVM = 1800
|
dvResourceVirtualEnvironmentVMTimeoutStartVM = 1800
|
||||||
@ -230,6 +232,7 @@ const (
|
|||||||
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
||||||
mkResourceVirtualEnvironmentVMMemoryFloating = "floating"
|
mkResourceVirtualEnvironmentVMMemoryFloating = "floating"
|
||||||
mkResourceVirtualEnvironmentVMMemoryShared = "shared"
|
mkResourceVirtualEnvironmentVMMemoryShared = "shared"
|
||||||
|
mkResourceVirtualEnvironmentVMMigrate = "migrate"
|
||||||
mkResourceVirtualEnvironmentVMName = "name"
|
mkResourceVirtualEnvironmentVMName = "name"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice = "network_device"
|
mkResourceVirtualEnvironmentVMNetworkDevice = "network_device"
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge = "bridge"
|
mkResourceVirtualEnvironmentVMNetworkDeviceBridge = "bridge"
|
||||||
@ -265,6 +268,7 @@ const (
|
|||||||
mkResourceVirtualEnvironmentVMTemplate = "template"
|
mkResourceVirtualEnvironmentVMTemplate = "template"
|
||||||
mkResourceVirtualEnvironmentVMTimeoutClone = "timeout_clone"
|
mkResourceVirtualEnvironmentVMTimeoutClone = "timeout_clone"
|
||||||
mkResourceVirtualEnvironmentVMTimeoutMoveDisk = "timeout_move_disk"
|
mkResourceVirtualEnvironmentVMTimeoutMoveDisk = "timeout_move_disk"
|
||||||
|
mkResourceVirtualEnvironmentVMTimeoutMigrate = "timeout_migrate"
|
||||||
mkResourceVirtualEnvironmentVMTimeoutReboot = "timeout_reboot"
|
mkResourceVirtualEnvironmentVMTimeoutReboot = "timeout_reboot"
|
||||||
mkResourceVirtualEnvironmentVMTimeoutShutdownVM = "timeout_shutdown_vm"
|
mkResourceVirtualEnvironmentVMTimeoutShutdownVM = "timeout_shutdown_vm"
|
||||||
mkResourceVirtualEnvironmentVMTimeoutStartVM = "timeout_start_vm"
|
mkResourceVirtualEnvironmentVMTimeoutStartVM = "timeout_start_vm"
|
||||||
@ -1183,7 +1187,12 @@ func VM() *schema.Resource {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Description: "The node name",
|
Description: "The node name",
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMMigrate: {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Description: "Whether to migrate the VM on node change instead of re-creating it",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvResourceVirtualEnvironmentVMMigrate,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentVMOperatingSystem: {
|
mkResourceVirtualEnvironmentVMOperatingSystem: {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
@ -1368,6 +1377,12 @@ func VM() *schema.Resource {
|
|||||||
Optional: true,
|
Optional: true,
|
||||||
Default: dvResourceVirtualEnvironmentVMTimeoutMoveDisk,
|
Default: dvResourceVirtualEnvironmentVMTimeoutMoveDisk,
|
||||||
},
|
},
|
||||||
|
mkResourceVirtualEnvironmentVMTimeoutMigrate: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "Migrate VM timeout",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvResourceVirtualEnvironmentVMTimeoutMigrate,
|
||||||
|
},
|
||||||
mkResourceVirtualEnvironmentVMTimeoutReboot: {
|
mkResourceVirtualEnvironmentVMTimeoutReboot: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Description: "Reboot timeout",
|
Description: "Reboot timeout",
|
||||||
@ -1485,6 +1500,12 @@ func VM() *schema.Resource {
|
|||||||
return strconv.Itoa(newValue.(int)) != d.Id()
|
return strconv.Itoa(newValue.(int)) != d.Id()
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
customdiff.ForceNewIf(
|
||||||
|
mkResourceVirtualEnvironmentVMNodeName,
|
||||||
|
func(ctx context.Context, d *schema.ResourceDiff, meta interface{}) bool {
|
||||||
|
return !d.Get(mkResourceVirtualEnvironmentVMMigrate).(bool)
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Importer: &schema.ResourceImporter{
|
Importer: &schema.ResourceImporter{
|
||||||
StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) {
|
StateContext: func(ctx context.Context, d *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) {
|
||||||
@ -4847,6 +4868,26 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
return diag.FromErr(e)
|
return diag.FromErr(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the node name has changed we need to migrate the VM to the new node before we do anything else.
|
||||||
|
if d.HasChange(mkResourceVirtualEnvironmentVMNodeName) {
|
||||||
|
oldNodeNameValue, _ := d.GetChange(mkResourceVirtualEnvironmentVMNodeName)
|
||||||
|
oldNodeName := oldNodeNameValue.(string)
|
||||||
|
vmAPI := api.Node(oldNodeName).VM(vmID)
|
||||||
|
|
||||||
|
migrateTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutMigrate).(int)
|
||||||
|
trueValue := types.CustomBool(true)
|
||||||
|
migrateBody := &vms.MigrateRequestBody{
|
||||||
|
TargetNode: nodeName,
|
||||||
|
WithLocalDisks: &trueValue,
|
||||||
|
OnlineMigration: &trueValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := vmAPI.MigrateVM(ctx, migrateBody, migrateTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vmAPI := api.Node(nodeName).VM(vmID)
|
vmAPI := api.Node(nodeName).VM(vmID)
|
||||||
|
|
||||||
updateBody := &vms.UpdateRequestBody{
|
updateBody := &vms.UpdateRequestBody{
|
||||||
|
Loading…
Reference in New Issue
Block a user