Skip to content

Commit

Permalink
Revert "[CSI] remove VOLUME_MOUNT_GROUP capability (#2739)" (#2872)
Browse files Browse the repository at this point in the history
issue: #2795

This reverts commit d371333.

The removal of the VOLUME_MOUNT_GROUP capability is not possible at this time, as we must first migrate to the new storage classes.
  • Loading branch information
antonmyagkov authored Jan 17, 2025
1 parent 7a4d68a commit 04b9add
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 7 deletions.
70 changes: 70 additions & 0 deletions cloud/blockstore/tests/csi_driver/e2e_tests_part2/test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest
import subprocess

from pathlib import Path

import cloud.blockstore.tests.csi_driver.lib.csi_runner as csi


Expand Down Expand Up @@ -59,6 +61,74 @@ def test_readonly_volume(mount_path, access_type, vm_mode, gid):
csi.cleanup_after_test(env, volume_name, access_type, [pod_id])


def test_mount_volume_group():
# Scenario
# 1. create volume and publish volume without mount volume group
# 2. create directory and file
# 3. unpublish volume
# 4. create new group with specified GID
# 5. publish volume with mount volume group GID
# 6. check that mounted dir and existing files have specified GID
# 7. create new directory and file
# 8. check that new directory and file have specified GID
env, run = csi.init()
try:
volume_name = "example-disk"
volume_size = 1024 ** 3
pod_name = "example-pod"
pod_id = "deadbeef1"
access_type = "mount"
env.csi.create_volume(name=volume_name, size=volume_size)
env.csi.stage_volume(volume_name, access_type)

gid = 1013
result = subprocess.run(
["groupadd", "-g", str(gid), "test_group_" + str(gid)],
capture_output=True,
)
assert result.returncode == 0

env.csi.publish_volume(
pod_id,
volume_name,
pod_name,
access_type
)

mount_path = Path("/var/lib/kubelet/pods") / pod_id / "volumes/kubernetes.io~csi" / volume_name / "mount"
test_dir1 = mount_path / "testdir1"
test_dir1.mkdir()
test_file1 = test_dir1 / "testfile1"
test_file1.touch()

env.csi.unpublish_volume(pod_id, volume_name, access_type)
env.csi.publish_volume(
pod_id,
volume_name,
pod_name,
access_type,
volume_mount_group=str(gid)
)

assert gid == mount_path.stat().st_gid
assert gid == test_dir1.stat().st_gid
assert gid == test_file1.stat().st_gid

test_file2 = mount_path / "testfile2"
test_file2.touch()
assert gid == test_file2.stat().st_gid

test_dir2 = mount_path / "testdir2"
test_dir2.mkdir()
assert gid == test_dir2.stat().st_gid

except subprocess.CalledProcessError as e:
csi.log_called_process_error(e)
raise
finally:
csi.cleanup_after_test(env, volume_name, access_type, [pod_id])


def test_node_volume_expand_vm_mode():
env, run = csi.init(vm_mode=True)
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,3 @@ metadata:
provisioner: nbs.csi.nebius.ai
volumeBindingMode: Immediate
allowVolumeExpansion: true
parameters:
fsType: ext4
33 changes: 32 additions & 1 deletion cloud/blockstore/tools/csi_driver/internal/driver/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"log"
"math"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
Expand Down Expand Up @@ -54,6 +55,13 @@ var vmModeCapabilities = []*csi.NodeServiceCapability{
},
},
},
{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Type: csi.NodeServiceCapability_RPC_VOLUME_MOUNT_GROUP,
},
},
},
{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Expand All @@ -73,6 +81,13 @@ var podModeCapabilities = []*csi.NodeServiceCapability{
},
},
},
{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Type: csi.NodeServiceCapability_RPC_VOLUME_MOUNT_GROUP,
},
},
},
{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Expand Down Expand Up @@ -643,6 +658,14 @@ func (s *nodeService) nodePublishDiskAsFilesystem(
return err
}

if mnt != nil && mnt.VolumeMountGroup != "" && !req.Readonly {
cmd := exec.Command("chown", "-R", ":"+mnt.VolumeMountGroup, req.TargetPath)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to chown %s to %q: %w, output %q",
mnt.VolumeMountGroup, req.TargetPath, err, out)
}
}

