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(ensurer): add additional units and files for lvm disk provisioni… #325

Merged
merged 8 commits into from
Oct 16, 2024
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ You can run the controller locally on your machine by executing `make start`.

Static code checks and tests can be executed by running `make verify`. We are using Go modules for Golang package dependency management and [Ginkgo](https://github.com/onsi/ginkgo)/[Gomega](https://github.com/onsi/gomega) for testing.

## Caveats
You can use all available disks on your Equinix instance, but only under
certain conditions:
* You must use Flatcar
* You must have a homogenous worker pool
RiRa12621 marked this conversation as resolved.
Show resolved Hide resolved
* You must set any value for `DataVolume`

## Feedback and Support

Feedback and contributions are always welcome. Please report bugs or suggestions as [GitHub issues](https://github.com/gardener/gardener-extension-provider-equinix-metal/issues) or join our [Slack channel #gardener](https://kubernetes.slack.com/messages/gardener) (please invite yourself to the Kubernetes workspace [here](http://slack.k8s.io)).
Expand Down
149 changes: 149 additions & 0 deletions pkg/webhook/controlplane/ensurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package controlplane

import (
"context"
"fmt"

"github.com/Masterminds/semver/v3"
"github.com/coreos/go-systemd/v22/unit"
Expand Down Expand Up @@ -149,6 +150,154 @@ func keepNodeNetworkEnvVarIfPresentInOldDeployment(new, old *appsv1.Deployment,
}
}

// EnsureAdditionalProvisionUnits ensures that additional required system units are added, that are required during provisioning.
func (e *ensurer) EnsureAdditionalProvisionUnits(ctx context.Context, gctx gcontext.GardenContext, new, _ *[]extensionsv1alpha1.Unit) error {

cluster, err := gctx.GetCluster(ctx)
if err != nil {
return err
}

// Define LVM setup unit
var lvmSetup = `
[Unit]
Description=LVM Setup
ConditionFirstBoot=yes
DefaultDependencies=no
Before=local-fs-pre.target
[Service]
Type=oneshot
Restart=on-failure
RemainAfterExit=yes
ExecStart=/opt/bin/lvm.sh
[Install]
WantedBy=multi-user.target
`
// Define LVM mount unit
var lvmMountContainerd = `
[Unit]
Description=Mount LVM to containerd dir
After=lvm-setup.service
Before=containerd.service
[Mount]
What=/dev/vg-containerd/vol_containerd
Where=/var/lib/containerd
Type=ext4
Options=defaults
[Install]
WantedBy=local-fs.target
`
operatingsystems := make(map[string]int)
for _, worker := range cluster.Shoot.Spec.Provider.Workers {
if worker.DataVolumes != nil {
// fail if multiple OSes are used
operatingsystems[worker.Machine.Image.Name]++
if len(operatingsystems) > 1 {
return fmt.Errorf("multiple operatingsystems used")
RiRa12621 marked this conversation as resolved.
Show resolved Hide resolved
}
switch worker.Machine.Image.Name {
case "flatcar":
extensionswebhook.AppendUniqueUnit(new, extensionsv1alpha1.Unit{
Name: "lvm-setup.service",
Enable: ptr.To(true),
Command: ptr.To(extensionsv1alpha1.CommandStart),
Content: ptr.To(lvmSetup),
})

extensionswebhook.AppendUniqueUnit(new, extensionsv1alpha1.Unit{
Name: "var-lib-containerd.mount",
Enable: ptr.To(true),
Command: ptr.To(extensionsv1alpha1.CommandStart),
Content: ptr.To(lvmMountContainerd),
})

return nil
}

}
}
return nil
}

// EnsureAdditionalProvisionFiles ensures that additional required system files are added, that are required during provisioning.
RiRa12621 marked this conversation as resolved.
Show resolved Hide resolved
func (e *ensurer) EnsureAdditionalProvisionFiles(ctx context.Context, gctx gcontext.GardenContext, new, _ *[]extensionsv1alpha1.File) error {
cluster, err := gctx.GetCluster(ctx)
if err != nil {
return err
}

operatingsystems := make(map[string]int)
for _, worker := range cluster.Shoot.Spec.Provider.Workers {
// if any worker is having any value set for `DataVolume`
// this script creates a lvm from all remaining non-boot disks.
if worker.DataVolumes != nil {
// fail if multiple OSes are used
operatingsystems[worker.Machine.Image.Name]++
if len(operatingsystems) > 1 {
return fmt.Errorf("multiple operatingsystems used")
}

switch worker.Machine.Image.Name {
case "flatcar":

var (
permissions int32 = 0755
customFileContent = `#!/bin/bash
set -euo pipefail


# Function to find all disks
find_volumes(){
lsblk -d -o NAME,TYPE | awk '$2 == "disk" {print "/dev/" $1}'
}

create_pvs() {
disks=$(find_volumes)
usable_disks=""

for disk in $disks; do
if pvcreate -y $disk 2>&1 | grep -q "successfully created"; then
usable_disks="$usable_disks $disk"
fi
done

echo $usable_disks
}

# Get the list of usable disks
usable_disks=$(create_pvs)

# Create Physical Volumes
pvcreate ${usable_disks}

# Create Volume Group
vgcreate vg-containerd ${usable_disks}

# Create Logical Volume for data
lvcreate -n vol_containerd -l 100%FREE vg-containerd

# Format the data volume with ext4 filesystem
mkfs.ext4 /dev/vg-containerd/vol_containerd
`
)

appendUniqueFile(new, extensionsv1alpha1.File{
Path: "/opt/bin/lvm.sh",
Permissions: &permissions,
Content: extensionsv1alpha1.FileContent{
Inline: &extensionsv1alpha1.FileContentInline{
Encoding: "",
Data: customFileContent,
},
},
})
return nil
}
}
}
return nil
}

// EnsureAdditionalUnits ensures that additional required system units are added.
func (e *ensurer) EnsureAdditionalUnits(_ context.Context, _ gcontext.GardenContext, new, _ *[]extensionsv1alpha1.Unit) error {
extensionswebhook.AppendUniqueUnit(new, extensionsv1alpha1.Unit{
Expand Down