Skip to content

Commit 4fb6dd8

Browse files
ON-15386: Add configurable file mount locations to CRD
1 parent 16c633e commit 4fb6dd8

File tree

7 files changed

+149
-75
lines changed

7 files changed

+149
-75
lines changed

api/v1alpha1/onload_types.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ type DevicePluginSpec struct {
104104
// +optional
105105
// MountOnload is used by the Onload Device Plugin to decide whether to
106106
// mount the `onload` script as a file in the container's filesystem.
107-
// `onload` is mounted at `/usr/bin/onload`
107+
// `onload` is mounted at `<baseMountPath>/<binMountpath>`
108108
// Mutually exclusive with Preload
109109
// +kubebuilder:default:=false
110110
MountOnload *bool `json:"mountOnload,omitempty"`
@@ -117,19 +117,19 @@ type DevicePluginSpec struct {
117117

118118
// +optional
119119
// BaseMountPath is a prefix to be applied to all onload file mounts in the
120-
// container's file system.
120+
// container's filesystem.
121121
// +kubebuilder:default=/opt/onload
122122
BaseMountPath *string `json:"baseMountPath,omitempty"`
123123

124124
// +optional
125125
// BinMountPath is the location to mount onload binaries in the container's
126-
// file system.
126+
// filesystem.
127127
// +kubebuilder:default=/usr/bin
128128
BinMountPath *string `json:"binMountPath,omitempty"`
129129

130130
// +optional
131131
// LibMountPath is the location to mount onload libraries in the container's
132-
// file system.
132+
// filesystem.
133133
// +kubebuilder:default=/usr/lib64
134134
LibMountPath *string `json:"libMounthPath,omitempty"`
135135
}

api/v1alpha1/zz_generated.deepcopy.go

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

cmd/deviceplugin/main.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@ func main() {
2626
flag.BoolVar(&config.MountOnload, "mountOnload",
2727
deviceplugin.DefaultConfig.MountOnload,
2828
"Should the device plugin mount the onload script into the pod")
29-
flag.StringVar(&config.HostPathPrefix, "hostOnloadPath", "/opt/onload/",
29+
flag.StringVar(&config.HostPathPrefix, "hostOnloadPath",
30+
deviceplugin.DefaultConfig.HostPathPrefix,
3031
"Base location of onload files on the host filesystem")
31-
flag.StringVar(&config.BaseMountPath, "baseMountPath", "/opt/onload",
32-
"Prefix to be applied to all file mounts in the container's file system")
33-
flag.StringVar(&config.BinMountPath, "binMountPath", "/usr/bin/",
34-
"Location to mount onload binaries in the container's file system")
35-
flag.StringVar(&config.LibMountPath, "libMountPath", "/usr/lib64",
36-
"Location to mount onload libraries in the container's file system")
32+
flag.StringVar(&config.BaseMountPath, "baseMountPath",
33+
deviceplugin.DefaultConfig.BaseMountPath,
34+
"Prefix to be applied to all file mounts in the container's filesystem")
35+
flag.StringVar(&config.BinMountPath, "binMountPath",
36+
deviceplugin.DefaultConfig.BinMountPath,
37+
"Location to mount onload binaries in the container's filesystem")
38+
flag.StringVar(&config.LibMountPath, "libMountPath",
39+
deviceplugin.DefaultConfig.LibMountPath,
40+
"Location to mount onload libraries in the container's filesystem")
3741
flag.Parse()
3842
err := flag.Lookup("logtostderr").Value.Set("true")
3943
if err != nil {

config/crd/bases/onload.amd.com_onloads.yaml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,33 @@ spec:
4141
description: DevicePlugin is the specification of the device plugin
4242
that will add a new onload resource into the cluster.
4343
properties:
44+
baseMountPath:
45+
default: /opt/onload
46+
description: BaseMountPath is a prefix to be applied to all onload
47+
file mounts in the container's filesystem.
48+
type: string
49+
binMountPath:
50+
default: /usr/bin
51+
description: BinMountPath is the location to mount onload binaries
52+
in the container's filesystem.
53+
type: string
4454
devicePluginImage:
4555
description: DevicePluginImage
4656
type: string
57+
hostOnloadPath:
58+
default: /opt/onload/
59+
description: HostOnloadPath is the base location of onload files
60+
on the host filesystem.
61+
type: string
4762
imagePullPolicy:
4863
description: 'ImagePullPolicy is the policy used when pulling
4964
images. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images'
5065
type: string
66+
libMounthPath:
67+
default: /usr/lib64
68+
description: LibMountPath is the location to mount onload libraries
69+
in the container's filesystem.
70+
type: string
5171
maxPodsPerNode:
5272
default: 100
5373
description: MaxPodsPerNode is the number of Kubernetes devices
@@ -59,7 +79,7 @@ spec:
5979
default: false
6080
description: MountOnload is used by the Onload Device Plugin to
6181
decide whether to mount the `onload` script as a file in the
62-
container's filesystem. `onload` is mounted at `/usr/bin/onload`
82+
container's filesystem. `onload` is mounted at `<baseMountPath>/<binMountpath>`
6383
Mutually exclusive with Preload
6484
type: boolean
6585
setPreload:

config/samples/onload/base/onload_v1alpha1_onload.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,7 @@ spec:
5858
# Uncomment to select whether LD_PRELOAD should be set by the device plugin
5959
# preload: true
6060
# mountOnload: false
61+
# hostOnloadPath: /opt/onload
62+
# baseMountPath: /opt/onload
63+
# binMountPath: /usr/bin
64+
# libMountPath: /usr/lib64

controllers/onload_controller.go

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -882,20 +882,51 @@ func (r *OnloadReconciler) createDevicePluginDaemonSet(
882882
return nil, err
883883
}
884884

885+
hostOnloadPath := "/opt/onload"
886+
if onload.Spec.DevicePlugin.HostOnloadPath != nil {
887+
hostOnloadPath = *onload.Spec.DevicePlugin.HostOnloadPath
888+
}
889+
890+
postStart := &corev1.LifecycleHandler{
891+
Exec: &corev1.ExecAction{
892+
Command: []string{
893+
"/bin/sh", "-c",
894+
fmt.Sprintf(`set -e;
895+
chcon --type container_file_t --recursive %s ||
896+
echo "chcon failed. System may not be SELinux enabled.";`, hostOnloadPath),
897+
},
898+
},
899+
}
900+
901+
preStop := &corev1.LifecycleHandler{
902+
Exec: &corev1.ExecAction{
903+
Command: []string{
904+
"/bin/sh", "-c",
905+
fmt.Sprintf(`set -e;
906+
rm -r %s;`, hostOnloadPath),
907+
},
908+
},
909+
}
910+
885911
devicePluginContainer := corev1.Container{
886912
Name: "device-plugin",
887913
Image: onload.Spec.DevicePlugin.DevicePluginImage,
888914
ImagePullPolicy: onload.Spec.DevicePlugin.ImagePullPolicy,
889915
SecurityContext: &corev1.SecurityContext{
890916
Privileged: ptr.To(true),
891917
},
918+
// Lifecycle to manage the Onload files in the host.
919+
Lifecycle: &corev1.Lifecycle{
920+
PostStart: postStart,
921+
PreStop: preStop,
922+
},
892923
VolumeMounts: []corev1.VolumeMount{
893924
{
894925
MountPath: "/var/lib/kubelet/device-plugins",
895926
Name: "kubelet-socket",
896927
},
897928
{
898-
MountPath: "/opt/onload",
929+
MountPath: hostOnloadPath,
899930
Name: "host-onload",
900931
},
901932
},
@@ -917,6 +948,30 @@ func (r *OnloadReconciler) createDevicePluginDaemonSet(
917948
fmt.Sprintf("-mountOnload=%t", *onload.Spec.DevicePlugin.MountOnload))
918949
}
919950

951+
if onload.Spec.DevicePlugin.HostOnloadPath != nil {
952+
devicePluginArgs = append(devicePluginArgs,
953+
fmt.Sprintf("-hostOnloadPath=%s",
954+
*onload.Spec.DevicePlugin.HostOnloadPath))
955+
}
956+
957+
if onload.Spec.DevicePlugin.BaseMountPath != nil {
958+
devicePluginArgs = append(devicePluginArgs,
959+
fmt.Sprintf("-baseMountPath=%s",
960+
*onload.Spec.DevicePlugin.BaseMountPath))
961+
}
962+
963+
if onload.Spec.DevicePlugin.BinMountPath != nil {
964+
devicePluginArgs = append(devicePluginArgs,
965+
fmt.Sprintf("-binMountPath=%s",
966+
*onload.Spec.DevicePlugin.BinMountPath))
967+
}
968+
969+
if onload.Spec.DevicePlugin.LibMountPath != nil {
970+
devicePluginArgs = append(devicePluginArgs,
971+
fmt.Sprintf("-libMountPath=%s",
972+
*onload.Spec.DevicePlugin.LibMountPath))
973+
}
974+
920975
if len(devicePluginArgs) > 0 {
921976
devicePluginContainer.Args = devicePluginArgs
922977
}
@@ -950,27 +1005,6 @@ func (r *OnloadReconciler) createDevicePluginDaemonSet(
9501005
},
9511006
}
9521007

953-
postStart := &corev1.LifecycleHandler{
954-
Exec: &corev1.ExecAction{
955-
Command: []string{
956-
"/bin/sh", "-c",
957-
`set -e;
958-
chcon --type container_file_t --recursive /opt/onload/ ||
959-
echo "chcon failed. System may not be SELinux enabled.";`,
960-
},
961-
},
962-
}
963-
964-
preStop := &corev1.LifecycleHandler{
965-
Exec: &corev1.ExecAction{
966-
Command: []string{
967-
"/bin/sh", "-c",
968-
`set -e;
969-
rm -r /opt/onload;`,
970-
},
971-
},
972-
}
973-
9741008
workerContainer := corev1.Container{
9751009
Name: workerContainerName,
9761010
Image: onload.Spec.DevicePlugin.DevicePluginImage,
@@ -983,21 +1017,11 @@ func (r *OnloadReconciler) createDevicePluginDaemonSet(
9831017
Privileged: ptr.To(true),
9841018
},
9851019
VolumeMounts: []corev1.VolumeMount{
986-
{
987-
MountPath: "/opt/onload",
988-
Name: "host-onload",
989-
},
9901020
{
9911021
MountPath: "/mnt/onload",
9921022
Name: "worker-volume",
9931023
},
9941024
},
995-
996-
// Lifecycle to manage the Onload files in the host.
997-
Lifecycle: &corev1.Lifecycle{
998-
PostStart: postStart,
999-
PreStop: preStop,
1000-
},
10011025
Env: workerContainerEnv,
10021026
}
10031027

@@ -1023,6 +1047,10 @@ func (r *OnloadReconciler) createDevicePluginDaemonSet(
10231047
},
10241048
VolumeMounts: []corev1.VolumeMount{
10251049
{
1050+
// MounthPath here doesn't have to match hostOnloadPath. The
1051+
// location in the initContainer's filesystem doesn't affect the
1052+
// device plugin, only whether they are both looking at the same
1053+
// volumeMount.
10261054
MountPath: "/host/onload",
10271055
Name: "host-onload",
10281056
},
@@ -1049,7 +1077,7 @@ func (r *OnloadReconciler) createDevicePluginDaemonSet(
10491077
Name: "host-onload",
10501078
VolumeSource: corev1.VolumeSource{
10511079
HostPath: &corev1.HostPathVolumeSource{
1052-
Path: "/opt/onload",
1080+
Path: hostOnloadPath,
10531081
Type: ptr.To(corev1.HostPathDirectoryOrCreate),
10541082
},
10551083
},

controllers/onload_controller_test.go

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package controllers
44

55
import (
66
"errors"
7-
"fmt"
87
"strconv"
98
"time"
109

@@ -793,7 +792,7 @@ var _ = Describe("onload controller", func() {
793792
)
794793

795794
DescribeTable("Testing Device Plugin options",
796-
func(dev *onloadv1alpha1.DevicePluginSpec) {
795+
func(dev *onloadv1alpha1.DevicePluginSpec, args string) {
797796
devicePlugin := appsv1.DaemonSet{}
798797
devicePluginName := types.NamespacedName{
799798
Name: onload.Name + "-onload-device-plugin-ds",
@@ -812,44 +811,43 @@ var _ = Describe("onload controller", func() {
812811
return err == nil
813812
}, timeout, pollingInterval).Should(BeTrue())
814813

815-
Expect(devicePlugin.Spec.Template.Spec.Containers).Should(
816-
ContainElement(MatchFields(IgnoreExtras, Fields{
817-
"Args": BeEmpty(),
818-
})),
819-
)
820-
if dev != nil {
821-
if dev.MaxPodsPerNode != nil {
822-
Expect(devicePlugin.Spec.Template.Spec.Containers).Should(
823-
ContainElement(MatchFields(IgnoreExtras, Fields{
824-
"Args": ContainElement(Equal(fmt.Sprintf("-maxPods=%d", *dev.MaxPodsPerNode))),
825-
})),
826-
)
827-
}
828-
if dev.SetPreload != nil {
829-
Expect(devicePlugin.Spec.Template.Spec.Containers).Should(
830-
ContainElement(MatchFields(IgnoreExtras, Fields{
831-
"Args": ContainElement(Equal(fmt.Sprintf("-setPreload=%t", *dev.SetPreload))),
832-
})),
833-
)
834-
}
835-
if dev.MountOnload != nil {
836-
Expect(devicePlugin.Spec.Template.Spec.Containers).Should(
837-
ContainElement(MatchFields(IgnoreExtras, Fields{
838-
"Args": ContainElement(Equal(fmt.Sprintf("-mountOnload=%t", *dev.MountOnload))),
839-
})),
840-
)
841-
}
814+
if args != "" {
815+
Expect(devicePlugin.Spec.Template.Spec.Containers).Should(
816+
ContainElement(MatchFields(IgnoreExtras, Fields{
817+
"Args": ContainElement(args),
818+
})),
819+
)
842820
}
821+
843822
},
844-
Entry( /*It*/ "shouldn't add anything when empty", nil),
823+
Entry( /*It*/ "shouldn't add anything when empty", nil, ""),
845824
Entry( /*It*/ "should pass the value of maxPodsPerNode through",
846825
&onloadv1alpha1.DevicePluginSpec{MaxPodsPerNode: ptr.To(1)},
826+
"-maxPods=1",
847827
),
848828
Entry( /*It*/ "should pass the value of setPreload through",
849829
&onloadv1alpha1.DevicePluginSpec{SetPreload: ptr.To(false)},
830+
"-setPreload=false",
850831
),
851832
Entry( /*It*/ "should pass the value of mountOnload through",
852833
&onloadv1alpha1.DevicePluginSpec{MountOnload: ptr.To(false)},
834+
"-mountOnload=false",
835+
),
836+
Entry( /*It*/ "should pass the value of hostOnloadPath through",
837+
&onloadv1alpha1.DevicePluginSpec{HostOnloadPath: ptr.To("foo")},
838+
"-hostOnloadPath=foo",
839+
),
840+
Entry( /*It*/ "should pass the value of baseMountPath through",
841+
&onloadv1alpha1.DevicePluginSpec{BaseMountPath: ptr.To("bar")},
842+
"-baseMountPath=bar",
843+
),
844+
Entry( /*It*/ "should pass the value of binMountPath through",
845+
&onloadv1alpha1.DevicePluginSpec{BinMountPath: ptr.To("baz")},
846+
"-binMountPath=baz",
847+
),
848+
Entry( /*It*/ "should pass the value of libMountPath through",
849+
&onloadv1alpha1.DevicePluginSpec{LibMountPath: ptr.To("qux")},
850+
"-libMountPath=qux",
853851
),
854852
)
855853
})

0 commit comments

Comments
 (0)