Exemple #1
0
func networkParamsToStateParams(networks []params.Network, ifaces []params.NetworkInterface) (
	[]state.NetworkInfo, []state.NetworkInterfaceInfo, error,
) {
	stateNetworks := make([]state.NetworkInfo, len(networks))
	for i, network := range networks {
		tag, err := names.ParseNetworkTag(network.Tag)
		if err != nil {
			return nil, nil, err
		}
		stateNetworks[i] = state.NetworkInfo{
			Name:       tag.Id(),
			ProviderId: network.ProviderId,
			CIDR:       network.CIDR,
			VLANTag:    network.VLANTag,
		}
	}
	stateInterfaces := make([]state.NetworkInterfaceInfo, len(ifaces))
	for i, iface := range ifaces {
		tag, err := names.ParseNetworkTag(iface.NetworkTag)
		if err != nil {
			return nil, nil, err
		}
		stateInterfaces[i] = state.NetworkInterfaceInfo{
			MACAddress:    iface.MACAddress,
			NetworkName:   tag.Id(),
			InterfaceName: iface.InterfaceName,
			IsVirtual:     iface.IsVirtual,
		}
	}
	return stateNetworks, stateInterfaces, nil
}
Exemple #2
0
// ActiveNetworks returns a list of network tags for which the machine
// has opened ports.
func (m *Machine) ActiveNetworks() ([]names.NetworkTag, error) {
	var results params.StringsResults
	args := params.Entities{
		Entities: []params.Entity{{Tag: m.tag.String()}},
	}
	err := m.st.facade.FacadeCall("GetMachineActiveNetworks", args, &results)
	if err != nil {
		return nil, err
	}
	if len(results.Results) != 1 {
		return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results))
	}
	result := results.Results[0]
	if result.Error != nil {
		return nil, result.Error
	}
	// Convert string tags to names.NetworkTag before returning.
	tags := make([]names.NetworkTag, len(result.Result))
	for i, tag := range result.Result {
		networkTag, err := names.ParseNetworkTag(tag)
		if err != nil {
			return nil, err
		}
		tags[i] = networkTag
	}
	return tags, nil
}
Exemple #3
0
func networkTagsToNames(tags []string) ([]string, error) {
	netNames := make([]string, len(tags))
	for i, tag := range tags {
		t, err := names.ParseNetworkTag(tag)
		if err != nil {
			return nil, err
		}
		netNames[i] = t.Id()
	}
	return netNames, nil
}
Exemple #4
0
func (s *networkSuite) TestParseNetworkTag(c *gc.C) {
	for i, t := range parseNetworkTagTests {
		c.Logf("test %d: %s", i, t.tag)
		got, err := names.ParseNetworkTag(t.tag)
		if err != nil || t.err != nil {
			c.Check(err, gc.DeepEquals, t.err)
			continue
		}
		c.Check(got, gc.FitsTypeOf, t.expected)
		c.Check(got, gc.Equals, t.expected)
	}
}
Exemple #5
0
// GetMachinePorts returns the port ranges opened on a machine for the
// specified network as a map mapping port ranges to the tags of the
// units that opened them.
func (f *FirewallerAPI) GetMachinePorts(args params.MachinePortsParams) (params.MachinePortsResults, error) {
	result := params.MachinePortsResults{
		Results: make([]params.MachinePortsResult, len(args.Params)),
	}
	canAccess, err := f.accessMachine()
	if err != nil {
		return params.MachinePortsResults{}, err
	}
	for i, param := range args.Params {
		machineTag, err := names.ParseMachineTag(param.MachineTag)
		if err != nil {
			result.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}
		networkTag, err := names.ParseNetworkTag(param.NetworkTag)
		if err != nil {
			result.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}
		machine, err := f.getMachine(canAccess, machineTag)
		if err != nil {
			result.Results[i].Error = common.ServerError(err)
			continue
		}
		ports, err := machine.OpenedPorts(networkTag.Id())
		if err != nil {
			result.Results[i].Error = common.ServerError(err)
			continue
		}
		if ports != nil {
			portRangeMap := ports.AllPortRanges()
			var portRanges []network.PortRange
			for portRange := range portRangeMap {
				portRanges = append(portRanges, portRange)
			}
			network.SortPortRanges(portRanges)

			for _, portRange := range portRanges {
				unitTag := names.NewUnitTag(portRangeMap[portRange]).String()
				result.Results[i].Ports = append(result.Results[i].Ports,
					params.MachinePortRange{
						UnitTag:   unitTag,
						PortRange: params.FromNetworkPortRange(portRange),
					})
			}
		}
	}
	return result, nil
}
Exemple #6
0
func (s *provisionerSuite) TestSetInstanceInfo(c *gc.C) {
	// Create a fresh machine, since machine 0 is already provisioned.
	notProvisionedMachine, err := s.State.AddMachine("quantal", state.JobHostUnits)
	c.Assert(err, gc.IsNil)

	apiMachine, err := s.provisioner.Machine(notProvisionedMachine.Tag().(names.MachineTag))
	c.Assert(err, gc.IsNil)

	instanceId, err := apiMachine.InstanceId()
	c.Assert(err, jc.Satisfies, params.IsCodeNotProvisioned)
	c.Assert(err, gc.ErrorMatches, "machine 1 is not provisioned")
	c.Assert(instanceId, gc.Equals, instance.Id(""))

	hwChars := instance.MustParseHardware("cpu-cores=123", "mem=4G")

	_, err = s.State.Network("net1")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)
	_, err = s.State.Network("vlan42")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)

	ifacesMachine, err := notProvisionedMachine.NetworkInterfaces()
	c.Assert(err, gc.IsNil)
	c.Assert(ifacesMachine, gc.HasLen, 0)

	networks := []params.Network{{
		Tag:        "network-net1",
		ProviderId: "net1",
		CIDR:       "0.1.2.0/24",
		VLANTag:    0,
	}, {
		Tag:        "network-vlan42",
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}, {
		Tag:        "network-vlan69",
		ProviderId: "vlan69",
		CIDR:       "0.3.2.0/24",
		VLANTag:    69,
	}, {
		Tag:        "network-vlan42", // duplicated; ignored
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}}
	ifaces := []params.NetworkInterface{{
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		NetworkTag:    "network-net1",
		InterfaceName: "eth0",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth1.42",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-vlan69",
		InterfaceName: "eth1.69",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1", // duplicated mac+net; ignored
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth2",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f4",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1", // duplicated name+machine id; ignored
		IsVirtual:     false,
	}}

	err = apiMachine.SetInstanceInfo("i-will", "fake_nonce", &hwChars, networks, ifaces)
	c.Assert(err, gc.IsNil)

	instanceId, err = apiMachine.InstanceId()
	c.Assert(err, gc.IsNil)
	c.Assert(instanceId, gc.Equals, instance.Id("i-will"))

	// Try it again - should fail.
	err = apiMachine.SetInstanceInfo("i-wont", "fake", nil, nil, nil)
	c.Assert(err, gc.ErrorMatches, `aborted instance "i-wont": cannot set instance data for machine "1": already set`)

	// Now try to get machine 0's instance id.
	apiMachine, err = s.provisioner.Machine(s.machine.Tag().(names.MachineTag))
	c.Assert(err, gc.IsNil)
	instanceId, err = apiMachine.InstanceId()
	c.Assert(err, gc.IsNil)
	c.Assert(instanceId, gc.Equals, instance.Id("i-manager"))

	// Check the networks are created.
	for i, _ := range networks {
		if i == 3 {
			// Last one was ignored, so skip it.
			break
		}
		tag, err := names.ParseNetworkTag(networks[i].Tag)
		c.Assert(err, gc.IsNil)
		networkName := tag.Id()
		network, err := s.State.Network(networkName)
		c.Assert(err, gc.IsNil)
		c.Check(network.Name(), gc.Equals, networkName)
		c.Check(network.ProviderId(), gc.Equals, networks[i].ProviderId)
		c.Check(network.Tag().String(), gc.Equals, networks[i].Tag)
		c.Check(network.VLANTag(), gc.Equals, networks[i].VLANTag)
		c.Check(network.CIDR(), gc.Equals, networks[i].CIDR)
	}

	// And the network interfaces as well.
	ifacesMachine, err = notProvisionedMachine.NetworkInterfaces()
	c.Assert(err, gc.IsNil)
	c.Assert(ifacesMachine, gc.HasLen, 4)
	actual := make([]params.NetworkInterface, len(ifacesMachine))
	for i, iface := range ifacesMachine {
		actual[i].InterfaceName = iface.InterfaceName()
		actual[i].NetworkTag = iface.NetworkTag().String()
		actual[i].MACAddress = iface.MACAddress()
		actual[i].IsVirtual = iface.IsVirtual()
		c.Check(iface.MachineTag(), gc.Equals, notProvisionedMachine.Tag())
		c.Check(iface.MachineId(), gc.Equals, notProvisionedMachine.Id())
	}
	c.Assert(actual, jc.SameContents, ifaces[:4]) // skip the rest as they are ignored.
}
Exemple #7
0
func (s *provisionerSuite) TestSetInstanceInfo(c *gc.C) {
	pm := poolmanager.New(state.NewStateSettings(s.State))
	_, err := pm.Create("loop-pool", provider.LoopProviderType, map[string]interface{}{"foo": "bar"})
	c.Assert(err, jc.ErrorIsNil)

	// Create a fresh machine, since machine 0 is already provisioned.
	template := state.MachineTemplate{
		Series: "quantal",
		Jobs:   []state.MachineJob{state.JobHostUnits},
		Volumes: []state.MachineVolumeParams{{
			Volume: state.VolumeParams{
				Pool: "loop-pool",
				Size: 123,
			}},
		},
	}
	notProvisionedMachine, err := s.State.AddOneMachine(template)
	c.Assert(err, jc.ErrorIsNil)

	apiMachine, err := s.provisioner.Machine(notProvisionedMachine.Tag().(names.MachineTag))
	c.Assert(err, jc.ErrorIsNil)

	instanceId, err := apiMachine.InstanceId()
	c.Assert(err, jc.Satisfies, params.IsCodeNotProvisioned)
	c.Assert(err, gc.ErrorMatches, "machine 1 not provisioned")
	c.Assert(instanceId, gc.Equals, instance.Id(""))

	hwChars := instance.MustParseHardware("cpu-cores=123", "mem=4G")

	_, err = s.State.Network("net1")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)
	_, err = s.State.Network("vlan42")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)

	ifacesMachine, err := notProvisionedMachine.NetworkInterfaces()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(ifacesMachine, gc.HasLen, 0)

	networks := []params.Network{{
		Tag:        "network-net1",
		ProviderId: "net1",
		CIDR:       "0.1.2.0/24",
		VLANTag:    0,
	}, {
		Tag:        "network-vlan42",
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}, {
		Tag:        "network-vlan69",
		ProviderId: "vlan69",
		CIDR:       "0.3.2.0/24",
		VLANTag:    69,
	}, {
		Tag:        "network-vlan42", // duplicated; ignored
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}}
	ifaces := []params.NetworkInterface{{
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		NetworkTag:    "network-net1",
		InterfaceName: "eth0",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth1.42",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-vlan69",
		InterfaceName: "eth1.69",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1", // duplicated mac+net; ignored
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth2",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f4",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1", // duplicated name+machine id; ignored
		IsVirtual:     false,
	}}
	volumes := []params.Volume{{
		VolumeTag: "volume-1-0",
		Info: params.VolumeInfo{
			VolumeId: "vol-123",
			Size:     124,
		},
	}}
	volumeAttachments := map[string]params.VolumeAttachmentInfo{
		"volume-1-0": {
			DeviceName: "xvdf1",
		},
	}

	err = apiMachine.SetInstanceInfo(
		"i-will", "fake_nonce", &hwChars, networks, ifaces, volumes, volumeAttachments,
	)
	c.Assert(err, jc.ErrorIsNil)

	instanceId, err = apiMachine.InstanceId()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(instanceId, gc.Equals, instance.Id("i-will"))

	// Try it again - should fail.
	err = apiMachine.SetInstanceInfo("i-wont", "fake", nil, nil, nil, nil, nil)
	c.Assert(err, gc.ErrorMatches, `cannot record provisioning info for "i-wont": cannot set instance data for machine "1": already set`)

	// Now try to get machine 0's instance id.
	apiMachine, err = s.provisioner.Machine(s.machine.Tag().(names.MachineTag))
	c.Assert(err, jc.ErrorIsNil)
	instanceId, err = apiMachine.InstanceId()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(instanceId, gc.Equals, instance.Id("i-manager"))

	// Check the networks are created.
	for i := range networks {
		if i == 3 {
			// Last one was ignored, so skip it.
			break
		}
		tag, err := names.ParseNetworkTag(networks[i].Tag)
		c.Assert(err, jc.ErrorIsNil)
		networkName := tag.Id()
		nw, err := s.State.Network(networkName)
		c.Assert(err, jc.ErrorIsNil)
		c.Check(nw.Name(), gc.Equals, networkName)
		c.Check(nw.ProviderId(), gc.Equals, network.Id(networks[i].ProviderId))
		c.Check(nw.Tag().String(), gc.Equals, networks[i].Tag)
		c.Check(nw.VLANTag(), gc.Equals, networks[i].VLANTag)
		c.Check(nw.CIDR(), gc.Equals, networks[i].CIDR)
	}

	// And the network interfaces as well.
	ifacesMachine, err = notProvisionedMachine.NetworkInterfaces()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(ifacesMachine, gc.HasLen, 4)
	actual := make([]params.NetworkInterface, len(ifacesMachine))
	for i, iface := range ifacesMachine {
		actual[i].InterfaceName = iface.InterfaceName()
		actual[i].NetworkTag = iface.NetworkTag().String()
		actual[i].MACAddress = iface.MACAddress()
		actual[i].IsVirtual = iface.IsVirtual()
		c.Check(iface.MachineTag(), gc.Equals, notProvisionedMachine.Tag())
		c.Check(iface.MachineId(), gc.Equals, notProvisionedMachine.Id())
	}
	c.Assert(actual, jc.SameContents, ifaces[:4]) // skip the rest as they are ignored.

	// Now check volumes and volume attachments.
	volume, err := s.State.Volume(names.NewVolumeTag("1/0"))
	c.Assert(err, jc.ErrorIsNil)
	volumeInfo, err := volume.Info()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(volumeInfo, gc.Equals, state.VolumeInfo{
		VolumeId: "vol-123",
		Pool:     "loop-pool",
		Size:     124,
	})
	stateVolumeAttachments, err := s.State.MachineVolumeAttachments(names.NewMachineTag("1"))
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(stateVolumeAttachments, gc.HasLen, 1)
	volumeAttachmentInfo, err := stateVolumeAttachments[0].Info()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(volumeAttachmentInfo, gc.Equals, state.VolumeAttachmentInfo{
		DeviceName: "xvdf1",
	})
}
Exemple #8
0
func (s *withoutStateServerSuite) TestSetInstanceInfo(c *gc.C) {
	// Provision machine 0 first.
	hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
	err := s.machines[0].SetInstanceInfo("i-am", "fake_nonce", &hwChars, nil, nil)
	c.Assert(err, gc.IsNil)

	networks := []params.Network{{
		Tag:        "network-net1",
		ProviderId: "net1",
		CIDR:       "0.1.2.0/24",
		VLANTag:    0,
	}, {
		Tag:        "network-vlan42",
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}, {
		Tag:        "network-vlan69",
		ProviderId: "vlan69",
		CIDR:       "0.3.2.0/24",
		VLANTag:    69,
	}, {
		Tag:        "network-vlan42", // duplicated; ignored
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}}
	ifaces := []params.NetworkInterface{{
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		NetworkTag:    "network-net1",
		InterfaceName: "eth0",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth1.42",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		NetworkTag:    "network-vlan69",
		InterfaceName: "eth0.69",
		IsVirtual:     true,
		Disabled:      true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1", // duplicated mac+net; ignored
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth2",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f2",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1", // duplicated name+machine id; ignored for machine 1.
		IsVirtual:     false,
	}}
	args := params.InstancesInfo{Machines: []params.InstanceInfo{{
		Tag:        s.machines[0].Tag().String(),
		InstanceId: "i-was",
		Nonce:      "fake_nonce",
	}, {
		Tag:             s.machines[1].Tag().String(),
		InstanceId:      "i-will",
		Nonce:           "fake_nonce",
		Characteristics: &hwChars,
		Networks:        networks,
		Interfaces:      ifaces,
	}, {
		Tag:             s.machines[2].Tag().String(),
		InstanceId:      "i-am-too",
		Nonce:           "fake",
		Characteristics: nil,
		Networks:        networks,
		Interfaces:      ifaces,
	},
		{Tag: "machine-42"},
		{Tag: "unit-foo-0"},
		{Tag: "service-bar"},
	}}
	result, err := s.provisioner.SetInstanceInfo(args)
	c.Assert(err, gc.IsNil)
	c.Assert(result, jc.DeepEquals, params.ErrorResults{
		Results: []params.ErrorResult{
			{&params.Error{
				Message: `aborted instance "i-was": cannot set instance data for machine "0": already set`,
			}},
			{nil},
			{nil},
			{apiservertesting.NotFoundError("machine 42")},
			{apiservertesting.ErrUnauthorized},
			{apiservertesting.ErrUnauthorized},
		},
	})

	// Verify machine 1 and 2 were provisioned.
	c.Assert(s.machines[1].Refresh(), gc.IsNil)
	c.Assert(s.machines[2].Refresh(), gc.IsNil)

	instanceId, err := s.machines[1].InstanceId()
	c.Assert(err, gc.IsNil)
	c.Check(instanceId, gc.Equals, instance.Id("i-will"))
	instanceId, err = s.machines[2].InstanceId()
	c.Assert(err, gc.IsNil)
	c.Check(instanceId, gc.Equals, instance.Id("i-am-too"))
	c.Check(s.machines[1].CheckProvisioned("fake_nonce"), jc.IsTrue)
	c.Check(s.machines[2].CheckProvisioned("fake"), jc.IsTrue)
	gotHardware, err := s.machines[1].HardwareCharacteristics()
	c.Assert(err, gc.IsNil)
	c.Check(gotHardware, gc.DeepEquals, &hwChars)
	ifacesMachine1, err := s.machines[1].NetworkInterfaces()
	c.Assert(err, gc.IsNil)
	c.Assert(ifacesMachine1, gc.HasLen, 4)
	actual := make([]params.NetworkInterface, len(ifacesMachine1))
	for i, iface := range ifacesMachine1 {
		actual[i].InterfaceName = iface.InterfaceName()
		actual[i].NetworkTag = iface.NetworkTag()
		actual[i].MACAddress = iface.MACAddress()
		actual[i].IsVirtual = iface.IsVirtual()
		actual[i].Disabled = iface.IsDisabled()
		c.Check(iface.MachineId(), gc.Equals, s.machines[1].Id())
		c.Check(iface.MachineTag(), gc.Equals, s.machines[1].Tag().String())
	}
	c.Assert(actual, jc.SameContents, ifaces[:4])
	ifacesMachine2, err := s.machines[2].NetworkInterfaces()
	c.Assert(err, gc.IsNil)
	c.Assert(ifacesMachine2, gc.HasLen, 1)
	c.Assert(ifacesMachine2[0].InterfaceName(), gc.Equals, ifaces[5].InterfaceName)
	c.Assert(ifacesMachine2[0].MACAddress(), gc.Equals, ifaces[5].MACAddress)
	c.Assert(ifacesMachine2[0].NetworkTag(), gc.Equals, ifaces[5].NetworkTag)
	c.Assert(ifacesMachine2[0].MachineId(), gc.Equals, s.machines[2].Id())
	for i, _ := range networks {
		if i == 3 {
			// Last one was ignored, so don't check.
			break
		}
		tag, err := names.ParseNetworkTag(networks[i].Tag)
		c.Assert(err, gc.IsNil)
		networkName := tag.Id()
		network, err := s.State.Network(networkName)
		c.Assert(err, gc.IsNil)
		c.Check(network.Name(), gc.Equals, networkName)
		c.Check(network.ProviderId(), gc.Equals, networks[i].ProviderId)
		c.Check(network.Tag().String(), gc.Equals, networks[i].Tag)
		c.Check(network.VLANTag(), gc.Equals, networks[i].VLANTag)
		c.Check(network.CIDR(), gc.Equals, networks[i].CIDR)
	}
}
Exemple #9
0
func (s *withoutControllerSuite) TestSetInstanceInfo(c *gc.C) {
	s.registerStorageProviders(c, "static")

	pm := poolmanager.New(state.NewStateSettings(s.State))
	_, err := pm.Create("static-pool", "static", map[string]interface{}{"foo": "bar"})
	c.Assert(err, jc.ErrorIsNil)
	err = s.State.UpdateModelConfig(map[string]interface{}{
		"storage-default-block-source": "static-pool",
	}, nil, nil)
	c.Assert(err, jc.ErrorIsNil)

	// Provision machine 0 first.
	hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
	err = s.machines[0].SetInstanceInfo("i-am", "fake_nonce", &hwChars, nil, nil, nil, nil)
	c.Assert(err, jc.ErrorIsNil)

	volumesMachine, err := s.State.AddOneMachine(state.MachineTemplate{
		Series: "quantal",
		Jobs:   []state.MachineJob{state.JobHostUnits},
		Volumes: []state.MachineVolumeParams{{
			Volume: state.VolumeParams{Size: 1000},
		}},
	})
	c.Assert(err, jc.ErrorIsNil)

	networks := []params.Network{{
		Tag:        "network-net1",
		ProviderId: "net1",
		CIDR:       "0.1.2.0/24",
		VLANTag:    0,
	}, {
		Tag:        "network-vlan42",
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}, {
		Tag:        "network-vlan69",
		ProviderId: "vlan69",
		CIDR:       "0.3.2.0/24",
		VLANTag:    69,
	}, {
		Tag:        "network-vlan42", // duplicated; ignored
		ProviderId: "vlan42",
		CIDR:       "0.2.2.0/24",
		VLANTag:    42,
	}}
	ifaces := []params.NetworkInterface{{
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		NetworkTag:    "network-net1",
		InterfaceName: "eth0",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1",
		IsVirtual:     false,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1",
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth1.42",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		NetworkTag:    "network-vlan69",
		InterfaceName: "eth0.69",
		IsVirtual:     true,
		Disabled:      true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f1", // duplicated mac+net; ignored
		NetworkTag:    "network-vlan42",
		InterfaceName: "eth2",
		IsVirtual:     true,
	}, {
		MACAddress:    "aa:bb:cc:dd:ee:f2",
		NetworkTag:    "network-net1",
		InterfaceName: "eth1", // duplicated name+machine id; ignored for machine 1.
		IsVirtual:     false,
	}}
	args := params.InstancesInfo{Machines: []params.InstanceInfo{{
		Tag:        s.machines[0].Tag().String(),
		InstanceId: "i-was",
		Nonce:      "fake_nonce",
	}, {
		Tag:             s.machines[1].Tag().String(),
		InstanceId:      "i-will",
		Nonce:           "fake_nonce",
		Characteristics: &hwChars,
		Networks:        networks,
		Interfaces:      ifaces,
	}, {
		Tag:             s.machines[2].Tag().String(),
		InstanceId:      "i-am-too",
		Nonce:           "fake",
		Characteristics: nil,
		Networks:        networks,
		Interfaces:      ifaces,
	}, {
		Tag:        volumesMachine.Tag().String(),
		InstanceId: "i-am-also",
		Nonce:      "fake",
		Volumes: []params.Volume{{
			VolumeTag: "volume-0",
			Info: params.VolumeInfo{
				VolumeId: "vol-0",
				Size:     1234,
			},
		}},
		VolumeAttachments: map[string]params.VolumeAttachmentInfo{
			"volume-0": {
				DeviceName: "sda",
			},
		},
	},
		{Tag: "machine-42"},
		{Tag: "unit-foo-0"},
		{Tag: "service-bar"},
	}}
	result, err := s.provisioner.SetInstanceInfo(args)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(result, jc.DeepEquals, params.ErrorResults{
		Results: []params.ErrorResult{
			{&params.Error{
				Message: `cannot record provisioning info for "i-was": cannot set instance data for machine "0": already set`,
			}},
			{nil},
			{nil},
			{nil},
			{apiservertesting.NotFoundError("machine 42")},
			{apiservertesting.ErrUnauthorized},
			{apiservertesting.ErrUnauthorized},
		},
	})

	// Verify machine 1 and 2 were provisioned.
	c.Assert(s.machines[1].Refresh(), gc.IsNil)
	c.Assert(s.machines[2].Refresh(), gc.IsNil)

	instanceId, err := s.machines[1].InstanceId()
	c.Assert(err, jc.ErrorIsNil)
	c.Check(instanceId, gc.Equals, instance.Id("i-will"))
	instanceId, err = s.machines[2].InstanceId()
	c.Assert(err, jc.ErrorIsNil)
	c.Check(instanceId, gc.Equals, instance.Id("i-am-too"))
	c.Check(s.machines[1].CheckProvisioned("fake_nonce"), jc.IsTrue)
	c.Check(s.machines[2].CheckProvisioned("fake"), jc.IsTrue)
	gotHardware, err := s.machines[1].HardwareCharacteristics()
	c.Assert(err, jc.ErrorIsNil)
	c.Check(gotHardware, gc.DeepEquals, &hwChars)
	ifacesMachine1, err := s.machines[1].NetworkInterfaces()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(ifacesMachine1, gc.HasLen, 4)
	actual := make([]params.NetworkInterface, len(ifacesMachine1))
	for i, iface := range ifacesMachine1 {
		actual[i].InterfaceName = iface.InterfaceName()
		actual[i].NetworkTag = iface.NetworkTag().String()
		actual[i].MACAddress = iface.MACAddress()
		actual[i].IsVirtual = iface.IsVirtual()
		actual[i].Disabled = iface.IsDisabled()
		c.Check(iface.MachineId(), gc.Equals, s.machines[1].Id())
		c.Check(iface.MachineTag(), gc.Equals, s.machines[1].Tag())
	}
	c.Assert(actual, jc.SameContents, ifaces[:4])
	ifacesMachine2, err := s.machines[2].NetworkInterfaces()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(ifacesMachine2, gc.HasLen, 1)
	c.Assert(ifacesMachine2[0].InterfaceName(), gc.Equals, ifaces[5].InterfaceName)
	c.Assert(ifacesMachine2[0].MACAddress(), gc.Equals, ifaces[5].MACAddress)
	c.Assert(ifacesMachine2[0].NetworkTag().String(), gc.Equals, ifaces[5].NetworkTag)
	c.Assert(ifacesMachine2[0].MachineId(), gc.Equals, s.machines[2].Id())
	for i := range networks {
		if i == 3 {
			// Last one was ignored, so don't check.
			break
		}
		tag, err := names.ParseNetworkTag(networks[i].Tag)
		c.Assert(err, jc.ErrorIsNil)
		networkName := tag.Id()
		nw, err := s.State.Network(networkName)
		c.Assert(err, jc.ErrorIsNil)
		c.Check(nw.Name(), gc.Equals, networkName)
		c.Check(nw.ProviderId(), gc.Equals, network.Id(networks[i].ProviderId))
		c.Check(nw.Tag().String(), gc.Equals, networks[i].Tag)
		c.Check(nw.VLANTag(), gc.Equals, networks[i].VLANTag)
		c.Check(nw.CIDR(), gc.Equals, networks[i].CIDR)
	}

	// Verify the machine with requested volumes was provisioned, and the
	// volume information recorded in state.
	volumeAttachments, err := s.State.MachineVolumeAttachments(volumesMachine.MachineTag())
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(volumeAttachments, gc.HasLen, 1)
	volumeAttachmentInfo, err := volumeAttachments[0].Info()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(volumeAttachmentInfo, gc.Equals, state.VolumeAttachmentInfo{DeviceName: "sda"})
	volume, err := s.State.Volume(volumeAttachments[0].Volume())
	c.Assert(err, jc.ErrorIsNil)
	volumeInfo, err := volume.Info()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(volumeInfo, gc.Equals, state.VolumeInfo{VolumeId: "vol-0", Pool: "static-pool", Size: 1234})

	// Verify the machine without requested volumes still has no volume
	// attachments recorded in state.
	volumeAttachments, err = s.State.MachineVolumeAttachments(s.machines[1].MachineTag())
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(volumeAttachments, gc.HasLen, 0)
}