Skip to content

Commit

Permalink
Adds new interfaces and shims to containerizer package to support pro…
Browse files Browse the repository at this point in the history
…visioner testing.

Updates bridge policy tests to accomodate new shims.
Uses new shims in provisioner API server and regenerated local mocks.
  • Loading branch information
manadart committed Oct 10, 2018
1 parent de1a96c commit f967246
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 67 deletions.
74 changes: 70 additions & 4 deletions apiserver/facades/agent/provisioner/machine_mock_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions apiserver/facades/agent/provisioner/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,6 @@ type Machine interface {
containerizer.Container
InstanceId() (instance.Id, error)
IsManual() (bool, error)
AllLinkLayerDevices() ([]*state.LinkLayerDevice, error)
MachineTag() names.MachineTag
}

Expand Down Expand Up @@ -847,17 +846,21 @@ func (p *ProvisionerAPI) processEachContainer(args params.Entities, handler perC
// The auth function (canAccess) checks that the machine is a
// top level machine (we filter those out next) or that the
// machine has the host as a parent.
container, err := p.getMachine(canAccess, machineTag)
ctr, err := p.getMachine(canAccess, machineTag)
if err != nil {
handler.SetError(i, common.ServerError(err))
continue
} else if !container.IsContainer() {
} else if !ctr.IsContainer() {
err = errors.Errorf("cannot prepare network config for %q: not a container", machineTag)
handler.SetError(i, common.ServerError(err))
continue
}

if err := handler.ProcessOneContainer(env, p.providerCallContext, i, hostMachine, container); err != nil {
if err := handler.ProcessOneContainer(
env, p.providerCallContext, i,
&containerizer.MachineShim{Machine: hostMachine},
&containerizer.MachineShim{Machine: ctr},
); err != nil {
handler.SetError(i, common.ServerError(err))
continue
}
Expand Down
35 changes: 7 additions & 28 deletions network/containerizer/bridgepolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/juju/juju/instance"
"github.com/juju/juju/network"

// Used for some constants and things like LinkLayerDevice[Args]
"github.com/juju/juju/state"
)
Expand All @@ -39,28 +40,6 @@ type BridgePolicy struct {
ContainerNetworkingMethod string
}

// Machine describes either a host machine, or a container machine. Either way
// *state.Machine should fulfill the interface in non-test code.
type Machine interface {
Id() string
AllSpaces() (set.Strings, error)
LinkLayerDevicesForSpaces([]string) (map[string][]*state.LinkLayerDevice, error)
}

var _ Machine = (*state.Machine)(nil)

// Container describes the extra attributes we need to be able to update the
// devices for a container.
// *state.Machine should fulfill the interface.
type Container interface {
Machine
ContainerType() instance.ContainerType
DesiredSpaces() (set.Strings, error)
SetLinkLayerDevices(...state.LinkLayerDeviceArgs) error
}

var _ Container = (*state.Machine)(nil)

// inferContainerSpaces tries to find a valid space for the container to be
// on. This should only be used when the container itself doesn't have any
// valid constraints on what spaces it should be in.
Expand Down Expand Up @@ -119,7 +98,7 @@ func (p *BridgePolicy) determineContainerSpaces(m Machine, containerMachine Cont
// findSpacesAndDevicesForContainer looks up what spaces the container wants
// to be in, and what spaces the host machine is already in, and tries to
// find the devices on the host that are useful for the container.
func (p *BridgePolicy) findSpacesAndDevicesForContainer(m Machine, containerMachine Container) (set.Strings, map[string][]*state.LinkLayerDevice, error) {
func (p *BridgePolicy) findSpacesAndDevicesForContainer(m Machine, containerMachine Container) (set.Strings, map[string][]LinkLayerDevice, error) {
containerSpaces, err := p.determineContainerSpaces(m, containerMachine, "")
if err != nil {
return nil, nil, errors.Trace(err)
Expand All @@ -133,7 +112,7 @@ func (p *BridgePolicy) findSpacesAndDevicesForContainer(m Machine, containerMach
return containerSpaces, devicesPerSpace, nil
}

func possibleBridgeTarget(dev *state.LinkLayerDevice) (bool, error) {
func possibleBridgeTarget(dev LinkLayerDevice) (bool, error) {
// LoopbackDevices can never be bridged
if dev.Type() == state.LoopbackDevice || dev.Type() == state.BridgeDevice {
return false, nil
Expand Down Expand Up @@ -164,7 +143,7 @@ func possibleBridgeTarget(dev *state.LinkLayerDevice) (bool, error) {
return false, nil
}

func formatDeviceMap(spacesToDevices map[string][]*state.LinkLayerDevice) string {
func formatDeviceMap(spacesToDevices map[string][]LinkLayerDevice) string {
spaceNames := make([]string, len(spacesToDevices))
i := 0
for spaceName := range spacesToDevices {
Expand Down Expand Up @@ -223,7 +202,7 @@ func BridgeNameForDevice(device string) string {
func (b *BridgePolicy) FindMissingBridgesForContainer(m Machine, containerMachine Container) ([]network.DeviceToBridge, int, error) {
reconfigureDelay := 0
containerSpaces, devicesPerSpace, err := b.findSpacesAndDevicesForContainer(m, containerMachine)
hostDeviceByName := make(map[string]*state.LinkLayerDevice, 0)
hostDeviceByName := make(map[string]LinkLayerDevice, 0)
if err != nil {
return nil, 0, errors.Trace(err)
}
Expand Down Expand Up @@ -352,7 +331,7 @@ func (p *BridgePolicy) PopulateContainerLinkLayerDevices(m Machine, containerMac
instance.KVM: network.DefaultKVMBridge,
}
spacesFound := set.NewStrings()
devicesByName := make(map[string]*state.LinkLayerDevice)
devicesByName := make(map[string]LinkLayerDevice)
bridgeDeviceNames := make([]string, 0)

for spaceName, hostDevices := range devicesPerSpace {
Expand Down Expand Up @@ -397,7 +376,7 @@ func (p *BridgePolicy) PopulateContainerLinkLayerDevices(m Machine, containerMac

for i, hostBridgeName := range sortedBridgeDeviceNames {
hostBridge := devicesByName[hostBridgeName]
newLLD, err := state.DefineEthernetDeviceOnBridge(fmt.Sprintf("eth%d", i), hostBridge)
newLLD, err := hostBridge.EthernetDeviceForBridge(fmt.Sprintf("eth%d", i))
if err != nil {
return errors.Trace(err)
}
Expand Down
39 changes: 23 additions & 16 deletions network/containerizer/bridgepolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
type bridgePolicyStateSuite struct {
statetesting.StateSuite

machine *state.Machine
containerMachine *state.Machine
machine containerizer.Machine
containerMachine containerizer.Container

bridgePolicy *containerizer.BridgePolicy
}
Expand Down Expand Up @@ -70,8 +70,9 @@ func (s *bridgePolicyStateSuite) SetUpTest(c *gc.C) {
s.StateSuite.SetUpTest(c)

var err error
s.machine, err = s.State.AddMachine("quantal", state.JobHostUnits)
m, err := s.State.AddMachine("quantal", state.JobHostUnits)
c.Assert(err, jc.ErrorIsNil)
s.machine = &containerizer.MachineShim{m}

s.bridgePolicy = &containerizer.BridgePolicy{
NetBondReconfigureDelay: 13,
Expand All @@ -87,14 +88,16 @@ func (s *bridgePolicyStateSuite) addContainerMachine(c *gc.C) {
}
container, err := s.State.AddMachineInsideMachine(containerTemplate, s.machine.Id(), instance.LXD)
c.Assert(err, jc.ErrorIsNil)
s.containerMachine = container
s.containerMachine = &containerizer.MachineShim{container}
}

func (s *bridgePolicyStateSuite) assertNoDevicesOnMachine(c *gc.C, machine *state.Machine) {
func (s *bridgePolicyStateSuite) assertNoDevicesOnMachine(c *gc.C, machine containerizer.Container) {
s.assertAllLinkLayerDevicesOnMachineMatchCount(c, machine, 0)
}

func (s *bridgePolicyStateSuite) assertAllLinkLayerDevicesOnMachineMatchCount(c *gc.C, machine *state.Machine, expectedCount int) {
func (s *bridgePolicyStateSuite) assertAllLinkLayerDevicesOnMachineMatchCount(
c *gc.C, machine containerizer.Container, expectedCount int,
) {
results, err := machine.AllLinkLayerDevices()
c.Assert(err, jc.ErrorIsNil)
c.Check(results, gc.HasLen, expectedCount)
Expand All @@ -117,7 +120,7 @@ func (s *bridgePolicyStateSuite) setupTwoSpaces(c *gc.C) {
s.createSpaceAndSubnet(c, "dmz", "10.10.0.0/24")
}

func (s *bridgePolicyStateSuite) createNICWithIP(c *gc.C, machine *state.Machine, deviceName, cidrAddress string) {
func (s *bridgePolicyStateSuite) createNICWithIP(c *gc.C, machine containerizer.Machine, deviceName, cidrAddress string) {
err := machine.SetLinkLayerDevices(
state.LinkLayerDeviceArgs{
Name: deviceName,
Expand All @@ -137,7 +140,9 @@ func (s *bridgePolicyStateSuite) createNICWithIP(c *gc.C, machine *state.Machine
c.Assert(err, jc.ErrorIsNil)
}

func (s *bridgePolicyStateSuite) createBridgeWithIP(c *gc.C, machine *state.Machine, bridgeName, cidrAddress string) {
func (s *bridgePolicyStateSuite) createBridgeWithIP(
c *gc.C, machine containerizer.Machine, bridgeName, cidrAddress string,
) {
err := machine.SetLinkLayerDevices(
state.LinkLayerDeviceArgs{
Name: bridgeName,
Expand All @@ -159,7 +164,9 @@ func (s *bridgePolicyStateSuite) createBridgeWithIP(c *gc.C, machine *state.Mach

// createNICAndBridgeWithIP creates a network interface and a bridge on the
// machine, and assigns the requested CIDRAddress to the bridge.
func (s *bridgePolicyStateSuite) createNICAndBridgeWithIP(c *gc.C, machine *state.Machine, deviceName, bridgeName, cidrAddress string) {
func (s *bridgePolicyStateSuite) createNICAndBridgeWithIP(
c *gc.C, machine containerizer.Machine, deviceName, bridgeName, cidrAddress string,
) {
s.createBridgeWithIP(c, machine, bridgeName, cidrAddress)
err := machine.SetLinkLayerDevices(
state.LinkLayerDeviceArgs{
Expand All @@ -178,7 +185,7 @@ func (s *bridgePolicyStateSuite) setupMachineInTwoSpaces(c *gc.C) {
s.createNICAndBridgeWithIP(c, s.machine, "ens0p10", "br-ens0p10", "10.10.0.20/24")
}

func (s *bridgePolicyStateSuite) createLoopbackNIC(c *gc.C, machine *state.Machine) {
func (s *bridgePolicyStateSuite) createLoopbackNIC(c *gc.C, machine containerizer.Machine) {
err := machine.SetLinkLayerDevices(
state.LinkLayerDeviceArgs{
Name: "lo",
Expand All @@ -199,15 +206,15 @@ func (s *bridgePolicyStateSuite) createLoopbackNIC(c *gc.C, machine *state.Machi
}

// createAllDefaultDevices creates the loopback, lxcbr0, lxdbr0, and virbr0 devices
func (s *bridgePolicyStateSuite) createAllDefaultDevices(c *gc.C, machine *state.Machine) {
func (s *bridgePolicyStateSuite) createAllDefaultDevices(c *gc.C, machine containerizer.Machine) {
// loopback
s.createLoopbackNIC(c, s.machine)
s.createLoopbackNIC(c, machine)
// container.DefaultLxcBridge
s.createBridgeWithIP(c, s.machine, "lxcbr0", "10.0.3.1/24")
s.createBridgeWithIP(c, machine, "lxcbr0", "10.0.3.1/24")
// container.DefaultLxdBridge
s.createBridgeWithIP(c, s.machine, "lxdbr0", "10.0.4.1/24")
s.createBridgeWithIP(c, machine, "lxdbr0", "10.0.4.1/24")
// container.DefaultKvmBridge
s.createBridgeWithIP(c, s.machine, "virbr0", "192.168.124.1/24")
s.createBridgeWithIP(c, machine, "virbr0", "192.168.124.1/24")
}

func (s *bridgePolicyStateSuite) TestPopulateContainerLinkLayerDevicesCorrectlyPaired(c *gc.C) {
Expand Down Expand Up @@ -345,7 +352,7 @@ func (s *bridgePolicyStateSuite) TestPopulateContainerLinkLayerDevicesUnitBindin
addCharm(c, s.State, "quantal", "mysql"), map[string]string{"server": "default"})
unit, err := app.AddUnit(state.AddUnitParams{})
c.Assert(err, jc.ErrorIsNil)
err = unit.AssignToMachine(s.containerMachine)
err = unit.AssignToMachine(s.containerMachine.Wrapped())
c.Assert(err, jc.ErrorIsNil)
spaces, err := s.containerMachine.DesiredSpaces()
c.Assert(err, jc.ErrorIsNil)
Expand Down
Loading

0 comments on commit f967246

Please sign in to comment.