Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion charts/latest/csi-driver-nfs/templates/csi-nfs-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
template:
metadata:
{{ include "nfs.labels" . | indent 6 }}
app: {{ .Values.node.name }}
app: {{ .Values.node.name }}
spec:
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
Expand Down Expand Up @@ -125,6 +125,8 @@ spec:
- name: pods-mount-dir
mountPath: {{ .Values.kubeletDir }}/pods
mountPropagation: "Bidirectional"
- name: kata-containers
mountPath: /run/kata-containers/shared/direct-volumes/
{{- if .Values.feature.propagateHostMountOptions }}
- name: host-nfsmount-conf
mountPath: /etc/nfsmount.conf
Expand All @@ -141,6 +143,10 @@ spec:
hostPath:
path: {{ .Values.kubeletDir }}/pods
type: Directory
- name: kata-containers
hostPath:
path: /run/kata-containers/shared/direct-volumes/
type: Directory
- hostPath:
path: {{ .Values.kubeletDir }}/plugins_registry
type: Directory
Expand Down
6 changes: 3 additions & 3 deletions charts/latest/csi-driver-nfs/values.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
customLabels: {}
image:
nfs:
repository: gcr.io/k8s-staging-sig-storage/nfsplugin
tag: canary
pullPolicy: IfNotPresent
repository: taenyang/nfsplugin
tag: latest
pullPolicy: Always
csiProvisioner:
repository: registry.k8s.io/sig-storage/csi-provisioner
tag: v3.6.1
Expand Down
1 change: 1 addition & 0 deletions pkg/nfs/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
case pvcNamespaceKey:
case pvcNameKey:
case pvNameKey:
case directVolume:
// no op
case mountPermissionsField:
if v != "" {
Expand Down
2 changes: 2 additions & 0 deletions pkg/nfs/nfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ const (
pvcNameMetadata = "${pvc.metadata.name}"
pvcNamespaceMetadata = "${pvc.metadata.namespace}"
pvNameMetadata = "${pv.metadata.name}"
directVolume = "directvolume"
fsType = "nfs"
)

func NewDriver(options *DriverOptions) *Driver {
Expand Down
14 changes: 14 additions & 0 deletions pkg/nfs/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/volume"
mount "k8s.io/mount-utils"

"github.com/kubernetes-csi/csi-driver-nfs/pkg/utils"
)

// NodeServer driver
Expand Down Expand Up @@ -86,9 +88,18 @@ func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("invalid mountPermissions %s", v))
}
}
case directVolume:
subDirReplaceMap[directVolume] = v
}
}

if subDirReplaceMap[directVolume] == "true" {
if err := utils.AddDirectVolume(targetPath, server, baseDir, fsType); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &csi.NodePublishVolumeResponse{}, nil
}

if server == "" {
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("%v is a required parameter", paramServer))
}
Expand Down Expand Up @@ -156,6 +167,9 @@ func (ns *NodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu

klog.V(2).Infof("NodeUnpublishVolume: unmounting volume %s on %s", volumeID, targetPath)
var err error
if err = utils.Remove(targetPath); err != nil {
klog.V(2).ErrorS(err, "NodeUnpublishVolume Error: unmounting volume %s on %s", volumeID, targetPath)
}
extensiveMountPointCheck := true
forceUnmounter, ok := ns.mounter.(mount.MounterForceUnmounter)
if ok {
Expand Down
100 changes: 100 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package utils

import (
b64 "encoding/base64"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/klog/v2"
)

const (
mountInfoFileName = "mountInfo.json"
nfsDir = "nfs"
)

// FSGroupChangePolicy holds policies that will be used for applying fsGroup to a volume.
// This type and the allowed values are tracking the PodFSGroupChangePolicy defined in
// https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/core/v1/types.go
// It is up to the client using the direct-assigned volume feature (e.g. CSI drivers) to determine
// the optimal setting for this change policy (i.e. from Pod spec or assuming volume ownership
// based on the storage offering).
type FSGroupChangePolicy string

var kataDirectVolumeRootPath = "/run/kata-containers/shared/direct-volumes"

// MountInfo contains the information needed by Kata to consume a host block device and mount it as a filesystem inside the guest VM.
type MountInfo struct {
// The type of the volume (ie. block)
VolumeType string `json:"volume-type"`
// The device backing the volume.
Device string `json:"device"`
// The filesystem type to be mounted on the volume.
FsType string `json:"fstype"`
// Additional metadata to pass to the agent regarding this volume.
Metadata map[string]string `json:"metadata,omitempty"`
// Additional mount options.
Options []string `json:"options,omitempty"`
}

// Add writes the mount info of a direct volume into a filesystem path known to Kata Container.
func Add(volumePath, mountInfo string) error {
volumeDir := filepath.Join(kataDirectVolumeRootPath, nfsDir, b64.URLEncoding.EncodeToString([]byte(volumePath)))
stat, err := os.Stat(volumeDir)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return err
}
if err := os.MkdirAll(volumeDir, 0700); err != nil {
return err
}
}
if stat != nil && !stat.IsDir() {
return fmt.Errorf("%s should be a directory", volumeDir)
}

var deserialized MountInfo
if err := json.Unmarshal([]byte(mountInfo), &deserialized); err != nil {
return err
}

return os.WriteFile(filepath.Join(volumeDir, mountInfoFileName), []byte(mountInfo), 0600)
}

// Remove deletes the direct volume path including all the files inside it.
func Remove(volumePath string) error {
return os.RemoveAll(filepath.Join(kataDirectVolumeRootPath, nfsDir, b64.URLEncoding.EncodeToString([]byte(volumePath))))
}

func AddDirectVolume(volumePath, server, baseDir, fsType string) error {
mountInfo := struct {
VolumeType string `json:"volume-type"`
Device string `json:"device"`
FsType string `json:"fstype"`
Metadata map[string]string `json:"metadata,omitempty"`
Options []string `json:"options,omitempty"`
}{
VolumeType: "fs",
FsType: fsType,
Options: []string{server + ":" + baseDir},
}

mi, err := json.Marshal(mountInfo)
if err != nil {
klog.Errorf("addDirectVolume - json.Marshal failed: ", err.Error())
return status.Errorf(codes.Internal, "json.Marshal failed: %s", err.Error())
}

if err := Add(volumePath, string(mi)); err != nil {
klog.Errorf("addDirectVolume - add direct volume failed: ", err.Error())
return status.Errorf(codes.Internal, "add direct volume failed: %s", err.Error())
}

klog.Infof("add direct volume done: %s %s", volumePath, string(mi))
return nil
}