From 7999704f2b34e0cb8d34215cd14612dcbbc42809 Mon Sep 17 00:00:00 2001 From: "mittachaitu@gmail.com" Date: Mon, 10 Nov 2025 15:29:27 +0000 Subject: [PATCH 1/5] chore: add telemetry as part of mount options for blobfuse mounts This commit adds telemetry=azpartner-aks/ as mount options for blobfuse mounts Signed-off-by: mittachaitu@gmail.com --- pkg/blob/nodeserver.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/blob/nodeserver.go b/pkg/blob/nodeserver.go index e6ea28e01..901c18095 100644 --- a/pkg/blob/nodeserver.go +++ b/pkg/blob/nodeserver.go @@ -409,6 +409,7 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe } // Get mountOptions that the volume will be formatted and mounted with + mountFlags = util.JoinMountOptions(mountFlags, []string{fmt.Sprintf("--telemetry=azpartner-aks/%s", d.Version)}) mountOptions := mountFlags if ephemeralVol { mountOptions = util.JoinMountOptions(mountOptions, strings.Split(ephemeralVolMountOptions, ",")) From 2b4e9c86152b613361939f5ddb811fcb472050d0 Mon Sep 17 00:00:00 2001 From: "mittachaitu@gmail.com" Date: Mon, 17 Nov 2025 04:51:40 +0000 Subject: [PATCH 2/5] fix: add telemetry to the flag only if protocol is fuse2 Signed-off-by: mittachaitu@gmail.com --- pkg/blob/nodeserver.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/blob/nodeserver.go b/pkg/blob/nodeserver.go index 901c18095..5ae3ac65f 100644 --- a/pkg/blob/nodeserver.go +++ b/pkg/blob/nodeserver.go @@ -409,7 +409,10 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe } // Get mountOptions that the volume will be formatted and mounted with - mountFlags = util.JoinMountOptions(mountFlags, []string{fmt.Sprintf("--telemetry=azpartner-aks/%s", d.Version)}) + if protocol == Fuse2 { + // Adding telemetry tag to know that blob is been mounted through AKS + mountFlags = util.JoinMountOptions(mountFlags, []string{fmt.Sprintf("--telemetry=azpartner-aks/%s", d.Version)}) + } mountOptions := mountFlags if ephemeralVol { mountOptions = util.JoinMountOptions(mountOptions, strings.Split(ephemeralVolMountOptions, ",")) From 8d9b9fd48a9a7592287b561c62262f2a5d40e58e Mon Sep 17 00:00:00 2001 From: "mittachaitu@gmail.com" Date: Wed, 19 Nov 2025 14:31:48 +0000 Subject: [PATCH 3/5] fix: move the tag adding logic inside blobfuse-proxy code This commit moves the logic to add tag to blobfuse-proxy service. If user specifies --telemetry=tire1 as mount option then add azpartner-aks/v1.28.0 value as comma separated value to user provided version (--telemetry=azpartner-aks/v1.28.0,tire1) Signed-off-by: mittachaitu@gmail.com --- Makefile | 2 +- pkg/blob/nodeserver.go | 4 ---- pkg/blobfuse-proxy/server/server.go | 19 ++++++++++++++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 8de5fe537..85dd65d5b 100644 --- a/Makefile +++ b/Makefile @@ -178,4 +178,4 @@ delete-metrics-svc: .PHONY: blobfuse-proxy blobfuse-proxy: - CGO_ENABLED=0 GOOS=linux GOARCH=$(ARCH) go build -mod vendor -ldflags="-s -w" -o _output/${ARCH}/blobfuse-proxy ./pkg/blobfuse-proxy + CGO_ENABLED=0 GOOS=linux GOARCH=$(ARCH) go build -mod vendor -ldflags="-s -w -X ${PKG}/pkg/blobfuse-proxy/server.driverVersion=${IMAGE_VERSION}" -o _output/${ARCH}/blobfuse-proxy ./pkg/blobfuse-proxy diff --git a/pkg/blob/nodeserver.go b/pkg/blob/nodeserver.go index 5ae3ac65f..e6ea28e01 100644 --- a/pkg/blob/nodeserver.go +++ b/pkg/blob/nodeserver.go @@ -409,10 +409,6 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe } // Get mountOptions that the volume will be formatted and mounted with - if protocol == Fuse2 { - // Adding telemetry tag to know that blob is been mounted through AKS - mountFlags = util.JoinMountOptions(mountFlags, []string{fmt.Sprintf("--telemetry=azpartner-aks/%s", d.Version)}) - } mountOptions := mountFlags if ephemeralVol { mountOptions = util.JoinMountOptions(mountOptions, strings.Split(ephemeralVolMountOptions, ",")) diff --git a/pkg/blobfuse-proxy/server/server.go b/pkg/blobfuse-proxy/server/server.go index 9730c83dd..db72923e4 100644 --- a/pkg/blobfuse-proxy/server/server.go +++ b/pkg/blobfuse-proxy/server/server.go @@ -34,7 +34,8 @@ import ( ) var ( - mutex sync.Mutex + mutex sync.Mutex + driverVersion string ) type BlobfuseVersion int @@ -71,6 +72,7 @@ func (server *MountServer) MountAzureBlob(_ context.Context, var cmd *exec.Cmd var result mount_azure_blob.MountAzureBlobResponse if protocol == blob.Fuse2 || server.blobfuseVersion == BlobfuseV2 { + telemetryTag := "azpartner-aks/" + driverVersion args = "mount " + args // add this arg for blobfuse2 to solve the issue: // https://github.com/Azure/azure-storage-fuse/issues/1015 @@ -82,6 +84,21 @@ func (server *MountServer) MountAzureBlob(_ context.Context, klog.V(2).Infof("append --disable-version-check to mount args") args = args + " " + "--disable-version-check=true" } + // Adding telemetry tag to know that blob is been mounted through AKS CSI Driver + if !strings.Contains(args, "--telemetry") { + klog.V(2).Infof("append --telemetry=%s to mount args", telemetryTag) + args = args + " " + "--telemetry=" + telemetryTag + } else { + // If telemetry flag is already present, check for aks tag if not present + // then user might have their own telemetry tag append aks tag to it + if !strings.Contains(args, "azpartner-aks") { + splitedArgs := strings.Split(args, "--telemetry=") + if len(splitedArgs) == 2 { + args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] + } + klog.V(2).Infof("updated --telemetry tag in mount args: %s", args) + } + } args = util.TrimDuplicatedSpace(args) klog.V(2).Infof("mount with v2, protocol: %s, args: %s", protocol, args) cmd = exec.Command("blobfuse2", strings.Split(args, " ")...) From 5c45e5b30429f4fca5c7bdd5e9a5ade63a51465f Mon Sep 17 00:00:00 2001 From: mittachaitu Date: Wed, 26 Nov 2025 09:46:34 +0000 Subject: [PATCH 4/5] fix: update telemtery tag and add Unit test for telemetry parsing Signed-off-by: mittachaitu --- pkg/blobfuse-proxy/server/server.go | 13 +++- pkg/blobfuse-proxy/server/server_test.go | 94 ++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/pkg/blobfuse-proxy/server/server.go b/pkg/blobfuse-proxy/server/server.go index db72923e4..ce1260a65 100644 --- a/pkg/blobfuse-proxy/server/server.go +++ b/pkg/blobfuse-proxy/server/server.go @@ -38,6 +38,9 @@ var ( driverVersion string ) +// telemetryTagPrefix is used to identify the mounts done via blobcsi driver +const telemetryTagPrefix = "blobpartner-csi/" + type BlobfuseVersion int const ( @@ -48,12 +51,14 @@ const ( type MountServer struct { blobfuseVersion BlobfuseVersion mount_azure_blob.UnimplementedMountServiceServer + exec func(name string, arg ...string) *exec.Cmd } // NewMountServer returns a new Mountserver func NewMountServiceServer() *MountServer { mountServer := &MountServer{} mountServer.blobfuseVersion = getBlobfuseVersion() + mountServer.exec = exec.Command return mountServer } @@ -72,7 +77,7 @@ func (server *MountServer) MountAzureBlob(_ context.Context, var cmd *exec.Cmd var result mount_azure_blob.MountAzureBlobResponse if protocol == blob.Fuse2 || server.blobfuseVersion == BlobfuseV2 { - telemetryTag := "azpartner-aks/" + driverVersion + telemetryTag := telemetryTagPrefix + driverVersion args = "mount " + args // add this arg for blobfuse2 to solve the issue: // https://github.com/Azure/azure-storage-fuse/issues/1015 @@ -91,7 +96,7 @@ func (server *MountServer) MountAzureBlob(_ context.Context, } else { // If telemetry flag is already present, check for aks tag if not present // then user might have their own telemetry tag append aks tag to it - if !strings.Contains(args, "azpartner-aks") { + if !strings.Contains(args, telemetryTagPrefix) { splitedArgs := strings.Split(args, "--telemetry=") if len(splitedArgs) == 2 { args = splitedArgs[0] + " --telemetry=" + telemetryTag + "," + splitedArgs[1] @@ -101,11 +106,11 @@ func (server *MountServer) MountAzureBlob(_ context.Context, } args = util.TrimDuplicatedSpace(args) klog.V(2).Infof("mount with v2, protocol: %s, args: %s", protocol, args) - cmd = exec.Command("blobfuse2", strings.Split(args, " ")...) + cmd = server.exec("blobfuse2", strings.Split(args, " ")...) } else { args = util.TrimDuplicatedSpace(args) klog.V(2).Infof("mount with v1, protocol: %s, args: %s", protocol, args) - cmd = exec.Command("blobfuse", strings.Split(args, " ")...) + cmd = server.exec("blobfuse", strings.Split(args, " ")...) } cmd.Env = append(os.Environ(), authEnv...) diff --git a/pkg/blobfuse-proxy/server/server_test.go b/pkg/blobfuse-proxy/server/server_test.go index f96e18229..d447dfab0 100644 --- a/pkg/blobfuse-proxy/server/server_test.go +++ b/pkg/blobfuse-proxy/server/server_test.go @@ -18,6 +18,8 @@ package server import ( "context" + "os/exec" + "strings" "testing" "github.com/stretchr/testify/require" @@ -64,3 +66,95 @@ func TestServerMountAzureBlob(t *testing.T) { }) } } + +// fakeExecCommand is used to mock exec.Command for testing, it returns list of args +func fakeExecCommandEchoArgs(command string, args ...string) *exec.Cmd { + return exec.Command("echo", append([]string{"-n"}, args...)...) +} + +func TestServerMountAzureBlob_Telemetry(t *testing.T) { + driverVersion = "fake-version" + t.Parallel() + testCases := []struct { + name string + args string + code codes.Code + mountServer MountServer + areValidTelemetryArgs func(cmdArgs string) bool + }{ + { + name: "mount_with_telemetry_tag_blobfusev2", + args: "--account-name=testaccount --container-name=testcontainer --telemetry=volume1-app1 --tmp-path=/tmp/blobfuse-tmp", + mountServer: MountServer{ + blobfuseVersion: BlobfuseV2, + exec: fakeExecCommandEchoArgs, + }, + code: codes.OK, + areValidTelemetryArgs: func(cmdArgs string) bool { + expectedTelemetryArg := "--telemetry=" + telemetryTagPrefix + driverVersion + ",volume1-app1" + return strings.Contains(cmdArgs, expectedTelemetryArg) + }, + }, + { + name: "mount_without_telemetry_tag_blobfusev2", + args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp", + mountServer: MountServer{ + blobfuseVersion: BlobfuseV2, + exec: fakeExecCommandEchoArgs, + }, + code: codes.OK, + areValidTelemetryArgs: func(cmdArgs string) bool { + expectedTelemetryArg := "--telemetry=" + telemetryTagPrefix + driverVersion + return strings.Contains(cmdArgs, expectedTelemetryArg) + }, + }, + { + name: "mount_with_same_telemetry_tag_blobfusev2", + args: "--account-name=testaccount --container-name=testcontainer --telemetry=" + telemetryTagPrefix + driverVersion, + mountServer: MountServer{ + blobfuseVersion: BlobfuseV2, + exec: fakeExecCommandEchoArgs, + }, + code: codes.OK, + areValidTelemetryArgs: func(cmdArgs string) bool { + // Argument order should remain unchanged + return strings.Contains(cmdArgs, "--account-name=testaccount --container-name=testcontainer --telemetry="+telemetryTagPrefix+driverVersion) + }, + }, + { + name: "mount_with_blobfusev1", + args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp", + mountServer: MountServer{ + blobfuseVersion: BlobfuseV1, + exec: fakeExecCommandEchoArgs, + }, + code: codes.OK, + areValidTelemetryArgs: func(cmdArgs string) bool { + // No telemetry arg should be added for blobfuse v1 + return !strings.Contains(cmdArgs, "--telemetry=") && cmdArgs == "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp" + }, + }, + } + + for i := range testCases { + tc := testCases[i] + + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + req := mount_azure_blob.MountAzureBlobRequest{ + MountArgs: tc.args, + AuthEnv: []string{}, + } + res, err := tc.mountServer.MountAzureBlob(context.Background(), &req) + if tc.code == codes.OK { + require.NoError(t, err) + require.NotNil(t, res) + require.True(t, tc.areValidTelemetryArgs(res.Output), "telemetry args are not valid in command args: %s", res.Output) + } else { + require.Error(t, err) + require.NotNil(t, res) + } + }) + } +} From 618aac5daec7b92c64a0b37e0a02b0a78b502e18 Mon Sep 17 00:00:00 2001 From: mittachaitu Date: Thu, 27 Nov 2025 07:13:05 +0000 Subject: [PATCH 5/5] fix: fix test case linting issue Signed-off-by: mittachaitu --- pkg/blobfuse-proxy/server/server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/blobfuse-proxy/server/server_test.go b/pkg/blobfuse-proxy/server/server_test.go index d447dfab0..37202979c 100644 --- a/pkg/blobfuse-proxy/server/server_test.go +++ b/pkg/blobfuse-proxy/server/server_test.go @@ -68,7 +68,7 @@ func TestServerMountAzureBlob(t *testing.T) { } // fakeExecCommand is used to mock exec.Command for testing, it returns list of args -func fakeExecCommandEchoArgs(command string, args ...string) *exec.Cmd { +func fakeExecCommandEchoArgs(_ string, args ...string) *exec.Cmd { return exec.Command("echo", append([]string{"-n"}, args...)...) }