-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
✨ Add bootCommands to cloud-init file generation #11271
base: main
Are you sure you want to change the base?
✨ Add bootCommands to cloud-init file generation #11271
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Welcome @davidumea! |
Hi @davidumea. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
Are there version constraints around What happens if we render it but the cloud-init version in the machine does not support it? Does it make cloud-init fail as a whole or is it just ignored? Edit: looks like it is already there for a long time (from the start?) at |
Exactly I don't think that should be an issue as
During my testing, if the bootcmd module fails e.g. due to invalid commands, cloud-init still continues with the following modules. I haven't been able to test running this with a cloud-init version that doesn't support bootcmd. |
@chrischdi Is there anything I can do to get this reviewed? |
/ok-to-test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bootcmd module has been in cloud-init for as long as I can remember (which is back to 2010), so don't see an issue there.
I would like the documentation to be more explicit though, particularly about how this will have no effect on Ignition. Have suggested some changes.
// BootCommands specifies extra commands to run very early in the boot process via the cloud-init bootcmd | ||
// module. This is typically run in the cloud-init.service systemd unit. This has no effect in Ignition. | ||
// +optional | ||
BootCommands []BootCommand `json:"bootCommands,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't it be added only to v1beta1 which is the actively maintained API version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remove this and run make verify
, it removes bootCommands
from the CRDs.
Might be an issue in the verify logic, what do you think?
diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml
index 79c3b19e0..4e1852f77 100644
--- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml
+++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml
@@ -47,17 +47,6 @@ spec:
KubeadmConfigSpec defines the desired state of KubeadmConfig.
Either ClusterConfiguration and InitConfiguration should be defined or the JoinConfiguration should be defined.
properties:
- bootCommands:
- description: |-
- BootCommands specifies extra commands to run very early in the boot process via the cloud-init bootcmd
- module. This is typically run in the cloud-init.service systemd unit. This has no effect in Ignition.
- items:
- description: BootCommand defines input for each bootcmd command
- in cloud-init.
- items:
- type: string
- type: array
- type: array
clusterConfiguration:
description: ClusterConfiguration along with InitConfiguration are
the configurations necessary for the init command
etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New fields should not be added to older API versions.
Conversions should be implemented instead.
See eg
cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3/conversion.go
Lines 47 to 56 in 3db18fb
dst.Files = restored.Files | |
dst.Users = restored.Users | |
if restored.Users != nil { | |
for i := range restored.Users { | |
if restored.Users[i].PasswdFrom != nil { | |
dst.Users[i].PasswdFrom = restored.Users[i].PasswdFrom | |
} | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted my changes to the v1alpha3 and v1alpha4 versions and added conversions instead a9c426a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remove this and run make verify, it removes bootCommands from the CRDs.
Disregard this, I didn't realize that all versions of the crds were in the same manifest.
// BootCommands specifies extra commands to run very early in the boot process via the cloud-init bootcmd | ||
// module. This is typically run in the cloud-init.service systemd unit. This has no effect in Ignition. | ||
// +optional | ||
BootCommands []BootCommand `json:"bootCommands,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New fields should not be added to older API versions.
Conversions should be implemented instead.
See eg
cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3/conversion.go
Lines 47 to 56 in 3db18fb
dst.Files = restored.Files | |
dst.Users = restored.Users | |
if restored.Users != nil { | |
for i := range restored.Users { | |
if restored.Users[i].PasswdFrom != nil { | |
dst.Users[i].PasswdFrom = restored.Users[i].PasswdFrom | |
} | |
} | |
} |
@@ -34,6 +34,7 @@ func TestNewInitControlPlaneAdditionalFileEncodings(t *testing.T) { | |||
cpinput := &ControlPlaneInput{ | |||
BaseUserData: BaseUserData{ | |||
Header: "test", | |||
BootCommands: nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have a test for BootCommands not nil for init, join CP, join workers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added non-nil values for BootCommands
in TestNewInitControlPlaneCommands
and TestNewJoinControlPlaneAdditionalFileEncodings
, did you want me to add more tests or is this enough? I couldn't find one for "join workers" daf4f97
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WRT to changes in TestNewInitControlPlaneCommands, TestNewJoinControlPlaneAdditionalFileEncodings I have dedicated comments.
We still need test coverage for join and join CP (if they are missing, kindly add them so we pay down some tech debt before adding more on top)
@@ -548,7 +548,7 @@ func TestMatchInitOrJoinConfiguration(t *testing.T) { | |||
}, | |||
JoinConfiguration: nil, | |||
Files: nil, | |||
... // 10 identical fields | |||
... // 11 identical fields |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to take some time to dig into impact of this change on existing clusters, because we need to make sure this change does not trigger rollouts
However, I'm not sure when I will get to it 😓
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it's feasible to have this included in the next minor release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I missed this notification before.
Unfortunately code freeze is tomorrow, but let's first focus on getting the PR right first, then we can think about what options do we have
I took some time to look into this, and it should not trigger a rollout even if message in the logs could change after we deploy this change.
@chrischdi could you kindly double check this assumption
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fine. Especially clusterctl upgrade tests should catch this if it happens and we are wrong.
Edit: sorry for the long round-trip, forgot to send the review / comment... (was pending)
ebc85c2
to
28edd6c
Compare
@@ -94,6 +95,9 @@ func TestNewInitControlPlaneCommands(t *testing.T) { | |||
|
|||
cpinput := &ControlPlaneInput{ | |||
BaseUserData: BaseUserData{ | |||
BootCommands: []bootstrapv1.BootCommand{ | |||
{"echo", "hello"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to make this test to be useful to validate the code actually works/to prevent regressions, you should also modify test assertions down below that boot commands actually show up in the generated output (and possibly, ensuring that command show up in the right section of the generated file)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure how to ensure that the commands show up in the right section of the generated file, but I added a check that the bootcommands show up in the generated file and also that the bootcmd:
string is there (which is omitted when bootCommands are unset)
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to test if the out put has the expected bootcmd and runcmd block vs testing the output has single lines.
Something like
expectedRunCmd := `runcmd:
- "\"echo $(date) ': hello world!'\""
- 'kubeadm init --config /run/kubeadm/kubeadm.yaml && echo success > /run/cluster-api/bootstrap-success.complete'
- "echo $(date) ': hello world!'"`
g.Expect(out).To(ContainSubstring(expectedRunCmd))
Should work; if you want to make it fancy, you can use regex, but up to you (similar for bootCmd)
Might be, to improve readability, let's also replace hello world! with something more specific like "hello preKubeadmCommands!" and "hello postKubeadmCommands!"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion!
@@ -34,6 +34,7 @@ func TestNewInitControlPlaneAdditionalFileEncodings(t *testing.T) { | |||
cpinput := &ControlPlaneInput{ | |||
BaseUserData: BaseUserData{ | |||
Header: "test", | |||
BootCommands: nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WRT to changes in TestNewInitControlPlaneCommands, TestNewJoinControlPlaneAdditionalFileEncodings I have dedicated comments.
We still need test coverage for join and join CP (if they are missing, kindly add them so we pay down some tech debt before adding more on top)
@@ -548,7 +548,7 @@ func TestMatchInitOrJoinConfiguration(t *testing.T) { | |||
}, | |||
JoinConfiguration: nil, | |||
Files: nil, | |||
... // 10 identical fields | |||
... // 11 identical fields |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I missed this notification before.
Unfortunately code freeze is tomorrow, but let's first focus on getting the PR right first, then we can think about what options do we have
I took some time to look into this, and it should not trigger a rollout even if message in the logs could change after we deploy this change.
@chrischdi could you kindly double check this assumption
/test help |
@chrischdi: The specified target(s) for
The following commands are available to trigger optional jobs:
Use
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
/test pull-cluster-api-e2e-main |
/test pull-cluster-api-e2e-main |
/retest Looks like a flake in creating the docker container and overlapping ports |
/retest Just to make sure its really not a flake |
What this PR does / why we need it:
Adds the ability to provide bootcmd commands to cloud-init via the KubeadmConfig or KubeadmConfigTemplates custom resources. (Same for KubeadmControlPlane)
One thing that I know that does not work at the time of creating this PR is validating/mutating webhooks for KubeadmConfig and KubeadmConfigTemplates. Some pointers to where to change that would be appreciated.
Which issue(s) this PR fixes
Fixes #