@@ -3,10 +3,14 @@ package hyperconverged
3
3
import (
4
4
"cmp"
5
5
"context"
6
+ "crypto/tls"
6
7
"encoding/json"
7
8
"fmt"
9
+ "io"
10
+ "net/http"
8
11
"os"
9
12
"reflect"
13
+ "regexp"
10
14
"slices"
11
15
12
16
"github.com/blang/semver/v4"
@@ -336,6 +340,8 @@ func (r *ReconcileHyperConverged) Reconcile(ctx context.Context, request reconci
336
340
return result , err
337
341
}
338
342
343
+ r .EvaluateUpgradeEligibility (hcoRequest )
344
+
339
345
if err = r .setOperatorUpgradeableStatus (hcoRequest ); err != nil {
340
346
return reconcile.Result {}, err
341
347
}
@@ -1330,6 +1336,69 @@ func (r *ReconcileHyperConverged) deleteObj(req *common.HcoRequest, obj client.O
1330
1336
return removed , nil
1331
1337
}
1332
1338
1339
+ func (r * ReconcileHyperConverged ) EvaluateUpgradeEligibility (req * common.HcoRequest ) error {
1340
+ podList := & corev1.PodList {}
1341
+ listOpts := []client.ListOption {
1342
+ client .InNamespace (req .Namespace ),
1343
+ client.MatchingLabels {"kubevirt.io" : "virt-controller" },
1344
+ }
1345
+
1346
+ if err := r .client .List (req .Ctx , podList , listOpts ... ); err != nil {
1347
+ req .Logger .Info ("Failed to list virt-controller pods" , "namespace" , req .Namespace , "error" , err )
1348
+ return fmt .Errorf ("failed to list virt-controller pods: %w" , err )
1349
+ }
1350
+
1351
+ if len (podList .Items ) == 0 {
1352
+ req .Logger .Info ("No virt-controller pods found" , "namespace" , req .Namespace )
1353
+ return nil
1354
+ }
1355
+
1356
+ httpClient := & http.Client {
1357
+ Transport : & http.Transport {
1358
+ TLSClientConfig : & tls.Config {InsecureSkipVerify : true },
1359
+ },
1360
+ }
1361
+
1362
+ for _ , pod := range podList .Items {
1363
+ if pod .Status .PodIP == "" {
1364
+ continue
1365
+ }
1366
+ metricsURL := fmt .Sprintf ("https://%s:%d/metrics" , pod .Status .PodIP , 8443 )
1367
+
1368
+ resp , err := httpClient .Get (metricsURL )
1369
+ if err != nil {
1370
+ req .Logger .Info ("Failed to query metrics from pod" , "pod" , pod .Name , "error" , err )
1371
+ continue
1372
+ }
1373
+
1374
+ if resp .StatusCode != http .StatusOK {
1375
+ req .Logger .Info ("Metrics endpoint returned non-200 status" , "pod" , pod .Name , "status" , resp .StatusCode )
1376
+ resp .Body .Close ()
1377
+ continue
1378
+ }
1379
+
1380
+ body , err := io .ReadAll (resp .Body )
1381
+ resp .Body .Close ()
1382
+ if err != nil {
1383
+ req .Logger .Info ("Failed to read metrics response from pod" , "pod" , pod .Name , "error" , err )
1384
+ continue
1385
+ }
1386
+
1387
+ virtMetrics := string (body )
1388
+
1389
+ req .Logger .Info ("Metrics data from pod" , "pod" , pod .Name , "metrics" , virtMetrics )
1390
+
1391
+ rhel8Regex := regexp .MustCompile (`.*rhel8.*` )
1392
+ if rhel8Regex .MatchString (virtMetrics ) {
1393
+ req .Logger .Info ("Detected outdated machine type in metrics" , "pod" , pod .Name , "matched" , rhel8Regex .FindString (virtMetrics ))
1394
+ req .Upgradeable = false
1395
+ return nil
1396
+ }
1397
+ }
1398
+
1399
+ return nil
1400
+ }
1401
+
1333
1402
func removeOldQuickStartGuides (req * common.HcoRequest , cl client.Client , requiredQSList []string ) {
1334
1403
existingQSList := & consolev1.ConsoleQuickStartList {}
1335
1404
req .Logger .Info ("reading quickstart guides" )
0 commit comments