Skip to content

Commit e16d590

Browse files
authored
Merge pull request #1060 from uriel-guzman/remove-hns-annotation
Delete HNS annotation from PV.
2 parents 609b02f + 3aa7e0b commit e16d590

File tree

7 files changed

+21
-87
lines changed

7 files changed

+21
-87
lines changed

examples/gcsfuse-profiles/pv-pvc-deployment.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ metadata:
2222
# gke-gcsfuse/bucket-scan-status: "override" # Required for "override": Will bypass the scanner with custom results.
2323
# gke-gcsfuse/bucket-scan-num-objects: "42" # Required for "override": Total number of objects in the bucket / directory.
2424
# gke-gcsfuse/bucket-scan-total-size-bytes: "123456789" # Required for "override": Total size in bytes of the bucket / directory.
25-
# gke-gcsfuse/bucket-scan-hns-enabled: "true" # Required for "override": "true" or "false" if HNS is enabled.
2625
spec:
2726
accessModes:
2827
- ReadWriteMany

pkg/profiles/recommender_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ var (
7070
"gke-gcsfuse/bucket-scan-num-objects": "1000",
7171
"gke-gcsfuse/bucket-scan-total-size-bytes": "1000000000",
7272
"gke-gcsfuse/bucket-scan-last-updated-time": "2025-10-08T22:17:48Z",
73-
"gke-gcsfuse/bucket-scan-hns-enabled": "true",
7473
},
7574
SCName: "gcsfusecsi-training",
7675
}

pkg/profiles/scanner.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ type bucketInfo struct {
182182
onlyDirSpecified bool
183183
numObjects int64
184184
totalSizeBytes int64
185-
isHNSEnabled bool
186185
isOverride bool
187186
}
188187

