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
2 changes: 1 addition & 1 deletion cmd/syncEnumerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ func GetSyncEnumeratorWithDestComparator(
}
destCleanerFunc := newFpoAwareProcessor(fpo, destinationCleaner.removeImmediately)

if UseSyncOrchestrator && (cca.fromTo == common.EFromTo.S3Blob() || cca.fromTo == common.EFromTo.BlobBlob() || cca.fromTo == common.EFromTo.BlobFSBlob()) {
if UseSyncOrchestrator && (cca.fromTo == common.EFromTo.S3Blob() || cca.fromTo == common.EFromTo.BlobBlob() || cca.fromTo == common.EFromTo.BlobFSBlob() || cca.fromTo == common.EFromTo.FileFile()) {
// newFpoAwareProcessor sets the destCleanerFunc to nil for a non folder aware source destination pair like S3->Blob.
// But in case of SyncOrchestrator, S3->Blob sync does recursive deletion for a prefix.
// This requires a valid deletion processor to be passed to the comparator.
Expand Down
29 changes: 27 additions & 2 deletions cmd/syncOrchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ var (
"BlobNotFound",
"PathNotFound",
"ResourceNotFound",
"ShareNotFound",
"ShareBeingDeleted",
}

orchestratorOptions *SyncOrchestratorOptions
Expand Down Expand Up @@ -200,6 +202,26 @@ func validateLocalRoot(path string) error {
return nil
}

// validateFileShareRoot validates an Azure Files share root URL
func validateFileShareRoot(sourcePath string) error {
// Parse as a URL to validate format
parsedURL, err := url.Parse(sourcePath)
if err != nil {
return err
}

// Basic validation - should be a valid URL with file.core.windows.net host
if parsedURL.Host == "" {
return fmt.Errorf("invalid Azure Files URL: missing host")
}

if !strings.Contains(parsedURL.Host, "file.core.windows.net") {
return fmt.Errorf("invalid Azure Files URL: expected file.core.windows.net host")
}

return nil
}

// validateS3Root returns the root object for the sync orchestrator based on the S3 source path.
// It parses the S3 URL and determines the entity type (file or folder) based on the URL structure.
//
Expand Down Expand Up @@ -269,6 +291,8 @@ func validateAndGetRootObject(path string, fromTo common.FromTo) (minimalStoredO
err = validateBlobRoot(path)
case common.ELocation.BlobFS():
err = validateBlobFSRoot(path)
case common.ELocation.File():
err = validateFileShareRoot(path)
default:
err = fmt.Errorf("sync orchestrator is not supported for %s source", fromTo.From().String())
}
Expand Down Expand Up @@ -545,7 +569,7 @@ func newSyncTraverser(enumerator *syncEnumerator, dir string, comparator objectP

func validate(cca *cookedSyncCmdArgs, orchestratorOptions *SyncOrchestratorOptions) error {
switch cca.fromTo {
case common.EFromTo.LocalBlob(), common.EFromTo.LocalBlobFS(), common.EFromTo.LocalFile(), common.EFromTo.S3Blob(), common.EFromTo.BlobBlob(), common.EFromTo.BlobBlobFS(), common.EFromTo.BlobFSBlob(), common.EFromTo.BlobFSBlobFS():
case common.EFromTo.LocalBlob(), common.EFromTo.LocalBlobFS(), common.EFromTo.LocalFile(), common.EFromTo.S3Blob(), common.EFromTo.BlobBlob(), common.EFromTo.BlobBlobFS(), common.EFromTo.BlobFSBlob(), common.EFromTo.BlobFSBlobFS(), common.EFromTo.FileFile():
// sync orchestrator is supported for these types
default:
return fmt.Errorf(
Expand All @@ -557,7 +581,8 @@ func validate(cca *cookedSyncCmdArgs, orchestratorOptions *SyncOrchestratorOptio
"\t- Blob->Blob\n" +
"\t- Blob->BlobFS\n" +
"\t- BlobFS->Blob\n" +
"\t- BlobFS->BlobFS",
"\t- BlobFS->BlobFS\n" +
"\t- File->File",
)
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/syncOrchestratorModels.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func (s *SyncOrchestratorOptions) validate(from common.Location) error {
return errors.New("sync orchestrator options should only be used when UseSyncOrchestrator is true")
}

if from != common.ELocation.Local() && from != common.ELocation.S3() && from != common.ELocation.Blob() && from != common.ELocation.BlobFS() {
return errors.New("sync optimizations using timestamps should only be used for local to remote syncs")
if from != common.ELocation.Local() && from != common.ELocation.S3() && from != common.ELocation.Blob() && from != common.ELocation.BlobFS() && from != common.ELocation.File() {
return errors.New("sync optimizations using timestamps should only be used for supported source locations (Local, S3, Blob, BlobFS, File)")
}

if s.maxDirectoryDirectChildCount == 0 {
Expand Down
2 changes: 2 additions & 0 deletions cmd/syncThrottler.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ func GetSafeParallelismLimit(maxActiveFiles, maxChildCount int64, fromTo common.
return min(limit, 48)
case common.EFromTo.S3Blob():
return min(limit, 64)
case common.EFromTo.FileFile():
return min(limit, 48)
default:
return min(limit, 48)
}
Expand Down
15 changes: 15 additions & 0 deletions cmd/zc_newobjectadapters.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,18 +349,30 @@ type shareDirectoryFilePropertiesAdapter struct {
}

func (a shareDirectoryFilePropertiesAdapter) Metadata() common.Metadata {
if a.FileProperty == nil {
return nil
}
return nil
}

func (a shareDirectoryFilePropertiesAdapter) LastModified() time.Time {
if a.FileProperty == nil {
return time.Time{}
}
return common.IffNotNil(a.FileProperty.LastModified, time.Time{})
}

func (a shareDirectoryFilePropertiesAdapter) FileLastWriteTime() time.Time {
if a.FileProperty == nil {
return time.Time{}
}
return common.IffNotNil(a.FileProperty.LastWriteTime, time.Time{})
}

func (a shareDirectoryFilePropertiesAdapter) FileChangeTime() time.Time {
if a.FileProperty == nil {
return time.Time{}
}
return common.IffNotNil(a.FileProperty.ChangeTime, time.Time{})
}

Expand Down Expand Up @@ -389,6 +401,9 @@ func (a shareDirectoryFilePropertiesAdapter) ContentMD5() []byte {
}

func (a shareDirectoryFilePropertiesAdapter) ContentLength() int64 {
if a.FileProperty == nil {
return 0
}
return common.IffNotNil(a.FileProperty.ContentLength, 0)
}

Expand Down