From 8e2a3f327bffb4e5339c0267adb75199ab2f375a Mon Sep 17 00:00:00 2001 From: Grant Griffiths Date: Wed, 13 Dec 2023 19:31:40 +0000 Subject: [PATCH] backport of commit 9b2e8ae20fe8cb119f9ce598d22f3af6760cefc9 --- .changelog/19441.txt | 3 +++ nomad/structs/structs.go | 5 +++++ nomad/structs/structs_test.go | 10 ++++++++++ website/content/docs/job-specification/csi_plugin.mdx | 3 ++- 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .changelog/19441.txt diff --git a/.changelog/19441.txt b/.changelog/19441.txt new file mode 100644 index 00000000000..96b1be83ea0 --- /dev/null +++ b/.changelog/19441.txt @@ -0,0 +1,3 @@ +```release-note:bug +csi: Added validation to `csi_plugin` blocks to prevent `stage_publish_base_dir` from being a subdirectory of `mount_dir` +``` diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 88579e819d9..723613649f3 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -7607,6 +7607,11 @@ func (t *Task) Validate(ephemeralDisk *EphemeralDisk, jobType string, tgServices mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \"%s\"", t.CSIPluginConfig.Type)) } + if t.CSIPluginConfig.StagePublishBaseDir != "" && t.CSIPluginConfig.MountDir != "" && + strings.HasPrefix(t.CSIPluginConfig.StagePublishBaseDir, t.CSIPluginConfig.MountDir) { + mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig StagePublishBaseDir must not be a subdirectory of MountDir, got: StagePublishBaseDir=\"%s\" MountDir=\"%s\"", t.CSIPluginConfig.StagePublishBaseDir, t.CSIPluginConfig.MountDir)) + } + // TODO: Investigate validation of the PluginMountDir. Not much we can do apart from check IsAbs until after we understand its execution environment though :( } diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index c6f8588ddc9..de476e9d9c9 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -2717,6 +2717,16 @@ func TestTask_Validate_CSIPluginConfig(t *testing.T) { }, expectedErr: "CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \"nonsense\"", }, + { + name: "requires staging publish base dir to not be a subdir of mountdir", + pc: &TaskCSIPluginConfig{ + ID: "com.hashicorp.csi", + Type: "monolith", + MountDir: "/csi", + StagePublishBaseDir: "/csi/local", + }, + expectedErr: "CSIPluginConfig StagePublishBaseDir must not be a subdirectory of MountDir, got: StagePublishBaseDir=\"/csi/local\" MountDir=\"/csi\"", + }, } for _, tt := range table { diff --git a/website/content/docs/job-specification/csi_plugin.mdx b/website/content/docs/job-specification/csi_plugin.mdx index f29bc2bfa6e..d1ada0e150a 100644 --- a/website/content/docs/job-specification/csi_plugin.mdx +++ b/website/content/docs/job-specification/csi_plugin.mdx @@ -49,7 +49,8 @@ csi_plugin { - `stage_publish_base_dir` `(string: )` - The base directory path inside the container where the plugin will be instructed to stage and publish volumes. This field is typically not required. - Refer to your CSI plugin's documentation for details. + Refer to your CSI plugin's documentation for details. This can not + be a subdirectory of `mount_dir`. - `health_timeout` `(duration: )` - The duration that the plugin supervisor will wait before restarting an unhealthy