@@ -5,22 +5,16 @@ import (
5
5
"fmt"
6
6
"net/http"
7
7
"os"
8
- "reflect"
9
8
"strings"
10
9
"time"
11
10
11
+ configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
12
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus"
12
13
"github.com/prometheus/client_golang/prometheus/promhttp"
13
14
log "github.com/sirupsen/logrus"
14
15
v1 "k8s.io/api/core/v1"
15
- k8serrors "k8s.io/apimachinery/pkg/api/errors"
16
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17
- "k8s.io/apimachinery/pkg/runtime/schema"
18
- "k8s.io/apimachinery/pkg/util/wait"
19
- "k8s.io/client-go/discovery"
20
16
"k8s.io/client-go/tools/clientcmd"
21
17
22
- configv1 "github.com/openshift/api/config/v1"
23
- configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
24
18
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client"
25
19
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
26
20
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm"
@@ -132,194 +126,8 @@ func main() {
132
126
<- ready
133
127
134
128
if * writeStatusName != "" {
135
- monitorClusterStatus ( sync , stopCh , opClient , configClient )
129
+ operatorstatus . MonitorClusterStatus ( * writeStatusName , sync , stopCh , opClient , configClient )
136
130
}
137
131
138
132
<- done
139
133
}
140
-
141
- func monitorClusterStatus (syncCh chan error , stopCh <- chan struct {}, opClient operatorclient.ClientInterface , configClient configv1client.ConfigV1Interface ) {
142
- var (
143
- syncs int
144
- successfulSyncs int
145
- hasClusterOperator bool
146
- )
147
- go wait .Until (func () {
148
- // slow poll until we see a cluster operator API, which could be never
149
- if ! hasClusterOperator {
150
- opStatusGV := schema.GroupVersion {
151
- Group : "config.openshift.io" ,
152
- Version : "v1" ,
153
- }
154
- err := discovery .ServerSupportsVersion (opClient .KubernetesInterface ().Discovery (), opStatusGV )
155
- if err != nil {
156
- log .Infof ("ClusterOperator api not present, skipping update (%v)" , err )
157
- time .Sleep (time .Minute )
158
- return
159
- }
160
- hasClusterOperator = true
161
- }
162
-
163
- // Sample the sync channel and see whether we're successfully retiring syncs as a
164
- // proxy for "working" (we can't know when we hit level, but we can at least verify
165
- // we are seeing some syncs succeeding). Once we observe at least one successful
166
- // sync we can begin reporting available and level.
167
- select {
168
- case err , ok := <- syncCh :
169
- if ! ok {
170
- // syncCh should only close if the Run() loop exits
171
- time .Sleep (5 * time .Second )
172
- log .Fatalf ("Status sync channel closed but process did not exit in time" )
173
- }
174
- syncs ++
175
- if err == nil {
176
- successfulSyncs ++
177
- }
178
- // grab any other sync events that have accumulated
179
- for len (syncCh ) > 0 {
180
- if err := <- syncCh ; err == nil {
181
- successfulSyncs ++
182
- }
183
- syncs ++
184
- }
185
- // if we haven't yet accumulated enough syncs, wait longer
186
- // TODO: replace these magic numbers with a better measure of syncs across all queueInformers
187
- if successfulSyncs < 5 || syncs < 10 {
188
- log .Printf ("Waiting to observe more successful syncs" )
189
- return
190
- }
191
- }
192
-
193
- // create the cluster operator in an initial state if it does not exist
194
- existing , err := configClient .ClusterOperators ().Get (* writeStatusName , metav1.GetOptions {})
195
- if k8serrors .IsNotFound (err ) {
196
- log .Info ("Existing operator status not found, creating" )
197
- created , createErr := configClient .ClusterOperators ().Create (& configv1.ClusterOperator {
198
- ObjectMeta : metav1.ObjectMeta {
199
- Name : * writeStatusName ,
200
- },
201
- Status : configv1.ClusterOperatorStatus {
202
- Conditions : []configv1.ClusterOperatorStatusCondition {
203
- configv1.ClusterOperatorStatusCondition {
204
- Type : configv1 .OperatorProgressing ,
205
- Status : configv1 .ConditionTrue ,
206
- Message : fmt .Sprintf ("Installing %s" , olmversion .OLMVersion ),
207
- LastTransitionTime : metav1 .Now (),
208
- },
209
- configv1.ClusterOperatorStatusCondition {
210
- Type : configv1 .OperatorFailing ,
211
- Status : configv1 .ConditionFalse ,
212
- LastTransitionTime : metav1 .Now (),
213
- },
214
- configv1.ClusterOperatorStatusCondition {
215
- Type : configv1 .OperatorAvailable ,
216
- Status : configv1 .ConditionFalse ,
217
- LastTransitionTime : metav1 .Now (),
218
- },
219
- },
220
- },
221
- })
222
- if createErr != nil {
223
- log .Errorf ("Failed to create cluster operator: %v\n " , createErr )
224
- return
225
- }
226
- existing = created
227
- err = nil
228
- }
229
- if err != nil {
230
- log .Errorf ("Unable to retrieve cluster operator: %v" , err )
231
- return
232
- }
233
-
234
- // update the status with the appropriate state
235
- previousStatus := existing .Status .DeepCopy ()
236
- switch {
237
- case successfulSyncs > 0 :
238
- setOperatorStatusCondition (& existing .Status .Conditions , configv1.ClusterOperatorStatusCondition {
239
- Type : configv1 .OperatorFailing ,
240
- Status : configv1 .ConditionFalse ,
241
- })
242
- setOperatorStatusCondition (& existing .Status .Conditions , configv1.ClusterOperatorStatusCondition {
243
- Type : configv1 .OperatorProgressing ,
244
- Status : configv1 .ConditionFalse ,
245
- Message : fmt .Sprintf ("Deployed %s" , olmversion .OLMVersion ),
246
- })
247
- setOperatorStatusCondition (& existing .Status .Conditions , configv1.ClusterOperatorStatusCondition {
248
- Type : configv1 .OperatorAvailable ,
249
- Status : configv1 .ConditionTrue ,
250
- })
251
- // we set the versions array when all the latest code is deployed and running - in this case,
252
- // the sync method is responsible for guaranteeing that happens before it returns nil
253
- if version := os .Getenv ("RELEASE_VERSION" ); len (version ) > 0 {
254
- existing .Status .Versions = []configv1.OperandVersion {
255
- {
256
- Name : "operator" ,
257
- Version : version ,
258
- },
259
- {
260
- Name : "operator-lifecycle-manager" ,
261
- Version : olmversion .OLMVersion ,
262
- },
263
- }
264
- } else {
265
- existing .Status .Versions = nil
266
- }
267
- default :
268
- setOperatorStatusCondition (& existing .Status .Conditions , configv1.ClusterOperatorStatusCondition {
269
- Type : configv1 .OperatorFailing ,
270
- Status : configv1 .ConditionTrue ,
271
- Message : "Waiting for updates to take effect" ,
272
- })
273
- setOperatorStatusCondition (& existing .Status .Conditions , configv1.ClusterOperatorStatusCondition {
274
- Type : configv1 .OperatorProgressing ,
275
- Status : configv1 .ConditionFalse ,
276
- Message : fmt .Sprintf ("Waiting to see update %s succeed" , olmversion .OLMVersion ),
277
- })
278
- // TODO: use % errors within a window to report available
279
- }
280
-
281
- // update the status
282
- if ! reflect .DeepEqual (previousStatus , & existing .Status ) {
283
- if _ , err := configClient .ClusterOperators ().UpdateStatus (existing ); err != nil {
284
- log .Errorf ("Unable to update cluster operator status: %v" , err )
285
- }
286
- }
287
-
288
- // if we've reported success, we can sleep longer, otherwise we want to keep watching for
289
- // successful
290
- if successfulSyncs > 0 {
291
- time .Sleep (5 * time .Minute )
292
- }
293
-
294
- }, 5 * time .Second , stopCh )
295
- }
296
-
297
- func setOperatorStatusCondition (conditions * []configv1.ClusterOperatorStatusCondition , newCondition configv1.ClusterOperatorStatusCondition ) {
298
- if conditions == nil {
299
- conditions = & []configv1.ClusterOperatorStatusCondition {}
300
- }
301
- existingCondition := findOperatorStatusCondition (* conditions , newCondition .Type )
302
- if existingCondition == nil {
303
- newCondition .LastTransitionTime = metav1 .NewTime (time .Now ())
304
- * conditions = append (* conditions , newCondition )
305
- return
306
- }
307
-
308
- if existingCondition .Status != newCondition .Status {
309
- existingCondition .Status = newCondition .Status
310
- existingCondition .LastTransitionTime = newCondition .LastTransitionTime
311
- }
312
-
313
- existingCondition .Reason = newCondition .Reason
314
- existingCondition .Message = newCondition .Message
315
- }
316
-
317
- func findOperatorStatusCondition (conditions []configv1.ClusterOperatorStatusCondition , conditionType configv1.ClusterStatusConditionType ) * configv1.ClusterOperatorStatusCondition {
318
- for i := range conditions {
319
- if conditions [i ].Type == conditionType {
320
- return & conditions [i ]
321
- }
322
- }
323
-
324
- return nil
325
- }
0 commit comments