instanceCreateAsCopy create a new instance by copying from an existing instance.
(s *state.State, opts instanceCreateAsCopyOpts, op *operations.Operation)
| 325 | |
| 326 | // instanceCreateAsCopy create a new instance by copying from an existing instance. |
| 327 | func instanceCreateAsCopy(s *state.State, opts instanceCreateAsCopyOpts, op *operations.Operation) (instance.Instance, error) { |
| 328 | var inst instance.Instance |
| 329 | var instOp *operationlock.InstanceOperation |
| 330 | var err error |
| 331 | var cleanup revert.Hook |
| 332 | |
| 333 | reverter := revert.New() |
| 334 | defer reverter.Fail() |
| 335 | |
| 336 | if opts.refresh { |
| 337 | // Load the target instance. |
| 338 | inst, err = instance.LoadByProjectAndName(s, opts.targetInstance.Project, opts.targetInstance.Name) |
| 339 | if err != nil { |
| 340 | opts.refresh = false // Instance doesn't exist, so switch to copy mode. |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | // If we are not in refresh mode, then create a new instance as we are in copy mode. |
| 345 | if !opts.refresh { |
| 346 | // Create the instance. |
| 347 | inst, instOp, cleanup, err = instance.CreateInternal(s, opts.targetInstance, op, true, false, true) |
| 348 | if err != nil { |
| 349 | return nil, fmt.Errorf("Failed creating instance record: %w", err) |
| 350 | } |
| 351 | |
| 352 | reverter.Add(cleanup) |
| 353 | } else { |
| 354 | instOp, err = inst.LockExclusive() |
| 355 | if err != nil { |
| 356 | return nil, fmt.Errorf("Failed getting exclusive access to target instance: %w", err) |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | defer instOp.Done(err) |
| 361 | |
| 362 | // At this point we have already figured out the instance's root disk device so we can simply retrieve it |
| 363 | // from the expanded devices. |
| 364 | instRootDiskDeviceKey, instRootDiskDevice, err := internalInstance.GetRootDiskDevice(inst.ExpandedDevices().CloneNative()) |
| 365 | if err != nil { |
| 366 | return nil, err |
| 367 | } |
| 368 | |
| 369 | var snapshots []instance.Instance |
| 370 | |
| 371 | if !opts.instanceOnly { |
| 372 | if opts.refresh { |
| 373 | // Compare snapshots. |
| 374 | sourceSnaps, err := opts.sourceInstance.Snapshots() |
| 375 | if err != nil { |
| 376 | return nil, err |
| 377 | } |
| 378 | |
| 379 | sourceSnapshotComparable := make([]storagePools.ComparableSnapshot, 0, len(sourceSnaps)) |
| 380 | for _, sourceSnap := range sourceSnaps { |
| 381 | _, sourceSnapName, _ := api.GetParentAndSnapshotName(sourceSnap.Name()) |
| 382 | |
| 383 | sourceSnapshotComparable = append(sourceSnapshotComparable, storagePools.ComparableSnapshot{ |
| 384 | Name: sourceSnapName, |
no test coverage detected
searching dependent graphs…