return nil
}

Expand Down Expand Up @@ -697,7 +720,7 @@ func (s *nodeService) nodeStageDiskAsFilesystem(
return fmt.Errorf("failed to create staging directory: %w", err)
}

mountOptions := []string{}
mountOptions := []string{"grpid"}
if fsType == "ext4" {
mountOptions = append(mountOptions, "errors=remount-ro")
}
Expand All @@ -718,6 +741,14 @@ func (s *nodeService) nodeStageDiskAsFilesystem(
return fmt.Errorf("failed to format or mount filesystem: %w", err)
}

if mnt != nil && mnt.VolumeMountGroup != "" {
cmd := exec.Command("chown", "-R", ":"+mnt.VolumeMountGroup, req.StagingTargetPath)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to chown %s to %q: %w, output %q",
mnt.VolumeMountGroup, req.StagingTargetPath, err, out)
}
}

if err := os.Chmod(req.StagingTargetPath, targetPerm); err != nil {
return fmt.Errorf("failed to chmod target path: %w", err)
}
Expand Down
30 changes: 26 additions & 4 deletions cloud/blockstore/tools/csi_driver/internal/driver/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
"context"
"fmt"
"io/fs"
"log"
"os"
"os/exec"
"os/user"
"path/filepath"
"slices"
"strings"
"testing"

"github.com/container-storage-interface/spec/lib/go/csi"
Expand Down Expand Up @@ -439,12 +442,24 @@ func TestStagedPublishUnpublishLocalFilestoreForKubevirt(t *testing.T) {
func TestPublishUnpublishDiskForInfrakuber(t *testing.T) {
tempDir := t.TempDir()

groupId := ""
currentUser, err := user.Current()
require.NoError(t, err)
groups, err := currentUser.GroupIds()
require.NoError(t, err)
for _, group := range groups {
if group != "" && group != "0" {
groupId = group
}
}
log.Printf("groupId: %s", groupId)

nbsClient := mocks.NewNbsClientMock()
mounter := csimounter.NewMock()

ipcType := nbs.EClientIpcType_IPC_NBD
nbdDeviceFile := filepath.Join(tempDir, "dev", "nbd3")
err := os.MkdirAll(nbdDeviceFile, fs.FileMode(0755))
err = os.MkdirAll(nbdDeviceFile, fs.FileMode(0755))
require.NoError(t, err)

ctx := context.Background()
Expand Down Expand Up @@ -477,7 +492,11 @@ func TestPublishUnpublishDiskForInfrakuber(t *testing.T) {
)

volumeCapability := csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{},
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{
VolumeMountGroup: groupId,
},
},
AccessMode: &csi.VolumeCapability_AccessMode{
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
},
Expand Down Expand Up @@ -512,7 +531,7 @@ func TestPublishUnpublishDiskForInfrakuber(t *testing.T) {
mockCallIsMountPoint := mounter.On("IsMountPoint", stagingTargetPath).Return(false, nil)

mounter.On("FormatAndMount", nbdDeviceFile, stagingTargetPath, "ext4",
[]string{"errors=remount-ro"}).Return(nil)
[]string{"grpid", "errors=remount-ro"}).Return(nil)

_, err = nodeService.NodeStageVolume(ctx, &csi.NodeStageVolumeRequest{
VolumeId: diskId,
Expand Down Expand Up @@ -548,8 +567,11 @@ func TestPublishUnpublishDiskForInfrakuber(t *testing.T) {
assert.True(t, fileInfo.IsDir())
assert.Equal(t, fs.FileMode(0775), fileInfo.Mode().Perm())

_, err = exec.Command("ls", "-ldn", targetPath).CombinedOutput()
output, err := exec.Command("ls", "-ldn", targetPath).CombinedOutput()
assert.False(t, os.IsNotExist(err))
log.Printf("Target path: %s", output)
fields := strings.Fields(string(output))
assert.Equal(t, groupId, fields[3])

mockCallCleanupMountPoint := mounter.On("CleanupMountPoint", targetPath).Return(nil)

Expand Down

0 comments on commit 04b9add

Please sign in to comment.