RefreshInstance synchronises one instance's volume (and optionally snapshots) over another. Snapshots that are not present in the source but are in the destination are removed from the destination if snapshots are included in the synchronisation. An empty srcSnapshots argument indicates a volume-onl
(inst instance.Instance, src instance.Instance, srcSnapshots []instance.Instance, allowInconsistent bool, op *operations.Operation)
| 1571 | // destination if snapshots are included in the synchronisation. An empty srcSnapshots argument |
| 1572 | // indicates a volume-only refresh. |
| 1573 | func (b *backend) RefreshInstance(inst instance.Instance, src instance.Instance, srcSnapshots []instance.Instance, allowInconsistent bool, op *operations.Operation) error { |
| 1574 | l := b.logger.AddContext(logger.Ctx{"project": inst.Project().Name, "instance": inst.Name(), "src": src.Name(), "srcSnapshots": len(srcSnapshots)}) |
| 1575 | l.Debug("RefreshInstance started") |
| 1576 | defer l.Debug("RefreshInstance finished") |
| 1577 | |
| 1578 | // This indicates whether or not it's a volume-only refresh. |
| 1579 | snapshots := len(srcSnapshots) > 0 |
| 1580 | |
| 1581 | if inst.Type() != src.Type() { |
| 1582 | return errors.New("Instance types must match") |
| 1583 | } |
| 1584 | |
| 1585 | volType, err := InstanceTypeToVolumeType(inst.Type()) |
| 1586 | if err != nil { |
| 1587 | return err |
| 1588 | } |
| 1589 | |
| 1590 | contentType := InstanceContentType(inst) |
| 1591 | |
| 1592 | // Load storage volume from database. |
| 1593 | dbVol, err := VolumeDBGet(b, inst.Project().Name, inst.Name(), volType) |
| 1594 | if err != nil { |
| 1595 | return err |
| 1596 | } |
| 1597 | |
| 1598 | // Generate the effective root device volume for instance. |
| 1599 | volStorageName := project.Instance(inst.Project().Name, inst.Name()) |
| 1600 | vol := b.GetVolume(volType, contentType, volStorageName, dbVol.Config) |
| 1601 | err = b.applyInstanceRootDiskOverrides(inst, &vol) |
| 1602 | if err != nil { |
| 1603 | return err |
| 1604 | } |
| 1605 | |
| 1606 | // Get the source storage pool. |
| 1607 | srcPool, err := LoadByInstance(b.state, src) |
| 1608 | if err != nil { |
| 1609 | return err |
| 1610 | } |
| 1611 | |
| 1612 | srcPoolBackend, ok := srcPool.(*backend) |
| 1613 | if !ok { |
| 1614 | return errors.New("Source pool is not a backend") |
| 1615 | } |
| 1616 | |
| 1617 | // Check source volume exists, and get its config. |
| 1618 | srcConfig, err := srcPool.GenerateInstanceBackupConfig(src, snapshots, true, op) |
| 1619 | if err != nil { |
| 1620 | return fmt.Errorf("Failed generating instance refresh config: %w", err) |
| 1621 | } |
| 1622 | |
| 1623 | // Ensure that only the requested snapshots are included in the source config. |
| 1624 | allSnapshots := srcConfig.VolumeSnapshots |
| 1625 | srcConfig.VolumeSnapshots = make([]*api.StorageVolumeSnapshot, 0, len(srcSnapshots)) |
| 1626 | for i := range allSnapshots { |
| 1627 | found := false |
| 1628 | for _, srcSnapshot := range srcSnapshots { |
| 1629 | _, srcSnapshotName, _ := api.GetParentAndSnapshotName(srcSnapshot.Name()) |
| 1630 | if srcSnapshotName == allSnapshots[i].Name { |
nothing calls this directly
no test coverage detected