~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/state/state.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
        "github.com/juju/loggo"
20
20
        jujutxn "github.com/juju/txn"
21
21
        "github.com/juju/utils"
 
22
        "github.com/juju/utils/clock"
22
23
        "github.com/juju/utils/os"
23
24
        "github.com/juju/utils/series"
24
25
        "github.com/juju/utils/set"
33
34
        "github.com/juju/juju/apiserver/params"
34
35
        "github.com/juju/juju/audit"
35
36
        "github.com/juju/juju/constraints"
36
 
        "github.com/juju/juju/core/description"
37
37
        "github.com/juju/juju/core/lease"
38
38
        "github.com/juju/juju/instance"
39
39
        "github.com/juju/juju/mongo"
40
40
        "github.com/juju/juju/network"
 
41
        "github.com/juju/juju/permission"
41
42
        "github.com/juju/juju/state/cloudimagemetadata"
42
43
        stateaudit "github.com/juju/juju/state/internal/audit"
43
44
        statelease "github.com/juju/juju/state/lease"
75
76
// State represents the state of an model
76
77
// managed by juju.
77
78
type State struct {
 
79
        clock              clock.Clock
78
80
        modelTag           names.ModelTag
79
81
        controllerModelTag names.ModelTag
80
82
        controllerTag      names.ControllerTag
147
149
        return st.controllerTag
148
150
}
149
151
 
150
 
