Skip to content

Commit

Permalink
Merge pull request #11841 from manadart/2.8-into-develop
Browse files Browse the repository at this point in the history
#11841

Merge from 2.8 to bring forward:
- #11838 from wallyworld/fstab-uuids
- #11833 from manadart/2.8-link-layer-address-extract
- #11821 from wallyworld/azure-bootstrap-fixes
- #11832 from manadart/2.8-interface-infos-dedup
- #11830 from ycliuhw/fix/lp-1887440
- #11825 from wallyworld/merge-2.7-20200713
- #11828 from achilleasa/2.8-make-manual-cleanup-script-more-robust
- #11826 from SimonRichardson/remove-nbd-integration-tests
- #11824 from hpidcock/fix-operator-imagepath
- #11798 from jujubot/increment-to-2.8.2
  • Loading branch information
jujubot committed Jul 20, 2020
2 parents 346cd85 + f0403ef commit e02e9b9
Show file tree
Hide file tree
Showing 38 changed files with 966 additions and 197 deletions.
72 changes: 60 additions & 12 deletions apiserver/common/networkingcommon/linklayer.go
Expand Up @@ -107,9 +107,15 @@ type MachineLinkLayerOp struct {
// incoming is the network interface information supplied for update.
incoming network.InterfaceInfos

// processed is the set of hardware IDs that we have
// processedDevs is the set of hardware IDs that we have
// processed from the incoming interfaces.
processed set.Strings
processedDevs set.Strings

// processedAddrs is the set of IP addresses that we have processed,
// keyed by the hardware address of the device they apply to.
// In theory this allows the same IP address to exist on devices in
// physically separate networks.
processedAddrs map[string]set.Strings

existingDevs []LinkLayerDevice
existingAddrs []LinkLayerAddress
Expand All @@ -121,9 +127,10 @@ func NewMachineLinkLayerOp(machine LinkLayerMachine, incoming network.InterfaceI
logger.Debugf("processing link-layer devices for machine %q", machine.Id())

return &MachineLinkLayerOp{
machine: machine,
incoming: incoming,
processed: set.NewStrings(),
machine: machine,
incoming: incoming,
processedDevs: set.NewStrings(),
processedAddrs: make(map[string]set.Strings),
}
}

Expand Down Expand Up @@ -160,6 +167,26 @@ func (o *MachineLinkLayerOp) PopulateExistingAddresses() error {
return errors.Trace(err)
}

// MatchingIncoming returns the first incoming interface that
// matches the input known device, based on hardware address.
// Nil is returned if there is no match.
func (o *MachineLinkLayerOp) MatchingIncoming(dev LinkLayerDevice) *network.InterfaceInfo {
if matches := o.incoming.GetByHardwareAddress(dev.MACAddress()); len(matches) > 0 {
return &matches[0]
}
return nil
}

// MatchingIncomingAddrs finds all the primary addresses on devices matching
// the hardware address of the input, and returns them as state args.
// TODO (manadart 2020-07-15): We should investigate making an enhanced
// core/network address type instead of this state type.
// It would embed ProviderAddress and could be obtained directly via a method
// or property of InterfaceInfos.
func (o *MachineLinkLayerOp) MatchingIncomingAddrs(dev LinkLayerDevice) []state.LinkLayerDeviceAddress {
return networkAddressStateArgsForHWAddr(o.Incoming(), dev.MACAddress())
}

// DeviceAddresses returns all currently known
// IP addresses assigned to the input device.
func (o *MachineLinkLayerOp) DeviceAddresses(dev LinkLayerDevice) []LinkLayerAddress {
Expand All @@ -178,16 +205,37 @@ func (o *MachineLinkLayerOp) AssertAliveOp() txn.Op {
return o.machine.AssertAliveOp()
}

// MarkProcessed indicates that the input (known) device was present in the
// MarkDevProcessed indicates that the input (known) device was present in the
// incoming data and its updates have been handled by the build step.
func (o *MachineLinkLayerOp) MarkProcessed(dev LinkLayerDevice) {
o.processed.Add(dev.MACAddress())
func (o *MachineLinkLayerOp) MarkDevProcessed(dev LinkLayerDevice) {
o.processedDevs.Add(dev.MACAddress())
}

// IsProcessed returns a boolean indicating whether the input incoming device
// matches a known device that was marked as processed by the method above.
func (o *MachineLinkLayerOp) IsProcessed(dev network.InterfaceInfo) bool {
return o.processed.Contains(dev.MACAddress)
// IsDevProcessed returns a boolean indicating whether the input incoming
// device matches a known device that was marked as processed by the method
// above.
func (o *MachineLinkLayerOp) IsDevProcessed(dev network.InterfaceInfo) bool {
return o.processedDevs.Contains(dev.MACAddress)
}

// MarkAddrProcessed indicates that the input (known) IP address was present in
// the incoming data for the device with input hardware address.
func (o *MachineLinkLayerOp) MarkAddrProcessed(hwAddr, ipAddr string) {
if _, ok := o.processedAddrs[hwAddr]; !ok {
o.processedAddrs[hwAddr] = set.NewStrings(ipAddr)
} else {
o.processedAddrs[hwAddr].Add(ipAddr)
}
}

// IsAddrProcessed returns a boolean indicating whether the input incoming
// device/address pair matches an entry that was marked as processed by the
// method above.
func (o *MachineLinkLayerOp) IsAddrProcessed(hwAddr, ipAddr string) bool {
if addrs, ok := o.processedAddrs[hwAddr]; ok {
return addrs.Contains(ipAddr)
}
return false
}

// Done (state.ModelOperation) returns the result of running the operation.
Expand Down
39 changes: 30 additions & 9 deletions apiserver/common/networkingcommon/types.go
Expand Up @@ -153,28 +153,29 @@ func BackingSubnetToParamsSubnet(subnet BackingSubnet) params.Subnet {

// NetworkInterfacesToStateArgs splits the given interface list into a slice of
// state.LinkLayerDeviceArgs and a slice of state.LinkLayerDeviceAddress.
func NetworkInterfacesToStateArgs(ifaces corenetwork.InterfaceInfos) (
func NetworkInterfacesToStateArgs(devs corenetwork.InterfaceInfos) (
[]state.LinkLayerDeviceArgs,
[]state.LinkLayerDeviceAddress,
) {
var devicesArgs []state.LinkLayerDeviceArgs
var devicesAddrs []state.LinkLayerDeviceAddress

logger.Tracef("transforming network interface list to state args: %+v", ifaces)
logger.Tracef("transforming network interface list to state args: %+v", devs)
seenDeviceNames := set.NewStrings()
for _, iface := range ifaces {
logger.Tracef("transforming device %q", iface.InterfaceName)
if !seenDeviceNames.Contains(iface.InterfaceName) {
for _, dev := range devs {
logger.Tracef("transforming device %q", dev.InterfaceName)
if !seenDeviceNames.Contains(dev.InterfaceName) {
// First time we see this, add it to devicesArgs.
seenDeviceNames.Add(iface.InterfaceName)
args := networkDeviceToStateArgs(iface)
seenDeviceNames.Add(dev.InterfaceName)

args := networkDeviceToStateArgs(dev)
logger.Tracef("state device args for device: %+v", args)
devicesArgs = append(devicesArgs, args)
}

addr, err := networkAddressToStateArgs(iface, iface.PrimaryAddress())
addr, err := networkAddressToStateArgs(dev, dev.PrimaryAddress())
if err != nil {
logger.Warningf("ignoring address for device %q: %v", iface.InterfaceName, err)
logger.Warningf("ignoring address for device %q: %v", dev.InterfaceName, err)
continue
}

Expand Down Expand Up @@ -205,6 +206,26 @@ func networkDeviceToStateArgs(dev corenetwork.InterfaceInfo) state.LinkLayerDevi
}
}

// networkAddressStateArgsForHWAddr accommodates the fact that network
// configuration is sometimes supplied with a duplicated device for each
// address.
// This is a normalisation that returns state args for all primary addresses
// of interfaces with the input hardware address.
func networkAddressStateArgsForHWAddr(devs corenetwork.InterfaceInfos, hwAddr string) []state.LinkLayerDeviceAddress {
var res []state.LinkLayerDeviceAddress

for _, dev := range devs.GetByHardwareAddress(hwAddr) {
addr, err := networkAddressToStateArgs(dev, dev.PrimaryAddress())
if err != nil {
logger.Warningf("ignoring address for device %q: %v", dev.InterfaceName, err)
continue
}
res = append(res, addr)
}

return res
}

func networkAddressToStateArgs(
dev corenetwork.InterfaceInfo, addr corenetwork.ProviderAddress,
) (state.LinkLayerDeviceAddress, error) {
Expand Down
25 changes: 22 additions & 3 deletions apiserver/common/storagecommon/blockdevices.go
Expand Up @@ -115,14 +115,33 @@ func MatchingBlockDevice(
}

if attachmentInfo.DeviceLink != "" {
// We'll prefer to use a mounted partition if available.
// This will be the case for filesystem storage; it will be part1.
var devWithUUID, parentDev *state.BlockDeviceInfo
devMatch:
for _, dev := range blockDevices {
for _, link := range dev.DeviceLinks {
if attachmentInfo.DeviceLink == link {
logger.Tracef("device link match on %v", attachmentInfo.DeviceLink)
return &dev, true
if attachmentInfo.DeviceLink == link || attachmentInfo.DeviceLink+"-part1" == link {
devCopy := dev
if dev.UUID != "" {
devWithUUID = &devCopy
} else {
parentDev = &devCopy
}
}
if devWithUUID != nil {
break devMatch
}
}
}
if devWithUUID != nil {
logger.Tracef("device link with UUID match on %v", attachmentInfo.DeviceLink)
return devWithUUID, true
}
if parentDev != nil {
logger.Tracef("device link without UUID match on %v", attachmentInfo.DeviceLink)
return parentDev, true
}
logger.Tracef("no match for block device dev link: %v", attachmentInfo.DeviceLink)
}

Expand Down
34 changes: 30 additions & 4 deletions apiserver/common/storagecommon/blockdevices_test.go
Expand Up @@ -103,11 +103,37 @@ func (s *BlockDeviceSuite) TestBlockDevicesGCE(c *gc.C) {
})
}

func (s *BlockDeviceSuite) TestBlockDevicesGCEPreferUUID(c *gc.C) {
blockDeviceInfo, ok := storagecommon.MatchingBlockDevice(gceTestBlockDevices, gceTestVolumeInfo, gceTestAttachmentInfoForUUID, gceTestPlanBlockInfo)
c.Assert(ok, jc.IsTrue)
c.Assert(blockDeviceInfo, jc.DeepEquals, &state.BlockDeviceInfo{
DeviceName: "sda1",
DeviceLinks: []string{
"/dev/disk/by-id/google-persistent-disk-0-part1",
"/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part1",
"/dev/disk/by-label/cloudimg-rootfs",
"/dev/disk/by-partuuid/8c3230b8-1ecf-45d9-a6c8-41f4bc51a849",
"/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part1",
"/dev/disk/by-uuid/27514291-b7f6-4b83-bc8a-07c7d7467218",
},
Label: "cloudimg-rootfs",
UUID: "27514291-b7f6-4b83-bc8a-07c7d7467218",
HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0",
BusAddress: "scsi@0:0.1.0",
Size: 0x2790,
FilesystemType: "ext4",
InUse: true,
MountPoint: "/",
SerialId: "0Google_PersistentDisk_persistent-disk-0",
})
}

var (
gceTestBlockDevices = []state.BlockDeviceInfo{{DeviceName: "loop0", Size: 0x59, FilesystemType: "squashfs", InUse: true, MountPoint: "/snap/core/7713"}, {DeviceName: "loop1", Size: 0x42, FilesystemType: "squashfs", InUse: true, MountPoint: "/snap/google-cloud-sdk/102"}, {DeviceName: "sda", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0"}, HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x2800, InUse: true, SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sda1", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0-part1", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part1", "/dev/disk/by-label/cloudimg-rootfs", "/dev/disk/by-partuuid/8c3230b8-1ecf-45d9-a6c8-41f4bc51a849", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part1", "/dev/disk/by-uuid/27514291-b7f6-4b83-bc8a-07c7d7467218"}, Label: "cloudimg-rootfs", UUID: "27514291-b7f6-4b83-bc8a-07c7d7467218", HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x2790, FilesystemType: "ext4", InUse: true, MountPoint: "/", SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sda14", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0-part14", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part14", "/dev/disk/by-partuuid/d82926ca-95f8-46fe-ab94-61bb6cc2a879", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part14"}, HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x4, SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sda15", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0-part15", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part15", "/dev/disk/by-label/UEFI", "/dev/disk/by-partuuid/264a576d-0211-45fa-9bdd-e674c08517f4", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part15", "/dev/disk/by-uuid/9889-C357"}, Label: "UEFI", UUID: "9889-C357", HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x6a, FilesystemType: "vfat", InUse: true, MountPoint: "/boot/efi", SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sdb", DeviceLinks: []string{"/dev/disk/by-id/google-us-east1-d-9082123458182365433", "/dev/disk/by-id/scsi-0Google_PersistentDisk_us-east1-d-9082123458182365433", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:2:0"}, HardwareId: "scsi-0Google_PersistentDisk_us-east1-d-9082123458182365433", BusAddress: "scsi@0:0.2.0", Size: 0x2800, SerialId: "0Google_PersistentDisk_us-east1-d-9082123458182365433"}, {DeviceName: "sdc", DeviceLinks: []string{"/dev/disk/by-id/google-us-east1-d-2880464023067017457", "/dev/disk/by-id/scsi-0Google_PersistentDisk_us-east1-d-2880464023067017457", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:3:0"}, HardwareId: "scsi-0Google_PersistentDisk_us-east1-d-2880464023067017457", BusAddress: "scsi@0:0.3.0", Size: 0x2800, SerialId: "0Google_PersistentDisk_us-east1-d-2880464023067017457"}, {DeviceName: "sdd", DeviceLinks: []string{"/dev/disk/by-id/google-us-east1-d-5005808815463186635", "/dev/disk/by-id/scsi-0Google_PersistentDisk_us-east1-d-5005808815463186635", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:4:0"}, HardwareId: "scsi-0Google_PersistentDisk_us-east1-d-5005808815463186635", BusAddress: "scsi@0:0.4.0", Size: 0x2800, SerialId: "0Google_PersistentDisk_us-east1-d-5005808815463186635"}}
gceTestPlanBlockInfo = state.BlockDeviceInfo{}
gceTestVolumeInfo = state.VolumeInfo{Size: 0x2800, Pool: "gce", VolumeId: "us-east1-d--515cb1ad-5d23-4d53-8cc1-b79c75a03908", Persistent: true}
gceTestAttachmentInfo = state.VolumeAttachmentInfo{DeviceLink: "/dev/disk/by-id/google-us-east1-d-5005808815463186635", ReadOnly: false, PlanInfo: (*state.VolumeAttachmentPlanInfo)(nil)}
gceTestBlockDevices = []state.BlockDeviceInfo{{DeviceName: "loop0", Size: 0x59, FilesystemType: "squashfs", InUse: true, MountPoint: "/snap/core/7713"}, {DeviceName: "loop1", Size: 0x42, FilesystemType: "squashfs", InUse: true, MountPoint: "/snap/google-cloud-sdk/102"}, {DeviceName: "sda", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0"}, HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x2800, InUse: true, SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sda1", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0-part1", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part1", "/dev/disk/by-label/cloudimg-rootfs", "/dev/disk/by-partuuid/8c3230b8-1ecf-45d9-a6c8-41f4bc51a849", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part1", "/dev/disk/by-uuid/27514291-b7f6-4b83-bc8a-07c7d7467218"}, Label: "cloudimg-rootfs", UUID: "27514291-b7f6-4b83-bc8a-07c7d7467218", HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x2790, FilesystemType: "ext4", InUse: true, MountPoint: "/", SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sda14", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0-part14", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part14", "/dev/disk/by-partuuid/d82926ca-95f8-46fe-ab94-61bb6cc2a879", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part14"}, HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x4, SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sda15", DeviceLinks: []string{"/dev/disk/by-id/google-persistent-disk-0-part15", "/dev/disk/by-id/scsi-0Google_PersistentDisk_persistent-disk-0-part15", "/dev/disk/by-label/UEFI", "/dev/disk/by-partuuid/264a576d-0211-45fa-9bdd-e674c08517f4", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:1:0-part15", "/dev/disk/by-uuid/9889-C357"}, Label: "UEFI", UUID: "9889-C357", HardwareId: "scsi-0Google_PersistentDisk_persistent-disk-0", BusAddress: "scsi@0:0.1.0", Size: 0x6a, FilesystemType: "vfat", InUse: true, MountPoint: "/boot/efi", SerialId: "0Google_PersistentDisk_persistent-disk-0"}, {DeviceName: "sdb", DeviceLinks: []string{"/dev/disk/by-id/google-us-east1-d-9082123458182365433", "/dev/disk/by-id/scsi-0Google_PersistentDisk_us-east1-d-9082123458182365433", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:2:0"}, HardwareId: "scsi-0Google_PersistentDisk_us-east1-d-9082123458182365433", BusAddress: "scsi@0:0.2.0", Size: 0x2800, SerialId: "0Google_PersistentDisk_us-east1-d-9082123458182365433"}, {DeviceName: "sdc", DeviceLinks: []string{"/dev/disk/by-id/google-us-east1-d-2880464023067017457", "/dev/disk/by-id/scsi-0Google_PersistentDisk_us-east1-d-2880464023067017457", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:3:0"}, HardwareId: "scsi-0Google_PersistentDisk_us-east1-d-2880464023067017457", BusAddress: "scsi@0:0.3.0", Size: 0x2800, SerialId: "0Google_PersistentDisk_us-east1-d-2880464023067017457"}, {DeviceName: "sdd", DeviceLinks: []string{"/dev/disk/by-id/google-us-east1-d-5005808815463186635", "/dev/disk/by-id/scsi-0Google_PersistentDisk_us-east1-d-5005808815463186635", "/dev/disk/by-path/pci-0000:00:03.0-scsi-0:0:4:0"}, HardwareId: "scsi-0Google_PersistentDisk_us-east1-d-5005808815463186635", BusAddress: "scsi@0:0.4.0", Size: 0x2800, SerialId: "0Google_PersistentDisk_us-east1-d-5005808815463186635"}}
gceTestPlanBlockInfo = state.BlockDeviceInfo{}
gceTestVolumeInfo = state.VolumeInfo{Size: 0x2800, Pool: "gce", VolumeId: "us-east1-d--515cb1ad-5d23-4d53-8cc1-b79c75a03908", Persistent: true}
gceTestAttachmentInfo = state.VolumeAttachmentInfo{DeviceLink: "/dev/disk/by-id/google-us-east1-d-5005808815463186635", ReadOnly: false, PlanInfo: (*state.VolumeAttachmentPlanInfo)(nil)}
gceTestAttachmentInfoForUUID = state.VolumeAttachmentInfo{DeviceLink: "/dev/disk/by-id/google-persistent-disk-0", ReadOnly: false, PlanInfo: (*state.VolumeAttachmentPlanInfo)(nil)}
)

func (s *BlockDeviceSuite) TestBlockDevicesOpenStack(c *gc.C) {
Expand Down
1 change: 1 addition & 0 deletions apiserver/common/storagecommon/storage.go
Expand Up @@ -233,6 +233,7 @@ func volumeAttachmentDevicePath(
return storage.BlockDevicePath(storage.BlockDevice{
HardwareId: volumeInfo.HardwareId,
WWN: volumeInfo.WWN,
UUID: blockDevice.UUID,
DeviceName: deviceName,
DeviceLinks: deviceLinks,
})
Expand Down
4 changes: 2 additions & 2 deletions apiserver/common/upgradeseries.go
Expand Up @@ -176,11 +176,11 @@ func (u *UpgradeSeriesAPI) GetMachine(tag names.Tag) (UpgradeSeriesMachine, erro
case names.UnitTagKind:
unit, err := u.backend.Unit(tag.Id())
if err != nil {

return nil, errors.Trace(err)
}
id, err = unit.AssignedMachineId()
if err != nil {
return nil, err
return nil, errors.Trace(err)
}
default:
}
Expand Down

0 comments on commit e02e9b9

Please sign in to comment.