Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overlay node image before bootstrapping if necessary #899

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/installer/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,22 @@ func (i *installer) startBootstrap() error {
return err
}

// If we're in a pure RHEL/CentOS environment, we need to overlay the node image
// first to have access to e.g. oc, kubelet, cri-o, etc...
// https://github.com/openshift/enhancements/pull/1637
if !i.ops.FileExists("/usr/bin/oc") {
err = i.ops.SystemctlAction("start", "node-image-overlay.service")
if err != nil {
return err
}

i.waitForNodeImageOverlay(context.Background())
jlebon marked this conversation as resolved.
Show resolved Hide resolved

if !i.ops.FileExists("/usr/bin/oc") {
return stderrors.New("/usr/bin/oc still doesn't exist after node image overlay")
}
}

servicesToStart := []string{"bootkube.service", "approve-csr.service", "progress.service"}
for _, service := range servicesToStart {
err = i.ops.SystemctlAction("start", service)
Expand Down Expand Up @@ -658,7 +674,7 @@ func (i *installer) waitForBootkube(ctx context.Context) {
return
case <-time.After(generalWaitInterval):
// check if bootkube is done every 5 seconds
if _, err := i.ops.ExecPrivilegeCommand(nil, "stat", "/opt/openshift/.bootkube.done"); err == nil {
if i.ops.FileExists("/opt/openshift/.bootkube.done") {
// in case bootkube is done log the status and return
i.log.Info("bootkube service completed")
out, _ := i.ops.ExecPrivilegeCommand(nil, "systemctl", "status", "bootkube.service")
Expand All @@ -669,6 +685,25 @@ func (i *installer) waitForBootkube(ctx context.Context) {
}
}

func (i *installer) waitForNodeImageOverlay(ctx context.Context) {
i.log.Infof("Waiting for node image overlay to complete")

for {
select {
case <-ctx.Done():
i.log.Info("Context cancelled, terminating wait for node image overlay\n")
return
case <-time.After(generalWaitInterval):
out, err := i.ops.ExecPrivilegeCommand(nil, "systemctl", "is-active", "node-image-overlay.service")
if err == nil {
i.log.Info("node image overlay service completed")
return
}
i.log.Debugf("node image overlay service not yet active: %s", out)
}
}
}

func (i *installer) waitForController(kc k8s_client.K8SClient) error {
i.log.Infof("Waiting for controller to be ready")
i.UpdateHostInstallProgress(models.HostStageWaitingForController, "waiting for controller pod ready event")
Expand Down
4 changes: 2 additions & 2 deletions src/main/drymock/dry_mode_k8s_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
func mockNodeList(mockk8sclient *k8s_client.MockK8SClient, clusterHosts config.DryClusterHosts, o ops.Ops) v1.NodeList {
nodeListPopulated := v1.NodeList{}
for _, clusterHost := range clusterHosts {
if !o.DryRebootHappened(clusterHost.RebootMarkerPath) {
if !o.FileExists(clusterHost.RebootMarkerPath) {
// Host didn't even reboot yet, don't pretend it's a node
continue
}
Expand Down Expand Up @@ -103,7 +103,7 @@ func PrepareControllerDryMock(mockk8sclient *k8s_client.MockK8SClient, logger *l
mcsLogs := ""
for _, clusterHost := range clusterHosts {
// Add IP access log for each IP, this is how the controller determines which node has downloaded the ignition
if !o.DryRebootHappened(clusterHost.RebootMarkerPath) {
if !o.FileExists(clusterHost.RebootMarkerPath) {
// Host didn't even reboot yet, don't pretend it fetched the ignition
continue
}
Expand Down
12 changes: 6 additions & 6 deletions src/ops/mock_ops.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions src/ops/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type Ops interface {
EvaluateDiskSymlink(string) string
FormatDisk(string) error
CreateManifests(string, []byte) error
DryRebootHappened(markerPath string) bool
FileExists(markerPath string) bool
ExecPrivilegeCommand(liveLogger io.Writer, command string, args ...string) (string, error)
ReadFile(filePath string) ([]byte, error)
GetEncapsulatedMC(ignitionPath string) (*mcfgv1.MachineConfig, error)
Expand Down Expand Up @@ -434,7 +434,7 @@ func (o *ops) GetMCSLogs() (string, error) {
mcsLogs := ""
for _, clusterHost := range o.installerConfig.ParsedClusterHosts {
// Add IP access log for each IP, this is how the installer determines which node has downloaded the ignition
if !o.DryRebootHappened(clusterHost.RebootMarkerPath) {
if !o.FileExists(clusterHost.RebootMarkerPath) {
// Host didn't even reboot yet, don't pretend it fetched the ignition
continue
}
Expand Down Expand Up @@ -648,11 +648,12 @@ func (o *ops) CreateManifests(kubeconfig string, content []byte) error {
return nil
}

// DryRebootHappened checks if a reboot happened according to a particular reboot marker path
// The dry run installer creates this file on "Reboot" (instead of actually rebooting)
// We use this function to check whether the given node in the cluster have already rebooted
func (o *ops) DryRebootHappened(markerPath string) bool {
_, err := o.ExecPrivilegeCommand(nil, "stat", markerPath)
// FileExists checks if a file exists. It's notably used to check if a
// dry reboot happened. The dry run installer creates the marker file on
// "Reboot" (instead of actually rebooting) We use this function to check
// whether the given node in the cluster have already rebooted
func (o *ops) FileExists(path string) bool {
_, err := o.ExecPrivilegeCommand(nil, "stat", path)

return err == nil
}
Expand Down