mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-04 21:14:05 +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
|
||||
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.
|
||||
- `network_device` - (Optional) A network device (multiple blocks supported).
|
||||
- `bridge` - (Optional) The name of the network bridge (defaults
|
||||
@ -446,6 +448,8 @@ output "ubuntu_vm_public_key" {
|
||||
1800).
|
||||
- `timeout_move_disk` - (Optional) Timeout for moving the disk of a VM in
|
||||
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
|
||||
to 1800).
|
||||
- `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" {
|
||||
name = "terraform-provider-proxmox-example"
|
||||
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
|
||||
vm_id = 2041
|
||||
tags = ["terraform", "ubuntu"]
|
||||
|
@ -526,7 +526,7 @@ type ListResponseData struct {
|
||||
|
||||
// MigrateRequestBody contains the body for a VM migration request.
|
||||
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"`
|
||||
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
|
||||
WithLocalDisks *types.CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
|
||||
|
@ -98,6 +98,7 @@ const (
|
||||
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
|
||||
dvResourceVirtualEnvironmentVMMemoryFloating = 0
|
||||
dvResourceVirtualEnvironmentVMMemoryShared = 0
|
||||
dvResourceVirtualEnvironmentVMMigrate = false
|
||||
dvResourceVirtualEnvironmentVMName = ""
|
||||
dvResourceVirtualEnvironmentVMNetworkDeviceBridge = "vmbr0"
|
||||
dvResourceVirtualEnvironmentVMNetworkDeviceEnabled = true
|
||||
@ -123,6 +124,7 @@ const (
|
||||
dvResourceVirtualEnvironmentVMTemplate = false
|
||||
dvResourceVirtualEnvironmentVMTimeoutClone = 1800
|
||||
dvResourceVirtualEnvironmentVMTimeoutMoveDisk = 1800
|
||||
dvResourceVirtualEnvironmentVMTimeoutMigrate = 1800
|
||||
dvResourceVirtualEnvironmentVMTimeoutReboot = 1800
|
||||
dvResourceVirtualEnvironmentVMTimeoutShutdownVM = 1800
|
||||
dvResourceVirtualEnvironmentVMTimeoutStartVM = 1800
|
||||
@ -230,6 +232,7 @@ const (
|
||||
mkResourceVirtualEnvironmentVMMemoryDedicated = "dedicated"
|
||||
mkResourceVirtualEnvironmentVMMemoryFloating = "floating"
|
||||
mkResourceVirtualEnvironmentVMMemoryShared = "shared"
|
||||
mkResourceVirtualEnvironmentVMMigrate = "migrate"
|
||||
mkResourceVirtualEnvironmentVMName = "name"
|
||||
mkResourceVirtualEnvironmentVMNetworkDevice = "network_device"
|
||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge = "bridge"
|
||||
@ -265,6 +268,7 @@ const (
|
||||
mkResourceVirtualEnvironmentVMTemplate = "template"
|
||||
mkResourceVirtualEnvironmentVMTimeoutClone = "timeout_clone"
|
||||
mkResourceVirtualEnvironmentVMTimeoutMoveDisk = "timeout_move_disk"
|
||||
mkResourceVirtualEnvironmentVMTimeoutMigrate = "timeout_migrate"
|
||||
mkResourceVirtualEnvironmentVMTimeoutReboot = "timeout_reboot"
|
||||
mkResourceVirtualEnvironmentVMTimeoutShutdownVM = "timeout_shutdown_vm"
|
||||
mkResourceVirtualEnvironmentVMTimeoutStartVM = "timeout_start_vm"
|
||||
@ -1183,7 +1187,12 @@ func VM() *schema.Resource {
|
||||
Type: schema.TypeString,
|
||||
Description: "The node name",
|
||||
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: {
|
||||
Type: schema.TypeList,
|
||||
@ -1368,6 +1377,12 @@ func VM() *schema.Resource {
|
||||
Optional: true,
|
||||
Default: dvResourceVirtualEnvironmentVMTimeoutMoveDisk,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMTimeoutMigrate: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "Migrate VM timeout",
|
||||
Optional: true,
|
||||
Default: dvResourceVirtualEnvironmentVMTimeoutMigrate,
|
||||
},
|
||||
mkResourceVirtualEnvironmentVMTimeoutReboot: {
|
||||
Type: schema.TypeInt,
|
||||
Description: "Reboot timeout",
|
||||
@ -1485,6 +1500,12 @@ func VM() *schema.Resource {
|
||||
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{
|
||||
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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
updateBody := &vms.UpdateRequestBody{
|
||||
|
Loading…
Reference in New Issue
Block a user