func ControllerAccess(st *State, tag names.Tag) (description.UserAccess, error) {
 
152
func ControllerAccess(st *State, tag names.Tag) (permission.UserAccess, error) {
151
153
        return st.UserAccess(tag.(names.UserTag), st.controllerTag)
152
154
}
153
155
 
301
303
func (st *State) ForModel(modelTag names.ModelTag) (*State, error) {
302
304
        session := st.session.Copy()
303
305
        newSt, err := newState(
304
 
                modelTag, st.controllerModelTag, session, st.mongoInfo, st.newPolicy,
 
306
                modelTag, st.controllerModelTag, session, st.mongoInfo, st.newPolicy, st.clock,
305
307
        )
306
308
        if err != nil {
307
309
                return nil, errors.Trace(err)
350
352
        // now we've set up leaseClientId, we can use workersFactory
351
353
 
352
354
        logger.Infof("starting standard state workers")
353
 
        clock := GetClock()
354
355
        factory := workersFactory{
355
356
                st:    st,
356
 
                clock: clock,
 
357
                clock: st.clock,
357
358
        }
358
359
        workers, err := workers.NewRestartWorkers(workers.RestartConfig{
359
360
                Factory: factory,
360
361
                Logger:  loggo.GetLogger(logger.Name() + ".workers"),
361
 
                Clock:   clock,
 
362
                Clock:   st.clock,
362
363
                Delay:   time.Second,
363
364
        })
364
365
        if err != nil {
382
383
                Namespace:  applicationLeadershipNamespace,
383
384
                Collection: leasesC,
384
385
                Mongo:      &environMongo{st},
385
 
                Clock:      GetClock(),
 
386
                Clock:      st.clock,
386
387
        })
387
388
        if err != nil {
388
389
                return nil, errors.Annotatef(err, "cannot create leadership lease client")
396
397
                Namespace:  singularControllerNamespace,
397
398
                Collection: leasesC,
398
399
                Mongo:      &environMongo{st},
399
 
                Clock:      GetClock(),
 
400
                Clock:      st.clock,
400
401
        })
401
402
        if err != nil {
402
403
                return nil, errors.Annotatef(err, "cannot create singular lease client")
683
684
        return writeConstraints(st, modelGlobalKey, cons)
684
685
}
685
686
 
686
 
// AllMachines returns all machines in the model
687
 
// ordered by id.
688
 
func (st *State) AllMachines() (machines []*Machine, err error) {
689
 
        machinesCollection, closer := st.getCollection(machinesC)
690
 
        defer closer()
691
 
 
 
687
func (st *State) allMachines(machinesCollection mongo.Collection) ([]*Machine, error) {
692
688
        mdocs := machineDocSlice{}
693
 
        err = machinesCollection.Find(nil).All(&mdocs)
 
689
        err := machinesCollection.Find(nil).All(&mdocs)
694
690
        if err != nil {
695
691
                return nil, errors.Annotatef(err, "cannot get all machines")
696
692
        }
697
693
        sort.Sort(mdocs)
698
 
        for _, doc := range mdocs {
699
 
                machines = append(machines, newMachine(st, &doc))
 
694
        machines := make([]*Machine, len(mdocs))
 
695
        for i, doc := range mdocs {
 
696
                machines[i] = newMachine(st, &doc)
700
697
        }
701
 
        return
 
698
        return machines, nil
 
699
}
 
700
 
 
701
// AllMachines returns all machines in the model
 
702
// ordered by id.
 
703
func (st *State) AllMachines() ([]*Machine, error) {
 
704
        machinesCollection, closer := st.getCollection(machinesC)
 
705
        defer closer()
 
706
        return st.allMachines(machinesCollection)
 
707
}
 
708
 
 
709
// AllMachinesFor returns all machines for the model represented
 
710
// by the given modeluuid
 
711
func (st *State) AllMachinesFor(modelUUID string) ([]*Machine, error) {
 
712
        machinesCollection, closer := st.getCollectionFor(modelUUID, machinesC)
 
713
        defer closer()
 
714
        return st.allMachines(machinesCollection)
702
715
}
703
716
 
704
717
type machineDocSlice []machineDoc
1073
1086
        }
1074
1087
 
1075
1088
        statusDoc := statusDoc{
1076
 
                ModelUUID: st.ModelUUID(),
1077
 
                // TODO(fwereade): this violates the spec. Should be "waiting".
1078
 
                // Implemented like this to be consistent with incorrect add-unit
1079
 
                // behaviour.
1080
 
                Status:     status.StatusUnknown,
1081
 
                StatusInfo: MessageWaitForAgentInit,
1082
 
                // TODO(fwereade): 2016-03-17 lp:1558657
1083
 
                Updated: time.Now().UnixNano(),
 
1089
                ModelUUID:  st.ModelUUID(),
 
1090
                Status:     status.Waiting,
 
1091
                StatusInfo: status.MessageWaitForMachine,
 
1092
                Updated:    st.clock.Now().UnixNano(),
1084
1093
                // This exists to preserve questionable unit-aggregation behaviour
1085
1094
                // while we work out how to switch to an implementation that makes
1086
1095
                // sense. It is also set in AddMissingServiceStatuses.
1148
1157
                if err := checkModelActive(st); err != nil {
1149
1158
                        return nil, errors.Trace(err)
1150
1159
                }
 
1160
                // TODO(fwereade): 2016-09-09 lp:1621754
 
1161
                // This is not always correct -- there are a million
 
1162
                // operations collected in this func, not *all* of them
 
1163
                // imply that this is the problem. (e.g. the charm being
 
1164
                // destroyed just as we add application will fail, but
 
1165
                // not because "application already exists")
1151
1166
                return nil, errors.Errorf("application already exists")
1152
1167
        } else if err != nil {
1153
1168
                return nil, errors.Trace(err)
1731
1746
                }
1732
1747
                return u.AssignToMachine(m)
1733
1748
        case AssignClean:
1734
 
                if _, err = u.AssignToCleanMachine(); err != noCleanMachines {
 
1749
                if _, err = u.AssignToCleanMachine(); errors.Cause(err) != noCleanMachines {
1735
1750
                        return errors.Trace(err)
1736
1751
                }
1737
1752
                return u.AssignToNewMachineOrContainer()
1738
1753
        case AssignCleanEmpty:
1739
 
                if _, err = u.AssignToCleanEmptyMachine(); err != noCleanMachines {
 
1754
                if _, err = u.AssignToCleanEmptyMachine(); errors.Cause(err) != noCleanMachines {
1740
1755
                        return errors.Trace(err)
1741
1756
                }
1742
1757
                return u.AssignToNewMachineOrContainer()
2024
2039
        }
2025
2040
        return p + key[2:], true
2026
2041
}
 
2042
 
 
2043
// SetClockForTesting is an exported function to allow other packages
 
2044
// to set the internal clock for the State instance. It is named such
 
2045
// that it should be obvious if it is ever called from a non-test packgae.
 
2046
func (st *State) SetClockForTesting(clock clock.Clock) error {
 
2047
        st.clock = clock
 
2048
        // Need to restart the lease workers so they get the new clock.
 
2049
        st.workers.Kill()
 
2050
        err := st.workers.Wait()
 
2051
        if err != nil {
 
2052
                return errors.Trace(err)
 
2053
        }
 
2054
        err = st.start(st.controllerTag)
 
2055
        if err != nil {
 
2056
                return errors.Trace(err)
 
2057
        }
 
2058
        return nil
 
2059
}