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

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/core/migration/phase.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2016 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package migration
 
5
 
 
6
// Phase values specify model migration phases.
 
7
type Phase int
 
8
 
 
9
// Enumerate all possible migration phases.
 
10
const (
 
11
        UNKNOWN Phase = iota
 
12
        QUIESCE
 
13
        READONLY
 
14
        PRECHECK
 
15
        IMPORT
 
16
        VALIDATION
 
17
        SUCCESS
 
18
        LOGTRANSFER
 
19
        REAP
 
20
        REAPFAILED
 
21
        DONE
 
22
        ABORT
 
23
)
 
24
 
 
25
var phaseNames = []string{
 
26
        "UNKNOWN",
 
27
        "QUIESCE",
 
28
        "READONLY",
 
29
        "PRECHECK",
 
30
        "VALIDATION",
 
31
        "IMPORT",
 
32
        "SUCCESS",
 
33
        "LOGTRANSFER",
 
34
        "REAP",
 
35
        "REAPFAILED",
 
36
        "DONE",
 
37
        "ABORT",
 
38
}
 
39
 
 
40
// String returns the name of an model migration phase constant.
 
41
func (p Phase) String() string {
 
42
        i := int(p)
 
43
        if i >= 0 && i < len(phaseNames) {
 
44
                return phaseNames[i]
 
45
        }
 
46
        return "UNKNOWN"
 
47
}
 
48
 
 
49
// CanTransitionTo returns true if the given phase is a valid next
 
50
// model migration phase.
 
51
func (p Phase) CanTransitionTo(targetPhase Phase) bool {
 
52
        nextPhases, exists := validTransitions[p]
 
53
        if !exists {
 
54
                return false
 
55
        }
 
56
        for _, nextPhase := range nextPhases {
 
57
                if nextPhase == targetPhase {
 
58
                        return true
 
59
                }
 
60
        }
 
61
        return false
 
62
}
 
63
 
 
64
// IsTerminal returns true if the phase is one which signifies the end
 
65
// of a migration.
 
66
func (p Phase) IsTerminal() bool {
 
67
        for _, t := range terminalPhases {
 
68
                if p == t {
 
69
                        return true
 
70
                }
 
71
        }
 
72
        return false
 
73
}
 
74
 
 
75
// Define all possible phase transitions.
 
76
//
 
77
// The keys are the "from" states and the values enumerate the
 
78
// possible "to" states.
 
79
var validTransitions = map[Phase][]Phase{
 
80
        QUIESCE:     {READONLY, ABORT},
 
81
        READONLY:    {PRECHECK, ABORT},
 
82
        PRECHECK:    {IMPORT, ABORT},
 
83
        IMPORT:      {VALIDATION, ABORT},
 
84
        VALIDATION:  {SUCCESS, ABORT},
 
85
        SUCCESS:     {LOGTRANSFER},
 
86
        LOGTRANSFER: {REAP},
 
87
        REAP:        {DONE, REAPFAILED},
 
88
}
 
89
 
 
90
var terminalPhases []Phase
 
91
 
 
92
func init() {
 
93
        // Compute the terminal phases.
 
94
        for p := 0; p <= len(phaseNames); p++ {
 
95
                phase := Phase(p)
 
96
                if _, exists := validTransitions[phase]; !exists {
 
97
                        terminalPhases = append(terminalPhases, phase)
 
98
                }
 
99
        }
 
100
}
 
101
 
 
102
// ParsePhase converts a string model migration phase name
 
103
// to its constant value.
 
104
func ParsePhase(target string) (Phase, bool) {
 
105
        for p, name := range phaseNames {
 
106
                if target == name {
 
107
                        return Phase(p), true
 
108
                }
 
109
        }
 
110
        return UNKNOWN, false
 
111
}