Skip to content

Commit 09f8eb2

Browse files
committed
support blobfuse2 protocol in storageclass
fix fix typo fix ut add e2e test for blobfuse2 fix fuse2 e2e test fix fix e2e test support blobfuse2 inside driver mount fix ut make fuse2 as preview
1 parent 23f7ecf commit 09f8eb2

File tree

11 files changed

+97
-38
lines changed

11 files changed

+97
-38
lines changed

docs/driver-parameters.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ skuName | Azure storage account type (alias: `storageAccountType`) | `Standard_L
1212
location | Azure location | `eastus`, `westus`, etc. | No | if empty, driver will use the same location name as current k8s cluster
1313
resourceGroup | Azure resource group name | existing resource group name | No | if empty, driver will use the same resource group name as current k8s cluster
1414
storageAccount | specify Azure storage account name| STORAGE_ACCOUNT_NAME | - No for blobfuse mount </br> - Yes for NFSv3 mount | - For blobfuse mount: if empty, driver will find a suitable storage account that matches `skuName` in the same resource group; if a storage account name is provided, storage account must exist. </br> - For NFSv3 mount, storage account name must be provided
15-
protocol | specify blobfuse mount or NFSv3 mount | `fuse`, `nfs` | No | `fuse`
15+
protocol | specify blobfuse, blobfuse2 or NFSv3 mount (blobfuse2 is still in Preview) | `fuse`, `fuse2`, `nfs` | No | `fuse`
1616
containerName | specify the existing container(directory) name | existing container name | No | if empty, driver will create a new container name, starting with `pvc-fuse` for blobfuse or `pvc-nfs` for NFSv3
1717
containerNamePrefix | specify Azure storage directory prefix created by driver | can only contain lowercase letters, numbers, hyphens, and length should be less than 21 | No |
1818
server | specify Azure storage account server address | existing server address, e.g. `accountname.privatelink.blob.core.windows.net` | No | if empty, driver will use default `accountname.blob.core.windows.net` or other sovereign cloud account address
@@ -70,7 +70,7 @@ Name | Meaning | Available Value | Mandatory | Default value
7070
volumeAttributes.resourceGroup | Azure resource group name | existing resource group name | No | if empty, driver will use the same resource group name as current k8s cluster
7171
volumeAttributes.storageAccount | existing storage account name | existing storage account name | Yes |
7272
volumeAttributes.containerName | existing container name | existing container name | Yes |
73-
volumeAttributes.protocol | specify blobfuse mount or NFSv3 mount | `fuse`, `nfs` | No | `fuse`
73+
volumeAttributes.protocol | specify blobfuse, blobfuse2 or NFSv3 mount (blobfuse2 is still in Preview) | `fuse`, `fuse2`, `nfs` | No | `fuse`
7474
--- | **Following parameters are only for blobfuse** | --- | --- |
7575
volumeAttributes.secretName | secret name that stores storage account name and key(only applies for SMB) | | No |
7676
volumeAttributes.secretNamespace | secret namespace | `default`,`kube-system`, etc | No | pvc namespace

pkg/blob/blob.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ const (
8585
trueValue = "true"
8686
defaultSecretAccountName = "azurestorageaccountname"
8787
defaultSecretAccountKey = "azurestorageaccountkey"
88-
fuse = "fuse"
89-
nfs = "nfs"
88+
Fuse = "fuse"
89+
Fuse2 = "fuse2"
90+
NFS = "nfs"
9091
vnetResourceGroupField = "vnetresourcegroup"
9192
vnetNameField = "vnetname"
9293
subnetNameField = "subnetname"
@@ -124,7 +125,7 @@ const (
124125
)
125126

126127
var (
127-
supportedProtocolList = []string{fuse, nfs}
128+
supportedProtocolList = []string{Fuse, Fuse2, NFS}
128129
retriableErrors = []string{accountNotProvisioned, tooManyRequests, statusCodeNotFound, containerBeingDeletedDataplaneAPIError, containerBeingDeletedManagementAPIError, clientThrottled}
129130
)
130131

@@ -409,7 +410,7 @@ func (d *Driver) GetAuthEnv(ctx context.Context, volumeID, protocol string, attr
409410
}
410411
klog.V(2).Infof("volumeID(%s) authEnv: %s", volumeID, authEnv)
411412

412-
if protocol == nfs {
413+
if protocol == NFS {
413414
// nfs protocol does not need account key, return directly
414415
return rgName, accountName, accountKey, containerName, authEnv, err
415416
}

pkg/blob/blob_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ func TestGetAuthEnv(t *testing.T) {
585585
volumeID := "unique-volumeid"
586586
attrib[storageAccountField] = "accountname"
587587
attrib[containerNameField] = "containername"
588-
rg, accountName, accountkey, containerName, authEnv, err := d.GetAuthEnv(context.TODO(), volumeID, nfs, attrib, secret)
588+
rg, accountName, accountkey, containerName, authEnv, err := d.GetAuthEnv(context.TODO(), volumeID, NFS, attrib, secret)
589589
if err != nil {
590590
t.Errorf("actualErr: (%v), expect no error", err)
591591
}

pkg/blob/controllerserver.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
163163
}
164164

165165
if subsID != "" && subsID != d.cloud.SubscriptionID {
166-
if protocol == nfs {
166+
if protocol == NFS {
167167
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("NFS protocol is not supported in cross subscription(%s)", subsID))
168168
}
169169
if !storeAccountKey {
@@ -184,7 +184,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
184184
}
185185

186186
if protocol == "" {
187-
protocol = fuse
187+
protocol = Fuse
188188
}
189189
if !isSupportedProtocol(protocol) {
190190
return nil, status.Errorf(codes.InvalidArgument, "protocol(%s) is not supported, supported protocol list: %v", protocol, supportedProtocolList)
@@ -206,7 +206,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
206206
vnetResourceIDs []string
207207
enableNfsV3 *bool
208208
)
209-
if protocol == nfs {
209+
if protocol == NFS {
210210
isHnsEnabled = to.BoolPtr(true)
211211
enableNfsV3 = to.BoolPtr(true)
212212
// set VirtualNetworkResourceIDs for storage account firewall setting

pkg/blob/controllerserver_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func TestCreateVolume(t *testing.T) {
237237
controllerServiceCapability,
238238
}
239239
_, err := d.CreateVolume(context.Background(), req)
240-
expectedErr := status.Errorf(codes.InvalidArgument, "protocol(unit-test) is not supported, supported protocol list: [fuse nfs]")
240+
expectedErr := status.Errorf(codes.InvalidArgument, "protocol(unit-test) is not supported, supported protocol list: [fuse fuse2 nfs]")
241241
if !reflect.DeepEqual(err, expectedErr) {
242242
t.Errorf("actualErr: (%v), expectedErr: (%v)", err, expectedErr)
243243
}

pkg/blob/nodeserver.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (d *Driver) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolu
140140
return &csi.NodePublishVolumeResponse{}, nil
141141
}
142142

143-
func (d *Driver) mountBlobfuseWithProxy(args string, authEnv []string) (string, error) {
143+
func (d *Driver) mountBlobfuseWithProxy(args string, protocol string, authEnv []string) (string, error) {
144144
klog.V(2).Infof("mouting using blobfuse proxy")
145145
var resp *mount_azure_blob.MountAzureBlobResponse
146146
var output string
@@ -152,6 +152,7 @@ func (d *Driver) mountBlobfuseWithProxy(args string, authEnv []string) (string,
152152
mountClient := NewMountClient(conn)
153153
mountreq := mount_azure_blob.MountAzureBlobRequest{
154154
MountArgs: args,
155+
Protocol: protocol,
155156
AuthEnv: authEnv,
156157
}
157158
klog.V(2).Infof("calling BlobfuseProxy: MountAzureBlob function")
@@ -164,11 +165,23 @@ func (d *Driver) mountBlobfuseWithProxy(args string, authEnv []string) (string,
164165
return output, err
165166
}
166167

167-
func (d *Driver) mountBlobfuseInsideDriver(args string, authEnv []string) (string, error) {
168+
func (d *Driver) mountBlobfuseInsideDriver(args string, protocol string, authEnv []string) (string, error) {
169+
var cmd *exec.Cmd
170+
168171
klog.V(2).Infof("mounting blobfuse inside driver")
169-
cmd := exec.Command("blobfuse", strings.Split(args, " ")...)
172+
if protocol == Fuse2 {
173+
klog.V(2).Infof("using blobfuse V2 to mount")
174+
args = "mount " + args
175+
cmd = exec.Command("blobfuse2", strings.Split(args, " ")...)
176+
} else {
177+
klog.V(2).Infof("using blobfuse V1 to mount")
178+
cmd = exec.Command("blobfuse", strings.Split(args, " ")...)
179+
}
180+
170181
cmd.Env = append(os.Environ(), authEnv...)
171182
output, err := cmd.CombinedOutput()
183+
klog.V(2).Infof("mount output: %s\n", string(output))
184+
172185
return string(output), err
173186
}
174187

@@ -290,14 +303,14 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
290303
serverAddress = fmt.Sprintf("%s.blob.%s", accountName, storageEndpointSuffix)
291304
}
292305

293-
if protocol == nfs {
306+
if protocol == NFS {
294307
klog.V(2).Infof("target %v\nprotocol %v\n\nvolumeId %v\ncontext %v\nmountflags %v\nserverAddress %v",
295308
targetPath, protocol, volumeID, attrib, mountFlags, serverAddress)
296309

297310
source := fmt.Sprintf("%s:/%s/%s", serverAddress, accountName, containerName)
298311
mountOptions := util.JoinMountOptions(mountFlags, []string{"sec=sys,vers=3,nolock"})
299312
if err := wait.PollImmediate(1*time.Second, 2*time.Minute, func() (bool, error) {
300-
return true, d.mounter.MountSensitive(source, targetPath, nfs, mountOptions, []string{})
313+
return true, d.mounter.MountSensitive(source, targetPath, NFS, mountOptions, []string{})
301314
}); err != nil {
302315
return nil, status.Error(codes.Internal, fmt.Sprintf("volume(%s) mount %q on %q failed with %v", volumeID, source, targetPath, err))
303316
}
@@ -348,9 +361,9 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
348361

349362
var output string
350363
if d.enableBlobfuseProxy {
351-
output, err = d.mountBlobfuseWithProxy(args, authEnv)
364+
output, err = d.mountBlobfuseWithProxy(args, protocol, authEnv)
352365
} else {
353-
output, err = d.mountBlobfuseInsideDriver(args, authEnv)
366+
output, err = d.mountBlobfuseInsideDriver(args, protocol, authEnv)
354367
}
355368

356369
if err != nil {

pkg/blob/nodeserver_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ func TestMountBlobfuseWithProxy(t *testing.T) {
741741
args := "--tmp-path /tmp"
742742
authEnv := []string{"username=blob", "authkey=blob"}
743743
d := NewFakeDriver()
744-
_, err := d.mountBlobfuseWithProxy(args, authEnv)
744+
_, err := d.mountBlobfuseWithProxy(args, "fuse", authEnv)
745745
// should be context.deadlineExceededError{} error
746746
assert.NotNil(t, err)
747747
}
@@ -750,7 +750,7 @@ func TestMountBlobfuseInsideDriver(t *testing.T) {
750750
args := "--tmp-path /tmp"
751751
authEnv := []string{"username=blob", "authkey=blob"}
752752
d := NewFakeDriver()
753-
_, err := d.mountBlobfuseInsideDriver(args, authEnv)
753+
_, err := d.mountBlobfuseInsideDriver(args, Fuse, authEnv)
754754
// the error should be of type exec.ExitError
755755
assert.NotNil(t, err)
756756
}

pkg/blobfuse-proxy/pb/azure_blob_mount.pb.go

Lines changed: 22 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/blobfuse-proxy/proto/azure_blob_mount.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ option go_package = ".;pb";
55
message MountAzureBlobRequest {
66
string mountArgs = 1;
77
repeated string authEnv = 2;
8+
string protocol = 3;
89
}
910

1011
message MountAzureBlobResponse {

pkg/blobfuse-proxy/server/server.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"google.golang.org/grpc"
2828
"k8s.io/klog/v2"
29+
"sigs.k8s.io/blob-csi-driver/pkg/blob"
2930
mount_azure_blob "sigs.k8s.io/blob-csi-driver/pkg/blobfuse-proxy/pb"
3031
"sigs.k8s.io/blob-csi-driver/pkg/util"
3132
)
@@ -62,16 +63,18 @@ func (server *MountServer) MountAzureBlob(ctx context.Context,
6263

6364
args := req.GetMountArgs()
6465
authEnv := req.GetAuthEnv()
65-
klog.V(2).Infof("received mount request: Mounting with args %v \n", args)
66+
protocol := req.GetProtocol()
67+
klog.V(2).Infof("received mount request: Protocol: %s, server default blobfuseVersion: %v, Mounting with args %v \n", protocol, server.blobfuseVersion, args)
6668

6769
var cmd *exec.Cmd
6870
var result mount_azure_blob.MountAzureBlobResponse
69-
switch server.blobfuseVersion {
70-
case BlobfuseV1:
71-
cmd = exec.Command("blobfuse", strings.Split(args, " ")...)
72-
case BlobfuseV2:
71+
if protocol == blob.Fuse2 || server.blobfuseVersion == BlobfuseV2 {
72+
klog.V(2).Infof("using blobfuse V2 to mount")
7373
args = "mount " + args
7474
cmd = exec.Command("blobfuse2", strings.Split(args, " ")...)
75+
} else {
76+
klog.V(2).Infof("using blobfuse V1 to mount")
77+
cmd = exec.Command("blobfuse", strings.Split(args, " ")...)
7578
}
7679

7780
cmd.Env = append(cmd.Env, authEnv...)
@@ -111,9 +114,10 @@ func getBlobfuseVersion() BlobfuseVersion {
111114
}
112115

113116
if osinfo.Distro == "Ubuntu" && osinfo.Version >= "22.04" {
114-
klog.V(2).Info("proxy using blobfuse V2 for mounting")
117+
klog.V(2).Info("proxy default using blobfuse V2 for mounting")
115118
return BlobfuseV2
116119
}
117120

121+
klog.V(2).Info("proxy default using blobfuse V1 for mounting")
118122
return BlobfuseV1
119123
}

0 commit comments

Comments
 (0)