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

feat: Provide operating system from config #1809

Merged
merged 5 commits into from
Feb 10, 2022
Merged
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
3 changes: 2 additions & 1 deletion docs/api_reference/v1beta2.en.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
+++
title = "v1beta2 API Reference"
date = 2022-01-28T16:22:51+05:00
date = 2022-02-04T17:38:06+02:00
weight = 11
+++
## v1beta2
Expand Down Expand Up @@ -401,6 +401,7 @@ HostConfig describes a single control plane node.
| isLeader | IsLeader indicates this host as a session leader. Default value is populated at the runtime. | bool | false |
| taints | Taints if not provided (i.e. nil) defaults to TaintEffectNoSchedule, with key node-role.kubernetes.io/master for control plane nodes. Explicitly empty (i.e. []corev1.Taint{}) means no taints will be applied (this is default for worker nodes). | [][corev1.Taint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#taint-v1-core) | false |
| kubelet | Kubelet | [KubeletConfig](#kubeletconfig) | false |
| operatingSystem | OperatingSystem information, can be populated at the runtime. | OperatingSystemName | false |

[Back to Group](#v1beta2)

Expand Down
2 changes: 2 additions & 0 deletions examples/terraform/aws/output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ output "kubeone_hosts" {
cloud_provider = "aws"
private_address = aws_instance.control_plane.*.private_ip
hostnames = aws_instance.control_plane.*.private_dns
operating_system = var.os
ssh_agent_socket = var.ssh_agent_socket
ssh_port = var.ssh_port
ssh_private_key_file = var.ssh_private_key_file
Expand All @@ -54,6 +55,7 @@ output "kubeone_static_workers" {
workers1 = {
private_address = aws_instance.static_workers1.*.private_ip
hostnames = aws_instance.static_workers1.*.private_dns
operating_system = var.os
ssh_agent_socket = var.ssh_agent_socket
ssh_port = var.ssh_port
ssh_private_key_file = var.ssh_private_key_file
Expand Down
6 changes: 3 additions & 3 deletions examples/terraform/aws/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ variable "ami_filters" {
}

centos = {
owners = ["125523088429"] # CentOS
image_name = ["CentOS 8.* x86_64"]
osp_name = "osp-centos8"
owners = ["792107900819"] # RockyLinux
image_name = ["Rocky-8-ec2-*.x86_64"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Live example of RHEL-rebuild is being used as a substitution for CentOS8

osp_name = "osp-centos"
}

flatcar = {
Expand Down
27 changes: 25 additions & 2 deletions pkg/apis/kubeone/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,31 @@ func (h *HostConfig) SetHostname(hostname string) {
}

// SetOperatingSystem sets the operating system for the given host
func (h *HostConfig) SetOperatingSystem(os OperatingSystemName) {
h.OperatingSystem = os
func (h *HostConfig) SetOperatingSystem(os OperatingSystemName) error {
if h.OperatingSystem.IsValid() {
h.OperatingSystem = os

return nil
}

return errors.Errorf("unknown operating system %q", os)
}

func (osName OperatingSystemName) IsValid() bool {
// linter exhaustive will make sure this switch is iterating over all current and future possibilities
switch osName {
case OperatingSystemNameUbuntu:
case OperatingSystemNameDebian:
case OperatingSystemNameCentOS:
case OperatingSystemNameRHEL:
case OperatingSystemNameAmazon:
case OperatingSystemNameFlatcar:
case OperatingSystemNameUnknown:
default:
return false
}

return true
}

// SetLeader sets is the given host leader
Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/kubeone/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ type HostConfig struct {
Taints []corev1.Taint `json:"taints,omitempty"`
// Kubelet
Kubelet KubeletConfig `json:"kubelet,omitempty"`
// OperatingSystem information populated at the runtime.
OperatingSystem OperatingSystemName `json:"-"`
// OperatingSystem information, can be populated at the runtime.
OperatingSystem OperatingSystemName `json:"operatingSystem,omitempty"`
}

// ControlPlaneConfig defines control plane nodes
Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/kubeone/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ type HostConfig struct {
Taints []corev1.Taint `json:"taints,omitempty"`
// Kubelet
Kubelet KubeletConfig `json:"kubelet,omitempty"`
// OperatingSystem information populated at the runtime.
OperatingSystem OperatingSystemName `json:"-"`
// OperatingSystem information, can be populated at the runtime.
OperatingSystem OperatingSystemName `json:"operatingSystem,omitempty"`
}

// ControlPlaneConfig defines control plane nodes
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/kubeone/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,9 @@ func ValidateHostConfig(hosts []kubeoneapi.HostConfig, fldPath *field.Path) fiel
if len(h.SSHUsername) == 0 {
allErrs = append(allErrs, field.Required(fldPath, "no SSH username given"))
}
if !h.OperatingSystem.IsValid() {
allErrs = append(allErrs, field.Invalid(fldPath.Child("operatingSystem"), h.OperatingSystem, "invalid operatingSystem provided"))
}
}

return allErrs
Expand Down
28 changes: 28 additions & 0 deletions pkg/apis/kubeone/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,34 @@ func TestValidateHostConfig(t *testing.T) {
},
expectedError: true,
},
{
name: "valid OS",
hostConfig: []kubeoneapi.HostConfig{
{
PublicAddress: "192.168.1.1",
PrivateAddress: "192.168.0.1",
SSHPrivateKeyFile: "test",
SSHAgentSocket: "test",
SSHUsername: "root",
OperatingSystem: kubeoneapi.OperatingSystemNameCentOS,
},
},
expectedError: false,
},
{
name: "invalid OS",
hostConfig: []kubeoneapi.HostConfig{
{
PublicAddress: "192.168.1.1",
PrivateAddress: "192.168.0.1",
SSHPrivateKeyFile: "test",
SSHAgentSocket: "test",
SSHUsername: "root",
OperatingSystem: kubeoneapi.OperatingSystemName("non-existing"),
},
},
expectedError: true,
},
}

for _, tc := range tests {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ func runApplyInstall(s *state.State, opts *applyOpts) error { // Print the expec

for _, node := range s.LiveCluster.StaticWorkers {
if !node.IsInCluster {
fmt.Printf("\t+ join worker node %q (%s)\n", node.Config.Hostname, node.Config.PrivateAddress)
fmt.Printf("\t+ join static worker node %q (%s)\n", node.Config.Hostname, node.Config.PrivateAddress)
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/tasks/prerequisites.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func installPrerequisites(s *state.State) error {
return fmt.Errorf("failed to install prerequisites: %w", err)
}

return s.RunTaskOnAllNodes(func(ctx *state.State, node *kubeoneapi.HostConfig, conn ssh.Connection) error {
return s.RunTaskOnControlPlane(func(ctx *state.State, node *kubeoneapi.HostConfig, conn ssh.Connection) error {
ctx.Logger.Info("Pre-pull images")

_, _, err := ctx.Runner.Run(
Expand Down
13 changes: 11 additions & 2 deletions pkg/tasks/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func determineHostname(s *state.State) error {

return s.RunTaskOnAllNodes(func(s *state.State, node *kubeoneapi.HostConfig, conn ssh.Connection) error {
if node.Hostname != "" {
s.Logger.Debugf("Hostname is already set to %q", node.Hostname)

return nil
}

Expand All @@ -64,6 +66,7 @@ func determineHostname(s *state.State) error {
return err
}

s.Logger.Debugf("Hostname is detected: %q", stdout)
node.SetHostname(stdout)

return nil
Expand All @@ -74,15 +77,21 @@ func determineOS(s *state.State) error {
s.Logger.Infoln("Determine operating system...")

return s.RunTaskOnAllNodes(func(s *state.State, node *kubeoneapi.HostConfig, conn ssh.Connection) error {
if node.OperatingSystem != kubeoneapi.OperatingSystemNameUnknown {
s.Logger.Debugf("Operating system is already set to %q", node.OperatingSystem)

return nil
}

buf, err := fs.ReadFile(sshiofs.New(conn), "/etc/os-release")
if err != nil {
return err
}

osrData := osrelease.Parse(string(buf))
node.SetOperatingSystem(kubeoneapi.OperatingSystemName(osrData.ID))
s.Logger.Debugf("Operating system detected: %q", osrData.ID)

return nil
return node.SetOperatingSystem(kubeoneapi.OperatingSystemName(osrData.ID))
}, state.RunParallel)
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/terraform/v1beta2/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type hostsSpec struct {
PublicAddress []string `json:"public_address"`
PrivateAddress []string `json:"private_address"`
Hostnames []string `json:"hostnames"`
OperatingSystem string `json:"operating_system"`
SSHUser string `json:"ssh_user"`
SSHPort int `json:"ssh_port"`
SSHPrivateKeyFile string `json:"ssh_private_key_file"`
Expand Down Expand Up @@ -286,6 +287,7 @@ func newHostConfig(publicIP, privateIP, hostname string, hs *hostsSpec) kubeonev
BastionPort: hs.BastionPort,
BastionUser: hs.BastionUser,
Hostname: hostname,
OperatingSystem: kubeonev1beta2.OperatingSystemName(hs.OperatingSystem),
PrivateAddress: privateIP,
PublicAddress: publicIP,
SSHAgentSocket: hs.SSHAgentSocket,
Expand Down