github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/distribution.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/instance"
    12  )
    13  
    14  // distributeuUnit takes a unit and set of clean, possibly empty, instances
    15  // and asks the InstanceDistributor policy (if any) which ones are suitable
    16  // for assigning the unit to. If there is no InstanceDistributor, or the
    17  // distribution group is empty, then all of the candidates will be returned.
    18  func distributeUnit(u *Unit, candidates []instance.Id) ([]instance.Id, error) {
    19  	if len(candidates) == 0 {
    20  		return nil, nil
    21  	}
    22  	if u.st.policy == nil {
    23  		return candidates, nil
    24  	}
    25  	distributor, err := u.st.policy.InstanceDistributor()
    26  	if errors.IsNotImplemented(err) {
    27  		return candidates, nil
    28  	} else if err != nil {
    29  		return nil, err
    30  	}
    31  	if distributor == nil {
    32  		return nil, fmt.Errorf("policy returned nil instance distributor without an error")
    33  	}
    34  	distributionGroup, err := ServiceInstances(u.st, u.doc.Application)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	if len(distributionGroup) == 0 {
    39  		return candidates, nil
    40  	}
    41  	return distributor.DistributeInstances(candidates, distributionGroup)
    42  }
    43  
    44  // ServiceInstances returns the instance IDs of provisioned
    45  // machines that are assigned units of the specified application.
    46  func ServiceInstances(st *State, application string) ([]instance.Id, error) {
    47  	units, err := allUnits(st, application)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	instanceIds := make([]instance.Id, 0, len(units))
    52  	for _, unit := range units {
    53  		machineId, err := unit.AssignedMachineId()
    54  		if errors.IsNotAssigned(err) {
    55  			continue
    56  		} else if err != nil {
    57  			return nil, err
    58  		}
    59  		machine, err := st.Machine(machineId)
    60  		if err != nil {
    61  			return nil, err
    62  		}
    63  		instanceId, err := machine.InstanceId()
    64  		if err == nil {
    65  			instanceIds = append(instanceIds, instanceId)
    66  		} else if errors.IsNotProvisioned(err) {
    67  			continue
    68  		} else {
    69  			return nil, err
    70  		}
    71  	}
    72  	return instanceIds, nil
    73  }