@@ -738,7 +737,7 @@ func (s *Scanner) bypassScanForOverride(ctx context.Context, pv *v1.PersistentVo
738737

739738
// The status annotation is already "override", but we patch it here along with
740739
// the timestamp to mark the operation as complete and update the in-memory map.
741-
s.eventRecorder.Eventf(pv, v1.EventTypeNormal, reasonScanOperationSucceeded, "Override mode detected for PV %q. Bypassing scan and using user-provided values: %d objects, %d bytes, HNS enabled: %t", pv.Name, bucketI.numObjects, bucketI.totalSizeBytes, bucketI.isHNSEnabled)
740+
s.eventRecorder.Eventf(pv, v1.EventTypeNormal, reasonScanOperationSucceeded, "Override mode detected for PV %q. Bypassing scan and using user-provided values: %d objects, %d bytes: %t", pv.Name, bucketI.numObjects, bucketI.totalSizeBytes)
742741
if patchErr := s.updatePVScanResult(ctx, pv, bucketI, profilesutil.ScanOverride); patchErr != nil {
743742
return patchErr
744743
}
@@ -956,7 +955,7 @@ func defaultBucketAttrs(ctx context.Context, gcsClient *storage.Client, bucketNa
956955
}
957956

958957
// defaultScanBucket performs a bucket scan.
959-
// It collects the number of objects, total size, and HNS status.
958+
// It collects the number of objects, total size.
960959
// This function respects the provided context and the scanTimeout.
961960
// It returns partial results if the timeout is reached (context.DeadlineExceeded).
962961
//
@@ -967,15 +966,13 @@ func defaultBucketAttrs(ctx context.Context, gcsClient *storage.Client, bucketNa
967966
//
968967
// Optionally, GCS Dataflux client scanning on the entire bucket can be forced by specifying `only-dir=/`
969968
func defaultScanBucket(s *Scanner, ctx context.Context, bucketI *bucketInfo, scanTimeout time.Duration, pv *v1.PersistentVolume) error {
970-
// Get bucket attributes to determine HNS status and project number.
969+
// Get bucket attributes to determine project number.
971970
// Use the parent context for this, as it's a quick metadata call.
972971
bucketAttrs, err := bucketAttrs(ctx, s.gcsClient, bucketI.name)
973972
if err != nil {
974973
return err
975974
}
976-
bucketI.isHNSEnabled = bucketAttrs.HierarchicalNamespace != nil && bucketAttrs.HierarchicalNamespace.Enabled
977975
bucketI.projectNumber = fmt.Sprint(bucketAttrs.ProjectNumber)
978-
klog.Infof("Bucket %q HNS enabled: %t", bucketI.name, bucketI.isHNSEnabled)
979976

980977
if bucketI.onlyDirSpecified {
981978
klog.Infof("'only-dir' is set for bucket %q, dir %q. Scanning with Dataflux.", bucketI.name, bucketI.dir)
@@ -1174,7 +1171,7 @@ func (s *Scanner) patchPVAnnotations(ctx context.Context, pvName string, annotat
11741171
}
11751172

11761173
// updatePVScanResult updates the PV annotations with the results of a bucket scan.
1177-
// It sets the status, number of objects, total size, HNS status, and last updated time.
1174+
// It sets the status, number of objects, total size, and last updated time.
11781175
// It also updates the in-memory lastSuccessfulScan map.
11791176
func (s *Scanner) updatePVScanResult(ctx context.Context, pv *v1.PersistentVolume, bucketI *bucketInfo, status string) error {
11801177
currentTime := timeNow()
@@ -1183,7 +1180,6 @@ func (s *Scanner) updatePVScanResult(ctx context.Context, pv *v1.PersistentVolum
11831180
profilesutil.AnnotationNumObjects: int64Ptr(bucketI.numObjects),
11841181
profilesutil.AnnotationTotalSize: int64Ptr(bucketI.totalSizeBytes),
11851182
profilesutil.AnnotationLastUpdatedTime: stringPtr(currentTime.UTC().Format(time.RFC3339)),
1186-
profilesutil.AnnotationHNSEnabled: boolPtr(bucketI.isHNSEnabled),
11871183
}
11881184
klog.Infof("Updating PV %q with scan result: %+v, status: %q", pv.Name, bucketI, status)
11891185
err := s.patchPVAnnotations(ctx, pv.Name, annotationsToUpdate)
@@ -1254,14 +1250,13 @@ func (s *Scanner) checkPVRelevance(pv *v1.PersistentVolume, sc *storagev1.Storag
12541250
// Handle the override annotation, if set.
12551251
if bucketStatus, ok := pv.Annotations[profilesutil.AnnotationStatus]; ok && bucketStatus == profilesutil.ScanOverride {
12561252
// Enforce required annotations for override mode and validate formats.
1257-
numObjects, totalSizeBytes, isHNSEnabled, err := profilesutil.ParseOverrideStatus(pv)
1253+
numObjects, totalSizeBytes, err := profilesutil.ParseOverrideStatus(pv)
12581254
if err != nil {
12591255
return nil, false, fmt.Errorf("failed to validate arguments for PV %q with override mode: %v", pv.Name, err)
12601256
}
12611257
overrideInfo := &bucketInfo{
12621258
numObjects: numObjects,
12631259
totalSizeBytes: totalSizeBytes,
1264-
isHNSEnabled: isHNSEnabled,
12651260
}
12661261

12671262
klog.Infof("PV %q: Override mode detected. Bypassing scan.", pv.Name)
@@ -1301,7 +1296,6 @@ func (s *Scanner) checkPVRelevance(pv *v1.PersistentVolume, sc *storagev1.Storag
13011296
profilesutil.AnnotationStatus,
13021297
profilesutil.AnnotationNumObjects,
13031298
profilesutil.AnnotationTotalSize,
1304-
profilesutil.AnnotationHNSEnabled,
13051299
}); len(annotationsUsed) > 0 {
13061300
return nil, false, status.Errorf(codes.InvalidArgument, "scanner annotations for PV %q found in non-override mode: %+v", pv.Name, annotationsUsed)
13071301
}

pkg/profiles/scanner_test.go

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ var (
7878
name: testBucketName,
7979
numObjects: 1234,
8080
totalSizeBytes: 567890,
81-
isHNSEnabled: true,
8281
}
8382
origbucketAttrs = bucketAttrs
8483
origScanBucketWithMetrics = scanBucketWithMetrics
@@ -153,7 +152,6 @@ func (f *fakeScanBucketImplFunc) Scan(scanner *Scanner, ctx context.Context, buc
153152
if f.err == nil && f.bucketI != nil {
154153
bucketI.numObjects = f.bucketI.numObjects
155154
bucketI.totalSizeBytes = f.bucketI.totalSizeBytes
156-
bucketI.isHNSEnabled = f.bucketI.isHNSEnabled
157155
}
158156
return f.err
159157
}
@@ -361,7 +359,6 @@ func TestCheckPVRelevance(t *testing.T) {
361359
putil.AnnotationStatus: putil.ScanOverride,
362360
putil.AnnotationNumObjects: "1000",
363361
putil.AnnotationTotalSize: "200000",
364-
putil.AnnotationHNSEnabled: "true",
365362
}
366363

367364
testCases := []struct {
@@ -478,7 +475,6 @@ func TestCheckPVRelevance(t *testing.T) {
478475
putil.AnnotationStatus: putil.ScanOverride,
479476
putil.AnnotationNumObjects: "not-a-number",
480477
putil.AnnotationTotalSize: "200000",
481-
putil.AnnotationHNSEnabled: "true",
482478
}, nil),
483479
scs: []*storagev1.StorageClass{validSC},
484480
wantRelevant: false,
@@ -491,20 +487,6 @@ func TestCheckPVRelevance(t *testing.T) {
491487
putil.AnnotationStatus: putil.ScanOverride,
492488
putil.AnnotationNumObjects: "-100",
493489
putil.AnnotationTotalSize: "200000",
494-
putil.AnnotationHNSEnabled: "true",
495-
}, nil),
496-
scs: []*storagev1.StorageClass{validSC},
497-
wantRelevant: false,
498-
wantErr: true,
499-
wantIsPendingScan: false,
500-
},
501-
{
502-
name: "Irrelevant - Override mode - Invalid HNSEnabled - Should return error",
503-
pv: createPV(testPVName, testSCName, testBucketName, csiDriverName, nil, map[string]string{
504-
putil.AnnotationStatus: putil.ScanOverride,
505-
putil.AnnotationNumObjects: "1000",
506-
putil.AnnotationTotalSize: "200000",
507-
putil.AnnotationHNSEnabled: "not-a-bool",
508490
}, nil),
509491
scs: []*storagev1.StorageClass{validSC},
510492
wantRelevant: false,
@@ -573,7 +555,6 @@ func TestSyncPV(t *testing.T) {
573555
putil.AnnotationStatus: putil.ScanOverride,
574556
putil.AnnotationNumObjects: "111",
575557
putil.AnnotationTotalSize: "2222",
576-
putil.AnnotationHNSEnabled: "false",
577558
}
578559
pvOverride := createPV(pvName, scName, bucketName, csiDriverName, nil, overrideAnnotations, nil)
579560

@@ -654,7 +635,6 @@ func TestSyncPV(t *testing.T) {
654635
expectedAnnots: map[string]string{
655636
putil.AnnotationNumObjects: "111",
656637
putil.AnnotationTotalSize: "2222",
657-
putil.AnnotationHNSEnabled: "false",
658638
},
659639
},
660640
}
@@ -731,7 +711,6 @@ func TestSyncPod(t *testing.T) {
731711
putil.AnnotationStatus: putil.ScanOverride,
732712
putil.AnnotationNumObjects: "100",
733713
putil.AnnotationTotalSize: "200",
734-
putil.AnnotationHNSEnabled: "true",
735714
}
736715
pvOverride := createPV("pv-override", testSCName, testBucketName, csiDriverName, nil, pvOverrideAnnotations, nil)
737716
pvcBoundOverride := createPVC("pvc-override", testNamespace, "pv-override", testSCName)
@@ -1183,7 +1162,6 @@ func TestUpdatePVScanResult(t *testing.T) {
11831162
bucketI := &bucketInfo{
11841163
numObjects: 999,
11851164
totalSizeBytes: 8888,
1186-
isHNSEnabled: true,
11871165
}
11881166
status := scanCompleted
11891167

@@ -1208,7 +1186,6 @@ func TestUpdatePVScanResult(t *testing.T) {
12081186
putil.AnnotationStatus: status,
12091187
putil.AnnotationNumObjects: "999",
12101188
putil.AnnotationTotalSize: "8888",
1211-
putil.AnnotationHNSEnabled: "true",
12121189
putil.AnnotationLastUpdatedTime: now.UTC().Format(time.RFC3339),
12131190
}
12141191

@@ -1306,12 +1283,7 @@ func TestDefaultScanBucket(t *testing.T) {
13061283
if err != nil {
13071284
t.Fatalf("strconv.ParseUint() error = %v", err)
13081285
}
1309-
hnsEnabledAttrs := &storage.BucketAttrs{
1310-
Name: testBucketName,
1311-
ProjectNumber: projectNumber,
1312-
HierarchicalNamespace: &storage.HierarchicalNamespace{Enabled: true},
1313-
}
1314-
hnsDisabledAttrs := &storage.BucketAttrs{
1286+
attrs := &storage.BucketAttrs{
13151287
Name: testBucketName,
13161288
ProjectNumber: projectNumber,
13171289
}
@@ -1333,22 +1305,22 @@ func TestDefaultScanBucket(t *testing.T) {
13331305
{
13341306
name: "onlyDir - Dataflux success",
13351307
inputBucketI: &bucketInfo{name: testBucketName, dir: testDirName, onlyDirSpecified: true},
1336-
fakeGetAttrs: fakebucketAttrsFunc{attrs: hnsEnabledAttrs},
1308+
fakeGetAttrs: fakebucketAttrsFunc{attrs: attrs},
13371309
fakeDataflux: fakeScanFunc{
13381310
numObjects: 200,
13391311
totalSizeBytes: 2000,
13401312
},
13411313
wantBucketI: &bucketInfo{
13421314
name: testBucketName, dir: testDirName, onlyDirSpecified: true,
1343-
numObjects: 200, totalSizeBytes: 2000, isHNSEnabled: true, projectNumber: testProjectNumber,
1315+
numObjects: 200, totalSizeBytes: 2000, projectNumber: testProjectNumber,
13441316
},
13451317
expectMetricsCall: false,
13461318
expectDatafluxCall: true,
13471319
},
13481320
{
13491321
name: "onlyDir - Dataflux error",
13501322
inputBucketI: &bucketInfo{name: testBucketName, dir: testDirName, onlyDirSpecified: true},
1351-
fakeGetAttrs: fakebucketAttrsFunc{attrs: hnsDisabledAttrs},
1323+
fakeGetAttrs: fakebucketAttrsFunc{attrs: attrs},
13521324
fakeDataflux: fakeScanFunc{err: errors.New("dataflux failed")},
13531325
wantErr: true,
13541326
expectMetricsCall: false,
@@ -1357,21 +1329,21 @@ func TestDefaultScanBucket(t *testing.T) {
13571329
{
13581330
name: "no onlyDir - Metrics success",
13591331
inputBucketI: &bucketInfo{name: testBucketName},
1360-
fakeGetAttrs: fakebucketAttrsFunc{attrs: hnsEnabledAttrs},
1332+
fakeGetAttrs: fakebucketAttrsFunc{attrs: attrs},
13611333
fakeMetrics: fakeScanFunc{
13621334
numObjects: 100,
13631335
totalSizeBytes: 1000,
13641336
},
13651337
wantBucketI: &bucketInfo{
1366-
name: testBucketName, numObjects: 100, totalSizeBytes: 1000, isHNSEnabled: true, projectNumber: testProjectNumber,
1338+
name: testBucketName, numObjects: 100, totalSizeBytes: 1000, projectNumber: testProjectNumber,
13671339
},
13681340
expectMetricsCall: true,
13691341
expectDatafluxCall: false,
13701342
},
13711343
{
13721344
name: "no onlyDir - Metrics error, Dataflux success (Fallback)",
13731345
inputBucketI: &bucketInfo{name: testBucketName},
1374-
fakeGetAttrs: fakebucketAttrsFunc{attrs: hnsDisabledAttrs},
1346+
fakeGetAttrs: fakebucketAttrsFunc{attrs: attrs},
13751347
fakeMetrics: fakeScanFunc{
13761348
numObjects: 100,
13771349
totalSizeBytes: 1000,
@@ -1382,15 +1354,15 @@ func TestDefaultScanBucket(t *testing.T) {
13821354
totalSizeBytes: 2000,
13831355
},
13841356
wantBucketI: &bucketInfo{
1385-
name: testBucketName, numObjects: 200, totalSizeBytes: 2000, isHNSEnabled: false, projectNumber: testProjectNumber,
1357+
name: testBucketName, numObjects: 200, totalSizeBytes: 2000, projectNumber: testProjectNumber,
13861358
},
13871359
expectMetricsCall: true,
13881360
expectDatafluxCall: true,
13891361
},
13901362
{
13911363
name: "no onlyDir - Metrics error, Dataflux error (Fallback Fails)",
13921364
inputBucketI: &bucketInfo{name: testBucketName},
1393-
fakeGetAttrs: fakebucketAttrsFunc{attrs: hnsEnabledAttrs},
1365+
fakeGetAttrs: fakebucketAttrsFunc{attrs: attrs},
13941366
fakeMetrics: fakeScanFunc{err: errors.New("metrics failed")},
13951367
fakeDataflux: fakeScanFunc{err: errors.New("dataflux failed")},
13961368
wantErr: true,

pkg/profiles/util/util.go

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const (
3535
AnnotationNumObjects = AnnotationPrefix + "/bucket-scan-num-objects"
3636
AnnotationTotalSize = AnnotationPrefix + "/bucket-scan-total-size-bytes"
3737
AnnotationLastUpdatedTime = AnnotationPrefix + "/bucket-scan-last-updated-time"
38-
AnnotationHNSEnabled = AnnotationPrefix + "/bucket-scan-hns-enabled"
3938

4039
ScanOverride = "override"
4140
)
@@ -44,7 +43,6 @@ var (
4443
requiredOverrideAnnotations = []string{
4544
AnnotationNumObjects,
4645
AnnotationTotalSize,
47-
AnnotationHNSEnabled,
4846
}
4947
)
5048

@@ -55,14 +53,13 @@ func ValidateStorageProfilesOverrideStatus(pv *corev1.PersistentVolume) error {
5553
AnnotationStatus,
5654
AnnotationNumObjects,
5755
AnnotationTotalSize,
58-
AnnotationHNSEnabled,
5956
}); len(annotationsUsed) > 0 {
6057
return status.Errorf(codes.InvalidArgument, "scanner annotations for PV %q found in non-override mode: %+v", pv.Name, annotationsUsed)
6158
}
6259
return nil
6360
}
6461

65-
_, _, _, err := ParseOverrideStatus(pv)
62+
_, _, err := ParseOverrideStatus(pv)
6663
if err != nil {
6764
return err
6865
}
@@ -98,38 +95,31 @@ func ParseNonNegativeIntegerFromString(val string) (int64, error) {
9895
// parseOverrideStatus checks that, if the override mode is set, the
9996
// PV has the required annotations with valid format/types.
10097
// Returns the required annotations (parsed) if valid, or returns an error otherwise.
101-
func ParseOverrideStatus(pv *v1.PersistentVolume) (int64, int64, bool, error) {
98+
func ParseOverrideStatus(pv *v1.PersistentVolume) (int64, int64, error) {
10299
// Enforce required annotations for override mode and validate formats.
103100
var numObjects int64
104101
var totalSizeBytes int64
105-
var isHNSEnabled bool
106102
for _, key := range requiredOverrideAnnotations {
107103
if _, exists := pv.Annotations[key]; !exists {
108-
return numObjects, totalSizeBytes, isHNSEnabled, status.Errorf(codes.InvalidArgument, "status %q requires annotation %q", ScanOverride, key)
104+
return numObjects, totalSizeBytes, status.Errorf(codes.InvalidArgument, "status %q requires annotation %q", ScanOverride, key)
109105
}
110106
switch key {
111107
case AnnotationNumObjects:
112108
val, err := ParseNonNegativeIntegerFromString(pv.Annotations[key])
113109
if err != nil {
114-
return numObjects, totalSizeBytes, isHNSEnabled, status.Errorf(codes.InvalidArgument, "invalid value for annotation %q: %v", key, err)
110+
return numObjects, totalSizeBytes, status.Errorf(codes.InvalidArgument, "invalid value for annotation %q: %v", key, err)
115111
}
116112
numObjects = val
117113
case AnnotationTotalSize:
118114
val, err := ParseNonNegativeIntegerFromString(pv.Annotations[key])
119115
if err != nil {
120-
return numObjects, totalSizeBytes, isHNSEnabled, status.Errorf(codes.InvalidArgument, "invalid value for annotation %q: %v", key, err)
116+
return numObjects, totalSizeBytes, status.Errorf(codes.InvalidArgument, "invalid value for annotation %q: %v", key, err)
121117
}
122118
totalSizeBytes = val
123-
case AnnotationHNSEnabled:
124-
val, err := strconv.ParseBool(pv.Annotations[AnnotationHNSEnabled])
125-
if err != nil {
126-
return numObjects, totalSizeBytes, isHNSEnabled, status.Errorf(codes.InvalidArgument, "invalid value for annotation %q: %v", key, err)
127-
}
128-
isHNSEnabled = val
129119
default:
130120
// This should never happen, but it's safer to check.
131-
return numObjects, totalSizeBytes, isHNSEnabled, status.Errorf(codes.Internal, "unexpected key for override mode requiredAnnotations: %q", key)
121+
return numObjects, totalSizeBytes, status.Errorf(codes.Internal, "unexpected key for override mode requiredAnnotations: %q", key)
132122
}
133123
}
134-
return numObjects, totalSizeBytes, isHNSEnabled, nil
124+
return numObjects, totalSizeBytes, nil
135125
}

pkg/profiles/util/util_test.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ func TestValidateStorageProfilesOverrideStatus(t *testing.T) {
163163
AnnotationStatus: ScanOverride,
164164
AnnotationNumObjects: "1000",
165165
AnnotationTotalSize: "2048",
166-
AnnotationHNSEnabled: "true",
167166
},
168167
},
169168
},
@@ -178,7 +177,6 @@ func TestValidateStorageProfilesOverrideStatus(t *testing.T) {
178177
AnnotationStatus: ScanOverride,
179178
AnnotationNumObjects: "1000",
180179
// annotationTotalSize is missing
181-
AnnotationHNSEnabled: "true",
182180
},
183181
},
184182
},
@@ -193,7 +191,6 @@ func TestValidateStorageProfilesOverrideStatus(t *testing.T) {
193191
AnnotationStatus: ScanOverride,
194192
AnnotationNumObjects: "not-a-number",
195193
AnnotationTotalSize: "2048",
196-
AnnotationHNSEnabled: "true",
197194
},
198195
},
199196
},
@@ -208,22 +205,6 @@ func TestValidateStorageProfilesOverrideStatus(t *testing.T) {
208205
AnnotationStatus: ScanOverride,
209206
AnnotationNumObjects: "1000",
210207
AnnotationTotalSize: "-2048",
211-
AnnotationHNSEnabled: "true",
212-
},
213-
},
214-
},
215-
wantErr: true,
216-
wantErrCode: codes.InvalidArgument,
217-
},
218-
{
219-
name: "Override mode: failure with invalid boolean value",
220-
pv: &corev1.PersistentVolume{
221-
ObjectMeta: metav1.ObjectMeta{
222-
Annotations: map[string]string{
223-
AnnotationStatus: ScanOverride,
224-
AnnotationNumObjects: "1000",
225-
AnnotationTotalSize: "2048",
226-
AnnotationHNSEnabled: "yes", // not a valid bool
227208
},
228209
},
229210
},

0 commit comments

Comments
 (0)