Skip to content

Commit c7fb265

Browse files
khannakshat7khannakshat7Dharmjit Singh
authored
Host agent changes (#564)
* host agent changes added for decoupling the installer Co-authored-by: khannakshat7 <[email protected]> Co-authored-by: Dharmjit Singh <[email protected]>
1 parent f6dc397 commit c7fb265

File tree

10 files changed

+439
-84
lines changed

10 files changed

+439
-84
lines changed

agent/cloudinit/cloudinit.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package cloudinit
55

66
import (
7+
"context"
78
"encoding/base64"
89
"fmt"
910
"path/filepath"
@@ -71,7 +72,7 @@ func (se ScriptExecutor) Execute(bootstrapScript string) error {
7172
}
7273

7374
for _, cmd := range cloudInitData.CommandsToExecute {
74-
err := se.RunCmdExecutor.RunCmd(cmd)
75+
err := se.RunCmdExecutor.RunCmd(context.TODO(), cmd)
7576
if err != nil {
7677
return errors.Wrap(err, fmt.Sprintf("Error running the command %s", cmd))
7778
}

agent/cloudinit/cloudinit_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ runCmd:
135135
Expect(err).NotTo(HaveOccurred())
136136

137137
Expect(fakeCmdExecutor.RunCmdCallCount()).To(Equal(1))
138-
cmd := fakeCmdExecutor.RunCmdArgsForCall(0)
138+
_, cmd := fakeCmdExecutor.RunCmdArgsForCall(0)
139139
Expect(cmd).To(Equal("echo 'some run command'"))
140140
})
141141

agent/cloudinit/cloudinitfakes/fake_icmd_runner.go

Lines changed: 13 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/cloudinit/cmd_runner.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
package cloudinit
55

66
import (
7+
"context"
78
"os"
89
"os/exec"
910
)
1011

1112
//counterfeiter:generate . ICmdRunner
1213
type ICmdRunner interface {
13-
RunCmd(string) error
14+
RunCmd(context.Context, string) error
1415
}
1516

1617
// CmdRunner default implementer of ICmdRunner
@@ -19,8 +20,12 @@ type CmdRunner struct {
1920
}
2021

2122
// RunCmd executes the command string
22-
func (r CmdRunner) RunCmd(cmd string) error {
23-
command := exec.Command("/bin/sh", "-c", cmd)
23+
func (r CmdRunner) RunCmd(ctx context.Context, cmd string) error {
24+
command := exec.CommandContext(ctx, "/bin/bash", "-c", cmd)
2425
command.Stderr = os.Stderr
25-
return command.Run()
26+
command.Stdout = os.Stdout
27+
if err := command.Run(); err != nil {
28+
return err
29+
}
30+
return nil
2631
}

agent/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ func main() {
168168
os.Exit(1)
169169
}
170170
}
171-
// Handle kubeconfig flag
172-
// first look in the byoh path for the kubeconfig
171+
// Handle kubeconfig flag first look in the byoh path for the kubeconfig
173172
config, err := registration.LoadRESTClientConfig(registration.GetBYOHConfigPath())
174173
if err != nil {
175174
logger.Error(err, "client config load failed")
@@ -231,6 +230,7 @@ func main() {
231230
K8sInstaller: k8sInstaller,
232231
SkipK8sInstallation: skipInstallation,
233232
UseInstallerController: useInstallerController,
233+
DownloadPath: downloadpath,
234234
}
235235
if err = hostReconciler.SetupWithManager(context.TODO(), mgr); err != nil {
236236
logger.Error(err, "unable to create controller")

agent/reconciler/host_reconciler.go

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type HostReconciler struct {
4545
K8sInstaller IK8sInstaller
4646
SkipK8sInstallation bool
4747
UseInstallerController bool
48+
DownloadPath string
4849
}
4950

5051
const (
@@ -94,6 +95,8 @@ func (r *HostReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctr
9495

9596
func (r *HostReconciler) reconcileNormal(ctx context.Context, byoHost *infrastructurev1beta1.ByoHost) (ctrl.Result, error) {
9697
logger := ctrl.LoggerFrom(ctx)
98+
logger = logger.WithValues("ByoHost", byoHost.Name)
99+
logger.Info("reconcile normal")
97100
if byoHost.Status.MachineRef == nil {
98101
logger.Info("Machine ref not yet set")
99102
conditions.MarkFalse(byoHost, infrastructurev1beta1.K8sNodeBootstrapSucceeded, infrastructurev1beta1.WaitingForMachineRefReason, clusterv1.ConditionSeverityInfo, "")
@@ -117,10 +120,20 @@ func (r *HostReconciler) reconcileNormal(ctx context.Context, byoHost *infrastru
117120
if r.SkipK8sInstallation {
118121
logger.Info("Skipping installation of k8s components")
119122
} else if r.UseInstallerController {
120-
if byoHost.Spec.InstallationSecret == nil {
121-
logger.Info("K8sInstallationSecret not ready")
122-
conditions.MarkFalse(byoHost, infrastructurev1beta1.K8sNodeBootstrapSucceeded, infrastructurev1beta1.K8sInstallationSecretUnavailableReason, clusterv1.ConditionSeverityInfo, "")
123-
return ctrl.Result{}, nil
123+
if !conditions.IsTrue(byoHost, infrastructurev1beta1.K8sComponentsInstallationSucceeded) {
124+
if byoHost.Spec.InstallationSecret == nil {
125+
logger.Info("InstallationSecret not ready")
126+
conditions.MarkFalse(byoHost, infrastructurev1beta1.K8sComponentsInstallationSucceeded, infrastructurev1beta1.K8sInstallationSecretUnavailableReason, clusterv1.ConditionSeverityInfo, "")
127+
return ctrl.Result{}, nil
128+
}
129+
err = r.executeInstallerController(ctx, byoHost)
130+
if err != nil {
131+
return ctrl.Result{}, err
132+
}
133+
r.Recorder.Event(byoHost, corev1.EventTypeNormal, "InstallScriptExecutionSucceeded", "install script executed")
134+
conditions.MarkTrue(byoHost, infrastructurev1beta1.K8sComponentsInstallationSucceeded)
135+
} else {
136+
logger.Info("install script already executed")
124137
}
125138
} else {
126139
err = r.installK8sComponents(ctx, byoHost)
@@ -156,6 +169,34 @@ func (r *HostReconciler) reconcileNormal(ctx context.Context, byoHost *infrastru
156169
return ctrl.Result{}, nil
157170
}
158171

172+
func (r *HostReconciler) executeInstallerController(ctx context.Context, byoHost *infrastructurev1beta1.ByoHost) error {
173+
logger := ctrl.LoggerFrom(ctx)
174+
secret := &corev1.Secret{}
175+
err := r.Client.Get(ctx, types.NamespacedName{Name: byoHost.Spec.InstallationSecret.Name, Namespace: byoHost.Spec.InstallationSecret.Namespace}, secret)
176+
if err != nil {
177+
logger.Error(err, "error getting install and uninstall script")
178+
r.Recorder.Eventf(byoHost, corev1.EventTypeWarning, "ReadInstallationSecretFailed", "install and uninstall script %s not found", byoHost.Spec.InstallationSecret.Name)
179+
return err
180+
}
181+
installScript := string(secret.Data["install"])
182+
uninstallScript := string(secret.Data["uninstall"])
183+
184+
byoHost.Spec.UninstallationScript = &uninstallScript
185+
installScript, err = r.parseScript(ctx, installScript)
186+
if err != nil {
187+
return err
188+
}
189+
logger.Info("executing install script")
190+
err = r.CmdRunner.RunCmd(ctx, installScript)
191+
if err != nil {
192+
logger.Error(err, "error executing installation script")
193+
r.Recorder.Event(byoHost, corev1.EventTypeWarning, "InstallScriptExecutionFailed", "install script execution failed")
194+
conditions.MarkFalse(byoHost, infrastructurev1beta1.K8sComponentsInstallationSucceeded, infrastructurev1beta1.K8sComponentsInstallationFailedReason, clusterv1.ConditionSeverityInfo, "")
195+
return err
196+
}
197+
return nil
198+
}
199+
159200
func (r *HostReconciler) reconcileDelete(ctx context.Context, byoHost *infrastructurev1beta1.ByoHost) (ctrl.Result, error) {
160201
return ctrl.Result{}, nil
161202
}
@@ -171,6 +212,18 @@ func (r *HostReconciler) getBootstrapScript(ctx context.Context, dataSecretName,
171212
return bootstrapSecret, nil
172213
}
173214

215+
func (r *HostReconciler) parseScript(ctx context.Context, script string) (string, error) {
216+
data, err := cloudinit.TemplateParser{
217+
Template: map[string]string{
218+
"BundleDownloadPath": r.DownloadPath,
219+
},
220+
}.ParseTemplate(script)
221+
if err != nil {
222+
return "", fmt.Errorf("unable to apply install parsed template to the data object")
223+
}
224+
return data, nil
225+
}
226+
174227
// SetupWithManager sets up the controller with the manager
175228
func (r *HostReconciler) SetupWithManager(ctx context.Context, mgr manager.Manager) error {
176229
return ctrl.NewControllerManagedBy(mgr).
@@ -215,6 +268,23 @@ func (r *HostReconciler) hostCleanUp(ctx context.Context, byoHost *infrastructur
215268
}
216269
if r.SkipK8sInstallation {
217270
logger.Info("Skipping uninstallation of k8s components")
271+
} else if r.UseInstallerController {
272+
if byoHost.Spec.UninstallationScript == nil {
273+
return fmt.Errorf("UninstallationScript not found in Byohost %s", byoHost.Name)
274+
}
275+
logger.Info("Executing Uninstall script")
276+
uninstallScript := *byoHost.Spec.UninstallationScript
277+
uninstallScript, err = r.parseScript(ctx, uninstallScript)
278+
if err != nil {
279+
logger.Error(err, "error parsing Uninstallation script")
280+
return err
281+
}
282+
err = r.CmdRunner.RunCmd(ctx, uninstallScript)
283+
if err != nil {
284+
logger.Error(err, "error execting Uninstallation script")
285+
r.Recorder.Event(byoHost, corev1.EventTypeWarning, "UninstallScriptExecutionFailed", "uninstall script execution failed")
286+
return err
287+
}
218288
} else {
219289
err = r.uninstallk8sComponents(ctx, byoHost)
220290
if err != nil {
@@ -236,6 +306,8 @@ func (r *HostReconciler) hostCleanUp(ctx context.Context, byoHost *infrastructur
236306
return err
237307
}
238308

309+
byoHost.Spec.InstallationSecret = nil
310+
byoHost.Spec.UninstallationScript = nil
239311
r.removeAnnotations(ctx, byoHost)
240312
conditions.MarkFalse(byoHost, infrastructurev1beta1.K8sNodeBootstrapSucceeded, infrastructurev1beta1.K8sNodeAbsentReason, clusterv1.ConditionSeverityInfo, "")
241313
return nil
@@ -245,7 +317,7 @@ func (r *HostReconciler) resetNode(ctx context.Context, byoHost *infrastructurev
245317
logger := ctrl.LoggerFrom(ctx)
246318
logger.Info("Running kubeadm reset")
247319

248-
err := r.CmdRunner.RunCmd(KubeadmResetCommand)
320+
err := r.CmdRunner.RunCmd(ctx, KubeadmResetCommand)
249321
if err != nil {
250322
r.Recorder.Event(byoHost, corev1.EventTypeWarning, "ResetK8sNodeFailed", "k8s Node Reset failed")
251323
return errors.Wrapf(err, "failed to exec kubeadm reset")

0 commit comments

Comments
 (0)