MigrateVM migrates a VM or container to another node using the Proxmox API. The migration process supports both QEMU VMs and LXC containers with different options and behaviors: For QEMU VMs: - Online migration (live migration) is supported for running VMs - Offline migration requires the VM to be
(vm *VM, options *MigrationOptions)
| 186 | // |
| 187 | // Returns the task UPID and an error if the migration cannot be initiated. |
| 188 | func (c *Client) MigrateVM(vm *VM, options *MigrationOptions) (string, error) { |
| 189 | if options == nil || options.Target == "" { |
| 190 | return "", fmt.Errorf("target node is required for migration") |
| 191 | } |
| 192 | |
| 193 | // Validate target node exists |
| 194 | if c.Cluster != nil { |
| 195 | targetExists := false |
| 196 | |
| 197 | for _, node := range c.Cluster.Nodes { |
| 198 | if node != nil && node.Name == options.Target { |
| 199 | targetExists = true |
| 200 | |
| 201 | break |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | if !targetExists { |
| 206 | return "", fmt.Errorf("target node '%s' not found in cluster", options.Target) |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | path := fmt.Sprintf("/nodes/%s/%s/%d/migrate", vm.Node, vm.Type, vm.ID) |
| 211 | |
| 212 | // Build migration data |
| 213 | data := map[string]interface{}{ |
| 214 | "target": options.Target, |
| 215 | } |
| 216 | |
| 217 | // Set migration parameters based on VM type |
| 218 | if vm.Type == VMTypeQemu { |
| 219 | // QEMU VMs use online parameter for live/offline migration |
| 220 | if options.Online != nil { |
| 221 | if *options.Online { |
| 222 | data["online"] = "1" |
| 223 | } else { |
| 224 | data["online"] = "0" |
| 225 | } |
| 226 | } else { |
| 227 | // Default: online migration for running VMs, offline for stopped VMs |
| 228 | if vm.Status == VMStatusRunning { |
| 229 | data["online"] = "1" |
| 230 | } else { |
| 231 | data["online"] = "0" |
| 232 | } |
| 233 | } |
| 234 | } else if vm.Type == VMTypeLXC { |
| 235 | // LXC containers use restart parameter (they don't support live migration) |
| 236 | data["restart"] = "1" |
| 237 | } |
| 238 | |
| 239 | // Add optional parameters |
| 240 | if options.Force { |
| 241 | data["force"] = "1" |
| 242 | } |
| 243 | |
| 244 | if options.MigrationNetwork != "" { |
| 245 | data["migration_network"] = options.MigrationNetwork |
no test coverage detected