dynamic host volumes: remove multi-node access modes (#24705)

CSI volumes support multi-node access patterns on the same volume ID, but
dynamic host volumes by nature do not. The underlying volume may actually be
multi-node (ex. NFS), but Nomad is ignorant of this. Remove the CSI-specific
multi-node access modes and instead include the single-node access modes
intended that are currently in the alpha edition of the CSI spec but which are
better suited for DHV.

This PR has been extracted from #24684 to keep reviews manageable.

Ref: https://github.com/hashicorp/nomad/pull/24479
Ref: https://github.com/hashicorp/nomad/pull/24684
This commit is contained in:
Tim Gross
2024-12-18 08:44:08 -05:00
parent 967addec48
commit 2adf6d5208
4 changed files with 23 additions and 20 deletions

View File

@@ -275,9 +275,8 @@ func (hvc *HostVolumeCapability) Validate() error {
switch hvc.AccessMode {
case HostVolumeAccessModeSingleNodeReader,
HostVolumeAccessModeSingleNodeWriter,
HostVolumeAccessModeMultiNodeReader,
HostVolumeAccessModeMultiNodeSingleWriter,
HostVolumeAccessModeMultiNodeMultiWriter:
HostVolumeAccessModeSingleNodeSingleWriter,
HostVolumeAccessModeSingleNodeMultiWriter:
default:
return fmt.Errorf("invalid access mode: %q", hvc.AccessMode)
}
@@ -302,12 +301,10 @@ type HostVolumeAccessMode string
const (
HostVolumeAccessModeUnknown HostVolumeAccessMode = ""
HostVolumeAccessModeSingleNodeReader HostVolumeAccessMode = "single-node-reader-only"
HostVolumeAccessModeSingleNodeWriter HostVolumeAccessMode = "single-node-writer"
HostVolumeAccessModeMultiNodeReader HostVolumeAccessMode = "multi-node-reader-only"
HostVolumeAccessModeMultiNodeSingleWriter HostVolumeAccessMode = "multi-node-single-writer"
HostVolumeAccessModeMultiNodeMultiWriter HostVolumeAccessMode = "multi-node-multi-writer"
HostVolumeAccessModeSingleNodeReader HostVolumeAccessMode = "single-node-reader-only"
HostVolumeAccessModeSingleNodeWriter HostVolumeAccessMode = "single-node-writer"
HostVolumeAccessModeSingleNodeSingleWriter HostVolumeAccessMode = "single-node-single-writer"
HostVolumeAccessModeSingleNodeMultiWriter HostVolumeAccessMode = "single-node-multi-writer"
)
// HostVolumeStub is used for responses for the list volumes endpoint

View File

@@ -45,7 +45,7 @@ func TestHostVolume_Copy(t *testing.T) {
out.Constraints[0].LTarget = "${meta.node_class}"
out.RequestedCapabilities = append(out.RequestedCapabilities, &HostVolumeCapability{
AttachmentMode: HostVolumeAttachmentModeBlockDevice,
AccessMode: HostVolumeAccessModeMultiNodeReader,
AccessMode: HostVolumeAccessModeSingleNodeMultiWriter,
})
out.Parameters["foo"] = "baz"
@@ -195,7 +195,7 @@ func TestHostVolume_CanonicalizeForUpdate(t *testing.T) {
RequestedCapacityMaxBytes: 500000,
RequestedCapabilities: []*HostVolumeCapability{{
AttachmentMode: HostVolumeAttachmentModeFilesystem,
AccessMode: HostVolumeAccessModeMultiNodeMultiWriter,
AccessMode: HostVolumeAccessModeSingleNodeMultiWriter,
}},
}
existing := &HostVolume{
@@ -240,7 +240,7 @@ func TestHostVolume_CanonicalizeForUpdate(t *testing.T) {
must.Eq(t, []*HostVolumeCapability{{
AttachmentMode: HostVolumeAttachmentModeFilesystem,
AccessMode: HostVolumeAccessModeMultiNodeMultiWriter,
AccessMode: HostVolumeAccessModeSingleNodeMultiWriter,
}}, vol.RequestedCapabilities)
must.Eq(t, "/var/nomad/alloc_mounts/82f357d6.ext4", vol.HostPath)

View File

@@ -170,16 +170,22 @@ func (v *VolumeRequest) Validate(jobType string, taskGroupCount, canaries int) e
switch v.Type {
case VolumeTypeHost:
if v.AttachmentMode != CSIVolumeAttachmentModeUnknown {
addErr("host volumes cannot have an attachment mode")
}
if v.AccessMode != CSIVolumeAccessModeUnknown {
addErr("host volumes cannot have an access mode")
}
if v.MountOptions != nil {
// TODO(1.10.0): support mount options for dynamic host volumes
addErr("host volumes cannot have mount options")
}
switch v.AccessMode {
case CSIVolumeAccessModeSingleNodeReader, CSIVolumeAccessModeMultiNodeReader:
if !v.ReadOnly {
addErr("%s volumes must be read-only", v.AccessMode)
}
default:
// dynamic host volumes are all "per node" so there's no way to
// validate that other access modes work for a given volume until we
// have access to other allocations (in the scheduler)
}
case VolumeTypeCSI:
switch v.AttachmentMode {

View File

@@ -31,9 +31,9 @@ func TestVolumeRequest_Validate(t *testing.T) {
{
name: "host volume with CSI volume config",
expected: []string{
"host volumes cannot have an access mode",
"host volumes cannot have an attachment mode",
"volume has an empty source",
"host volumes cannot have mount options",
"single-node-reader-only volumes must be read-only",
"volume cannot be per_alloc for system or sysbatch jobs",
"volume cannot be per_alloc when canaries are in use",
},