github.com/openshift/installer@v1.4.17/pkg/utils/baremetal/bootstrap.go (about)

     1  package baremetal
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	baremetalhost "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
    11  	"github.com/sirupsen/logrus"
    12  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    13  	"k8s.io/apimachinery/pkg/runtime"
    14  	"k8s.io/apimachinery/pkg/watch"
    15  	"k8s.io/client-go/dynamic"
    16  	"k8s.io/client-go/rest"
    17  	clientwatch "k8s.io/client-go/tools/watch"
    18  
    19  	"github.com/openshift/installer/pkg/infrastructure/baremetal"
    20  )
    21  
    22  // WaitForBaremetalBootstrapControlPlane will watch baremetalhost resources on the bootstrap
    23  // and wait for the control plane to finish provisioning.
    24  func WaitForBaremetalBootstrapControlPlane(ctx context.Context, config *rest.Config, dir string) error {
    25  	client, err := dynamic.NewForConfig(config)
    26  	if err != nil {
    27  		return fmt.Errorf("creating a baremetal client: %w", err)
    28  	}
    29  
    30  	r := client.Resource(baremetalhost.GroupVersion.WithResource("baremetalhosts")).Namespace("openshift-machine-api")
    31  	blw := BmhCacheListerWatcher{
    32  		Resource:   r,
    33  		RetryWatch: true,
    34  	}
    35  
    36  	logrus.Infof("  Waiting for baremetal control plane to provision...")
    37  
    38  	masters := map[string]baremetalhost.BareMetalHost{}
    39  
    40  	_, withSyncErr := clientwatch.UntilWithSync(
    41  		ctx,
    42  		blw,
    43  		&unstructured.Unstructured{},
    44  		nil,
    45  		func(event watch.Event) (bool, error) {
    46  			switch event.Type {
    47  			case watch.Added, watch.Modified:
    48  			default:
    49  				return false, nil
    50  			}
    51  
    52  			bmh := &baremetalhost.BareMetalHost{}
    53  
    54  			unstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(event.Object)
    55  			if err != nil {
    56  				return false, err
    57  			}
    58  
    59  			if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstr, bmh); err != nil {
    60  				logrus.Error("failed to convert to bmh", err)
    61  				return false, err
    62  			}
    63  
    64  			role, found := bmh.Labels["installer.openshift.io/role"]
    65  
    66  			if found && role == "control-plane" {
    67  				prev, found := masters[bmh.Name]
    68  
    69  				if !found || bmh.Status.Provisioning.State != prev.Status.Provisioning.State {
    70  					if bmh.Status.Provisioning.State == baremetalhost.StateNone {
    71  						// StateNone is an empty string
    72  						logrus.Infof("  baremetalhost: %s: uninitialized", bmh.Name)
    73  					} else {
    74  						logrus.Infof("  baremetalhost: %s: %s", bmh.Name, bmh.Status.Provisioning.State)
    75  					}
    76  
    77  					if bmh.Status.OperationalStatus == baremetalhost.OperationalStatusError {
    78  						logrus.Warnf("  baremetalhost: %s: %s: %s", bmh.Name, bmh.Status.ErrorType, bmh.Status.ErrorMessage)
    79  					}
    80  				}
    81  
    82  				masters[bmh.Name] = *bmh
    83  			}
    84  
    85  			if len(masters) == 0 {
    86  				return false, nil
    87  			}
    88  
    89  			for _, master := range masters {
    90  				if master.Status.Provisioning.State != baremetalhost.StateProvisioned {
    91  					return false, nil
    92  				}
    93  			}
    94  
    95  			return true, nil
    96  		},
    97  	)
    98  
    99  	mastersJSON, err := json.Marshal(masters)
   100  	if err != nil {
   101  		return fmt.Errorf("failed to marshal masters: %w", err)
   102  	}
   103  
   104  	err = os.WriteFile(filepath.Join(dir, baremetal.MastersFileName), mastersJSON, 0600)
   105  	if err != nil {
   106  		return fmt.Errorf("failed to persist masters file to disk: %w", err)
   107  	}
   108  
   109  	return withSyncErr
   110  }