From 8d3049b49beec4bd25279adac22a34b99be35f39 Mon Sep 17 00:00:00 2001 From: hc-github-team-nomad-core <82989552+hc-github-team-nomad-core@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:52:08 -0600 Subject: [PATCH] Backport of [CSI] Prevent stage_publish_base_dir from being subdir of mount_dir into release/1.6.x #19463 Co-authored-by: Grant Griffiths --- .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 000000000..96b1be83e --- /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 e1b2789a9..1b0a32fdc 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -7842,6 +7842,11 @@ func (t *Task) Validate(jobType string, tg *TaskGroup) error { 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 c49a10412..c4a7c8add 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -2905,6 +2905,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 799203865..a0bfa3ac8 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