state.go RawHistoryFolder
1package installation
2
3// State represents the current phase of the installation
4type State int
5
6const (
7 // StateNotStarted is the initial state before installation begins
8 StateNotStarted State = iota
9
10 // StatePreflightChecks represents preflight verification phase
11 StatePreflightChecks
12
13 // StateDiskPartitioning represents disk partitioning phase
14 StateDiskPartitioning
15
16 // StateBaseInstallation represents base system installation phase
17 StateBaseInstallation
18
19 // StateSystemConfiguration represents system configuration phase (hostname, locale, etc.)
20 StateSystemConfiguration
21
22 // StateBootloaderSetup represents bootloader installation phase
23 StateBootloaderSetup
24
25 // StateRepositorySetup represents repository configuration phase
26 StateRepositorySetup
27
28 // StatePostInstallation represents post-installation tasks
29 StatePostInstallation
30
31 // StateCompleted represents successful installation completion
32 StateCompleted
33
34 // StateFailed represents installation failure
35 StateFailed
36)
37
38// String returns human-readable state name
39func (s State) String() string {
40 switch s {
41 case StateNotStarted:
42 return "NotStarted"
43 case StatePreflightChecks:
44 return "PreflightChecks"
45 case StateDiskPartitioning:
46 return "DiskPartitioning"
47 case StateBaseInstallation:
48 return "BaseInstallation"
49 case StateSystemConfiguration:
50 return "SystemConfiguration"
51 case StateBootloaderSetup:
52 return "BootloaderSetup"
53 case StateRepositorySetup:
54 return "RepositorySetup"
55 case StatePostInstallation:
56 return "PostInstallation"
57 case StateCompleted:
58 return "Completed"
59 case StateFailed:
60 return "Failed"
61 default:
62 return "Unknown"
63 }
64}
65
66// IsTerminal returns true if the state is a terminal state (cannot transition further)
67func (s State) IsTerminal() bool {
68 return s == StateCompleted || s == StateFailed
69}
70
71// IsValid returns true if the state is a valid state
72func (s State) IsValid() bool {
73 return s >= StateNotStarted && s <= StateFailed
74}
75
76// CanTransitionTo returns true if a transition from the current state to the target state is allowed
77// This enforces the business rule that states must progress in strict order
78func (s State) CanTransitionTo(target State) bool {
79 // Cannot transition FROM a terminal state
80 if s.IsTerminal() {
81 return false
82 }
83
84 // Can always transition to Failed from any non-terminal state
85 if target == StateFailed {
86 return true
87 }
88
89 // Must be valid target
90 if !target.IsValid() {
91 return false
92 }
93
94 // Define valid transitions (strict progression)
95 validTransitions := map[State][]State{
96 StateNotStarted: {StatePreflightChecks},
97 StatePreflightChecks: {StateDiskPartitioning},
98 StateDiskPartitioning: {StateBaseInstallation},
99 StateBaseInstallation: {StateSystemConfiguration},
100 StateSystemConfiguration: {StateBootloaderSetup},
101 StateBootloaderSetup: {StateRepositorySetup},
102 StateRepositorySetup: {StatePostInstallation},
103 StatePostInstallation: {StateCompleted},
104 StateCompleted: {},
105 StateFailed: {},
106 }
107
108 allowed, exists := validTransitions[s]
109 if !exists {
110 return false
111 }
112
113 for _, allowedState := range allowed {
114 if allowedState == target {
115 return true
116 }
117 }
118
119 return false
120}
121
122// TransitionTo performs a state transition with validation
123func (s *State) TransitionTo(target State) error {
124 if !s.CanTransitionTo(target) {
125 return ErrInvalidStateTransition
126 }
127 *s = target
128 return nil
129}
130
131// PhaseSequence returns the sequence of installation phases in order
132func PhaseSequence() []State {
133 return []State{
134 StatePreflightChecks,
135 StateDiskPartitioning,
136 StateBaseInstallation,
137 StateSystemConfiguration,
138 StateBootloaderSetup,
139 StateRepositorySetup,
140 StatePostInstallation,
141 StateCompleted,
142 }
143}
144
145// PhaseIndex returns the index of a phase in the sequence, or -1 if not found
146func PhaseIndex(state State) int {
147 sequence := PhaseSequence()
148 for i, s := range sequence {
149 if s == state {
150 return i
151 }
152 }
153 return -1
154}
155
156// ProgressPercentage returns estimated progress as percentage (0-100) based on current state
157func (s State) ProgressPercentage() int {
158 switch s {
159 case StateNotStarted:
160 return 0
161 case StatePreflightChecks:
162 return 10
163 case StateDiskPartitioning:
164 return 25
165 case StateBaseInstallation:
166 return 40
167 case StateSystemConfiguration:
168 return 60
169 case StateBootloaderSetup:
170 return 75
171 case StateRepositorySetup:
172 return 85
173 case StatePostInstallation:
174 return 95
175 case StateCompleted:
176 return 100
177 case StateFailed:
178 return 0 // Reset to 0 on failure
179 default:
180 return 0
181 }
182}