Skip to content

Commit

Permalink
baremetal: monitor bootstrap process
Browse files Browse the repository at this point in the history
  • Loading branch information
honza committed Mar 27, 2024
1 parent 9c98f76 commit 25a0910
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
96 changes: 96 additions & 0 deletions cmd/openshift-install/create.go
Expand Up @@ -16,6 +16,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -54,6 +55,8 @@ import (
"github.com/openshift/installer/pkg/types/vsphere"
cov1helpers "github.com/openshift/library-go/pkg/config/clusteroperator/v1helpers"
"github.com/openshift/library-go/pkg/route/routeapihelpers"

baremetalhost "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
)

type target struct {
Expand Down Expand Up @@ -435,6 +438,17 @@ func waitForBootstrapComplete(ctx context.Context, config *rest.Config) *cluster
return newAPIError(err)
}

// baremetal: monitor control plane bootstrapping progress
if assetStore, err := assetstore.NewStore(command.RootOpts.Dir); err == nil {
if installConfig, err := assetStore.Load(&installconfig.InstallConfig{}); err == nil && installConfig != nil {
if installConfig.(*installconfig.InstallConfig).Config.Platform.Name() == baremetal.Name {
if err := waitForBaremetalBootstrapControlPlane(ctx, config); err != nil {
return err
}
}
}
}

if err := waitForBootstrapConfigMap(ctx, client); err != nil {
return err
}
Expand All @@ -446,6 +460,88 @@ func waitForBootstrapComplete(ctx context.Context, config *rest.Config) *cluster
return nil
}

func waitForBaremetalBootstrapControlPlane(ctx context.Context, config *rest.Config) *clusterCreateError {
timeout := 30 * time.Minute

client, err := dynamic.NewForConfig(config)
if err != nil {
return newClientError(errors.Wrap(err, "creating a baremetal client"))
}

r := client.Resource(baremetalhost.GroupVersion.WithResource("baremetalhosts")).Namespace("openshift-machine-api")
blw := baremetal.BmhCacheListerWatcher{
Resource: r,
}

untilTime := time.Now().Add(timeout)
timezone, _ := untilTime.Zone()
logrus.Infof("Waiting up to %v (until %v %s) for baremetal control plane to provision...",
timeout, untilTime.Format(time.Kitchen), timezone)

waitCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()

masters := map[string]baremetalhost.BareMetalHost{}

_, err = clientwatch.UntilWithSync(
waitCtx,
blw,
&unstructured.Unstructured{},
nil,
func(event watch.Event) (bool, error) {
switch event.Type {
case watch.Added, watch.Modified:
default:
return false, nil
}

bmh := &baremetalhost.BareMetalHost{}

unstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(event.Object)
if err != nil {
return false, err
}

if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstr, bmh); err != nil {
logrus.Error("failed to convert to bmh", err)
return false, err
}

role, found := bmh.Labels["installer.openshift.io/role"]

if found && role == "control-plane" {
if bmh.Status.Provisioning.State == baremetalhost.StateNone {
// StateNone is an empty string
logrus.Infof(" baremetalhost: %s: unknown", bmh.Name)
} else {
logrus.Infof(" baremetalhost: %s: %s", bmh.Name, bmh.Status.Provisioning.State)
}

if bmh.Status.OperationalStatus == baremetalhost.OperationalStatusError {
logrus.Infof(" baremetalhost: %s: error: %s", bmh.Name, bmh.Status.ErrorMessage)
}
masters[bmh.Name] = *bmh
}

if len(masters) == 0 {
return false, nil
}

for _, master := range masters {
if master.Status.Provisioning.State != baremetalhost.StateProvisioned {
return false, nil
}
}

return true, nil
},
)
if err != nil {
return newBootstrapError(err)
}
return nil
}

// waitForBootstrapConfigMap watches the configmaps in the kube-system namespace
// and waits for the bootstrap configmap to report that bootstrapping has
// completed.
Expand Down
26 changes: 26 additions & 0 deletions pkg/types/baremetal/cache.go
@@ -0,0 +1,26 @@
package baremetal

import (
"context"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
)

// BmhCacheListerWatcher is an object that wraps the listing and wrapping
// functionality for baremetal host resources.
type BmhCacheListerWatcher struct {
Resource dynamic.ResourceInterface
}

// List returns a list of baremetal hosts as dynamic objects.
func (bc BmhCacheListerWatcher) List(options metav1.ListOptions) (runtime.Object, error) {
return bc.Resource.List(context.TODO(), options)
}

// Watch starts a watch over baremetal hosts.
func (bc BmhCacheListerWatcher) Watch(options metav1.ListOptions) (watch.Interface, error) {
return bc.Resource.Watch(context.TODO(), options)
}

0 comments on commit 25a0910

Please sign in to comment.