github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/core/migration/phase.go (about) 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 NONE 13 QUIESCE 14 READONLY 15 PRECHECK 16 IMPORT 17 VALIDATION 18 SUCCESS 19 LOGTRANSFER 20 REAP 21 REAPFAILED 22 DONE 23 ABORT 24 ABORTDONE 25 ) 26 27 var phaseNames = []string{ 28 "UNKNOWN", // To catch uninitialised fields. 29 "NONE", // For watchers to indicate there's never been a migration attempt. 30 "QUIESCE", 31 "READONLY", 32 "PRECHECK", 33 "VALIDATION", 34 "IMPORT", 35 "SUCCESS", 36 "LOGTRANSFER", 37 "REAP", 38 "REAPFAILED", 39 "DONE", 40 "ABORT", 41 "ABORTDONE", 42 } 43 44 // String returns the name of an model migration phase constant. 45 func (p Phase) String() string { 46 i := int(p) 47 if i >= 0 && i < len(phaseNames) { 48 return phaseNames[i] 49 } 50 return "UNKNOWN" 51 } 52 53 // CanTransitionTo returns true if the given phase is a valid next 54 // model migration phase. 55 func (p Phase) CanTransitionTo(targetPhase Phase) bool { 56 nextPhases, exists := validTransitions[p] 57 if !exists { 58 return false 59 } 60 for _, nextPhase := range nextPhases { 61 if nextPhase == targetPhase { 62 return true 63 } 64 } 65 return false 66 } 67 68 // IsTerminal returns true if the phase is one which signifies the end 69 // of a migration. 70 func (p Phase) IsTerminal() bool { 71 for _, t := range terminalPhases { 72 if p == t { 73 return true 74 } 75 } 76 return false 77 } 78 79 // Define all possible phase transitions. 80 // 81 // The keys are the "from" states and the values enumerate the 82 // possible "to" states. 83 var validTransitions = map[Phase][]Phase{ 84 QUIESCE: {READONLY, ABORT}, 85 READONLY: {PRECHECK, ABORT}, 86 PRECHECK: {IMPORT, ABORT}, 87 IMPORT: {VALIDATION, ABORT}, 88 VALIDATION: {SUCCESS, ABORT}, 89 SUCCESS: {LOGTRANSFER}, 90 LOGTRANSFER: {REAP}, 91 REAP: {DONE, REAPFAILED}, 92 ABORT: {ABORTDONE}, 93 } 94 95 var terminalPhases []Phase 96 97 func init() { 98 // Compute the terminal phases. 99 for p := 0; p <= len(phaseNames); p++ { 100 phase := Phase(p) 101 if _, exists := validTransitions[phase]; !exists { 102 terminalPhases = append(terminalPhases, phase) 103 } 104 } 105 } 106 107 // ParsePhase converts a string model migration phase name 108 // to its constant value. 109 func ParsePhase(target string) (Phase, bool) { 110 for p, name := range phaseNames { 111 if target == name { 112 return Phase(p), true 113 } 114 } 115 return UNKNOWN, false 116 }