Example #1
0
func (s *AssignSuite) assertAssignUnitToNewMachineContainerConstraint(c *gc.C) {
	unit, err := s.wordpress.AddUnit()
	c.Assert(err, gc.IsNil)
	err = unit.AssignToNewMachine()
	c.Assert(err, gc.IsNil)
	machineId := s.assertAssignedUnit(c, unit)
	c.Assert(state.ParentId(machineId), gc.Not(gc.Equals), "")
	c.Assert(state.ContainerTypeFromId(machineId), gc.Equals, instance.LXC)
}
Example #2
0
// NewProvisionerAPI creates a new server-side ProvisionerAPI facade.
func NewProvisionerAPI(
	st *state.State,
	resources *common.Resources,
	authorizer common.Authorizer,
) (*ProvisionerAPI, error) {
	if !authorizer.AuthMachineAgent() && !authorizer.AuthEnvironManager() {
		return nil, common.ErrPerm
	}
	getAuthFunc := func() (common.AuthFunc, error) {
		isEnvironManager := authorizer.AuthEnvironManager()
		isMachineAgent := authorizer.AuthMachineAgent()
		authEntityTag := authorizer.GetAuthTag()

		return func(tag string) bool {
			if isMachineAgent && tag == authEntityTag {
				// A machine agent can always access its own machine.
				return true
			}
			_, id, err := names.ParseTag(tag, names.MachineTagKind)
			if err != nil {
				return false
			}
			parentId := state.ParentId(id)
			if parentId == "" {
				// All top-level machines are accessible by the
				// environment manager.
				return isEnvironManager
			}
			// All containers with the authenticated machine as a
			// parent are accessible by it.
			return isMachineAgent && names.MachineTag(parentId) == authEntityTag
		}, nil
	}
	// Both provisioner types can watch the environment.
	getCanWatch := common.AuthAlways(true)
	// Only the environment provisioner can read secrets.
	getCanReadSecrets := common.AuthAlways(authorizer.AuthEnvironManager())
	return &ProvisionerAPI{
		Remover:                common.NewRemover(st, false, getAuthFunc),
		StatusSetter:           common.NewStatusSetter(st, getAuthFunc),
		DeadEnsurer:            common.NewDeadEnsurer(st, getAuthFunc),
		PasswordChanger:        common.NewPasswordChanger(st, getAuthFunc),
		LifeGetter:             common.NewLifeGetter(st, getAuthFunc),
		StateAddresser:         common.NewStateAddresser(st),
		APIAddresser:           common.NewAPIAddresser(st, resources),
		ToolsGetter:            common.NewToolsGetter(st, getAuthFunc),
		EnvironWatcher:         common.NewEnvironWatcher(st, resources, getCanWatch, getCanReadSecrets),
		EnvironMachinesWatcher: common.NewEnvironMachinesWatcher(st, resources, getCanReadSecrets),
		InstanceIdGetter:       common.NewInstanceIdGetter(st, getAuthFunc),
		st:                     st,
		resources:              resources,
		authorizer:             authorizer,
		getAuthFunc:            getAuthFunc,
		getCanWatchMachines:    getCanReadSecrets,
	}, nil
}
Example #3
0
func (s *AssignSuite) assertAssignUnitNewPolicyNoContainer(c *gc.C) {
	_, err := s.State.AddMachine("quantal", state.JobHostUnits) // available machine
	c.Assert(err, gc.IsNil)
	unit, err := s.wordpress.AddUnit()
	c.Assert(err, gc.IsNil)

	err = s.State.AssignUnit(unit, state.AssignNew)
	c.Assert(err, gc.IsNil)
	assertMachineCount(c, s.State, 2)
	id, err := unit.AssignedMachineId()
	c.Assert(err, gc.IsNil)
	c.Assert(state.ParentId(id), gc.Equals, "")
}
Example #4
0
// fetchUnitMachineIds returns a set of IDs for machines that
// the specified units reside on, and those machines' ancestors.
func fetchUnitMachineIds(units map[string]map[string]*state.Unit) (*set.Strings, error) {
	machineIds := new(set.Strings)
	for _, svcUnitMap := range units {
		for _, unit := range svcUnitMap {
			if !unit.IsPrincipal() {
				continue
			}
			mid, err := unit.AssignedMachineId()
			if err != nil {
				return nil, err
			}
			for mid != "" {
				machineIds.Add(mid)
				mid = state.ParentId(mid)
			}
		}
	}
	return machineIds, nil
}
Example #5
0
func (context *statusContext) processMachine(machines []*state.Machine, host *api.MachineStatus, startIndex int) (nextIndex int) {
	nextIndex = startIndex + 1
	currentHost := host
	var previousContainer *api.MachineStatus
	for nextIndex < len(machines) {
		machine := machines[nextIndex]
		container := context.makeMachineStatus(machine)
		if currentHost.Id == state.ParentId(machine.Id()) {
			currentHost.Containers[machine.Id()] = container
			previousContainer = &container
			nextIndex++
		} else {
			if state.NestingLevel(machine.Id()) > state.NestingLevel(previousContainer.Id) {
				nextIndex = context.processMachine(machines, previousContainer, nextIndex-1)
			} else {
				break
			}
		}
	}
	return
}
Example #6
0
// StartInstance is specified in the InstanceBroker interface.
func (e *environ) StartInstance(args environs.StartInstanceParams) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error) {

	defer delay()
	machineId := args.MachineConfig.MachineId
	logger.Infof("dummy startinstance, machine %s", machineId)
	if err := e.checkBroken("StartInstance"); err != nil {
		return nil, nil, nil, err
	}
	estate, err := e.state()
	if err != nil {
		return nil, nil, nil, err
	}
	estate.mu.Lock()
	defer estate.mu.Unlock()
	if args.MachineConfig.MachineNonce == "" {
		return nil, nil, nil, fmt.Errorf("cannot start instance: missing machine nonce")
	}
	if _, ok := e.Config().CACert(); !ok {
		return nil, nil, nil, fmt.Errorf("no CA certificate in environment configuration")
	}
	if args.MachineConfig.StateInfo.Tag != names.MachineTag(machineId) {
		return nil, nil, nil, fmt.Errorf("entity tag must match started machine")
	}
	if args.MachineConfig.APIInfo.Tag != names.MachineTag(machineId) {
		return nil, nil, nil, fmt.Errorf("entity tag must match started machine")
	}
	logger.Infof("would pick tools from %s", args.Tools)
	series := args.Tools.OneSeries()

	idString := fmt.Sprintf("%s-%d", e.name, estate.maxId)
	i := &dummyInstance{
		id:           instance.Id(idString),
		addresses:    instance.NewAddresses(idString + ".dns"),
		ports:        make(map[instance.Port]bool),
		machineId:    machineId,
		series:       series,
		firewallMode: e.Config().FirewallMode(),
		state:        estate,
	}

	var hc *instance.HardwareCharacteristics
	// To match current system capability, only provide hardware characteristics for
	// environ machines, not containers.
	if state.ParentId(machineId) == "" {
		// We will just assume the instance hardware characteristics exactly matches
		// the supplied constraints (if specified).
		hc = &instance.HardwareCharacteristics{
			Arch:     args.Constraints.Arch,
			Mem:      args.Constraints.Mem,
			RootDisk: args.Constraints.RootDisk,
			CpuCores: args.Constraints.CpuCores,
			CpuPower: args.Constraints.CpuPower,
			Tags:     args.Constraints.Tags,
		}
		// Fill in some expected instance hardware characteristics if constraints not specified.
		if hc.Arch == nil {
			arch := "amd64"
			hc.Arch = &arch
		}
		if hc.Mem == nil {
			mem := uint64(1024)
			hc.Mem = &mem
		}
		if hc.RootDisk == nil {
			disk := uint64(8192)
			hc.RootDisk = &disk
		}
		if hc.CpuCores == nil {
			cores := uint64(1)
			hc.CpuCores = &cores
		}
	}
	// Simulate networks added when requested.
	networkInfo := make([]network.Info, len(args.MachineConfig.IncludeNetworks))
	for i, netName := range args.MachineConfig.IncludeNetworks {
		if strings.HasPrefix(netName, "bad-") {
			// Simulate we didn't get correct information for the network.
			networkInfo[i] = network.Info{
				ProviderId:  network.Id(netName),
				NetworkName: netName,
				CIDR:        "invalid",
			}
		} else {
			networkInfo[i] = network.Info{
				ProviderId:    network.Id(netName),
				NetworkName:   netName,
				CIDR:          fmt.Sprintf("0.%d.2.0/24", i+1),
				InterfaceName: fmt.Sprintf("eth%d", i),
				VLANTag:       i,
				MACAddress:    fmt.Sprintf("aa:bb:cc:dd:ee:f%d", i),
				IsVirtual:     i > 0,
			}
		}
	}
	estate.insts[i.id] = i
	estate.maxId++
	estate.ops <- OpStartInstance{
		Env:             e.name,
		MachineId:       machineId,
		MachineNonce:    args.MachineConfig.MachineNonce,
		Constraints:     args.Constraints,
		IncludeNetworks: args.MachineConfig.IncludeNetworks,
		ExcludeNetworks: args.MachineConfig.ExcludeNetworks,
		NetworkInfo:     networkInfo,
		Instance:        i,
		Info:            args.MachineConfig.StateInfo,
		APIInfo:         args.MachineConfig.APIInfo,
		Secret:          e.ecfg().secret(),
	}
	return i, hc, networkInfo, nil
}