Skip to content

Commit 6eb3f77

Browse files
authored
fix: Traverse symlinks for disk size calculation of models stored on PVC (#55)
Resolve symlinks (created by PVC puller) in order to calculate the size of the target model instead of the size of the symlink itself. Resolves #54 --------- Signed-off-by: Golan Levy <[email protected]>
1 parent bb931ea commit 6eb3f77

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

model-serving-puller/puller/puller.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,10 @@ func (s *Puller) ProcessLoadModelRequest(ctx context.Context, req *mmesh.LoadMod
209209
}
210210

211211
// update the model key to add the disk size
212-
if size, err1 := getModelDiskSize(modelFullPath); err1 != nil {
212+
if size, err1 := s.getModelDiskSize(modelFullPath); err1 != nil {
213213
s.Log.Error(err1, "Model disk size will not be included in the LoadModelRequest due to error", "model_key", modelKey)
214214
} else {
215+
s.Log.Info("Calculated disk size", "modelFullPath", modelFullPath, "disk_size", size)
215216
modelKey.DiskSizeBytes = size
216217
}
217218

@@ -230,18 +231,36 @@ func (s *Puller) ProcessLoadModelRequest(ctx context.Context, req *mmesh.LoadMod
230231
return req, nil
231232
}
232233

233-
func getModelDiskSize(modelPath string) (int64, error) {
234+
func (s *Puller) getModelDiskSize(modelPath string) (int64, error) {
234235
// This walks the local filesystem and accumulates the size of the model
235236
// It would be more efficient to accumulate the size as the files are downloaded,
236237
// but this would require refactoring because the s3 download iterator does not return a size.
237238
var size int64
238-
err := filepath.Walk(modelPath, func(_ string, info os.FileInfo, err error) error {
239+
err := filepath.Walk(modelPath, func(path string, info os.FileInfo, err error) error {
239240
if err != nil {
240241
return err
241242
}
242-
if !info.IsDir() {
243+
244+
// Calculating the size of the resolved path (for pvc) instead of the symlink itself.
245+
// We are not expecting to have infinite recursion since otherwise the serving runtime would not be able to load the model
246+
if info.Mode()&os.ModeSymlink != 0 {
247+
resolvedPath, resolveErr := os.Readlink(path)
248+
249+
if resolveErr != nil {
250+
s.Log.Error(resolveErr, "Failed to resolve symlink path", "path", path)
251+
} else {
252+
symlinkTargetSize, symlinkTargetSizeErr := s.getModelDiskSize(resolvedPath)
253+
254+
if symlinkTargetSizeErr != nil {
255+
return symlinkTargetSizeErr
256+
}
257+
258+
size += symlinkTargetSize
259+
}
260+
} else if !info.IsDir() {
243261
size += info.Size()
244262
}
263+
245264
return nil
246265
})
247266
if err != nil {

model-serving-puller/puller/puller_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,31 @@ func Test_getModelDiskSize(t *testing.T) {
607607
{"testModelSize/2", 39375276},
608608
}
609609

610+
p, _ := newPullerWithMock(t)
611+
612+
// creating symlinks on runtime since git is not managing symlinks by default
613+
symlinkName := "symlink"
614+
symlinkPath := filepath.Join(RootModelDir, symlinkName)
615+
610616
for _, tt := range diskSizeTests {
611617
t.Run("", func(t *testing.T) {
612618
fullPath := filepath.Join(RootModelDir, tt.modelPath)
613-
diskSize, err := getModelDiskSize(fullPath)
619+
validatePathDiskSize(t, p, fullPath, tt.expectedSize)
620+
621+
// testing symlink to the same path
622+
err := os.Symlink(fullPath, symlinkPath)
623+
assert.NoError(t, err)
624+
625+
validatePathDiskSize(t, p, symlinkPath, tt.expectedSize)
626+
627+
err = os.Remove(symlinkPath)
614628
assert.NoError(t, err)
615-
assert.EqualValues(t, tt.expectedSize, diskSize)
616629
})
617630
}
618631
}
632+
633+
func validatePathDiskSize(t *testing.T, p *Puller, path string, expectedSize int64) {
634+
diskSize, err := p.getModelDiskSize(path)
635+
assert.NoError(t, err)
636+
assert.EqualValues(t, expectedSize, diskSize)
637+
}

0 commit comments

Comments
 (0)