2021-08-08 16:21:42 +08:00
package command
import (
"fmt"
2022-07-29 15:17:28 +08:00
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/replication/source"
"github.com/seaweedfs/seaweedfs/weed/security"
"github.com/seaweedfs/seaweedfs/weed/util"
2021-08-08 16:21:42 +08:00
"google.golang.org/grpc"
"time"
)
type RemoteSyncOptions struct {
2021-09-20 03:06:15 +08:00
filerAddress * string
2022-09-11 05:15:42 +08:00
storageClass * string
2021-09-20 03:06:15 +08:00
grpcDialOption grpc . DialOption
readChunkFromFiler * bool
timeAgo * time . Duration
dir * string
2021-12-30 16:23:57 +08:00
clientId int32
2022-07-24 01:50:28 +08:00
clientEpoch int32
2021-08-08 16:21:42 +08:00
}
var _ = filer_pb . FilerClient ( & RemoteSyncOptions { } )
2021-12-26 16:15:03 +08:00
func ( option * RemoteSyncOptions ) WithFilerClient ( streamingMode bool , fn func ( filer_pb . SeaweedFilerClient ) error ) error {
2023-01-20 17:48:12 +08:00
return pb . WithFilerClient ( streamingMode , option . clientId , pb . ServerAddress ( * option . filerAddress ) , option . grpcDialOption , func ( client filer_pb . SeaweedFilerClient ) error {
2021-08-08 16:21:42 +08:00
return fn ( client )
} )
}
func ( option * RemoteSyncOptions ) AdjustedUrl ( location * filer_pb . Location ) string {
return location . Url
}
2022-08-05 08:35:00 +08:00
func ( option * RemoteSyncOptions ) GetDataCenter ( ) string {
return ""
}
2021-08-08 16:21:42 +08:00
var (
remoteSyncOptions RemoteSyncOptions
)
func init ( ) {
cmdFilerRemoteSynchronize . Run = runFilerRemoteSynchronize // break init cycle
remoteSyncOptions . filerAddress = cmdFilerRemoteSynchronize . Flag . String ( "filer" , "localhost:8888" , "filer of the SeaweedFS cluster" )
2021-09-07 06:10:55 +08:00
remoteSyncOptions . dir = cmdFilerRemoteSynchronize . Flag . String ( "dir" , "" , "a mounted directory on filer" )
2022-09-11 05:18:28 +08:00
remoteSyncOptions . storageClass = cmdFilerRemoteSynchronize . Flag . String ( "storageClass" , "" , "override amz storage class, empty to delete" )
2021-08-08 16:21:42 +08:00
remoteSyncOptions . readChunkFromFiler = cmdFilerRemoteSynchronize . Flag . Bool ( "filerProxy" , false , "read file chunks from filer instead of volume servers" )
2021-12-14 05:14:36 +08:00
remoteSyncOptions . timeAgo = cmdFilerRemoteSynchronize . Flag . Duration ( "timeAgo" , 0 , "start time before now, skipping previous metadata changes. \"300ms\", \"1.5h\" or \"2h45m\". Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\"" )
2021-12-30 16:23:57 +08:00
remoteSyncOptions . clientId = util . RandomInt32 ( )
2021-08-08 16:21:42 +08:00
}
var cmdFilerRemoteSynchronize = & Command {
2021-09-07 07:16:22 +08:00
UsageLine : "filer.remote.sync" ,
2021-09-04 19:35:46 +08:00
Short : "resumable continuously write back updates to remote storage" ,
Long : ` resumable continuously write back updates to remote storage
2021-08-08 16:21:42 +08:00
filer . remote . sync listens on filer update events .
If any mounted remote file is updated , it will fetch the updated content ,
and write to the remote storage .
2021-09-04 19:35:46 +08:00
2021-09-07 07:16:22 +08:00
weed filer . remote . sync - dir = / mount / s3_on_cloud
2021-12-14 05:14:36 +08:00
The metadata sync starting time is determined with the following priority order :
1. specified by timeAgo
2. last sync timestamp for this directory
3. directory creation time
2021-08-08 16:21:42 +08:00
` ,
}
func runFilerRemoteSynchronize ( cmd * Command , args [ ] string ) bool {
2024-07-17 00:15:55 +08:00
util . LoadSecurityConfiguration ( )
2021-08-08 16:21:42 +08:00
grpcDialOption := security . LoadClientTLS ( util . GetViper ( ) , "grpc.client" )
remoteSyncOptions . grpcDialOption = grpcDialOption
2021-08-16 03:38:26 +08:00
dir := * remoteSyncOptions . dir
2021-09-13 13:47:52 +08:00
filerAddress := pb . ServerAddress ( * remoteSyncOptions . filerAddress )
2021-08-16 03:38:26 +08:00
2021-08-08 16:21:42 +08:00
filerSource := & source . FilerSource { }
filerSource . DoInitialize (
2021-09-13 13:47:52 +08:00
filerAddress . ToHttpAddress ( ) ,
filerAddress . ToGrpcAddress ( ) ,
2021-08-08 16:21:42 +08:00
"/" , // does not matter
* remoteSyncOptions . readChunkFromFiler ,
)
2021-09-16 13:47:17 +08:00
if dir != "" {
2021-09-05 04:46:44 +08:00
fmt . Printf ( "synchronize %s to remote storage...\n" , dir )
2023-10-02 02:33:56 +08:00
util . RetryUntil ( "filer.remote.sync " + dir , func ( ) error {
2021-09-05 04:46:44 +08:00
return followUpdatesAndUploadToRemote ( & remoteSyncOptions , filerSource , dir )
} , func ( err error ) bool {
if err != nil {
glog . Errorf ( "synchronize %s: %v" , dir , err )
}
return true
} )
2021-09-07 06:10:55 +08:00
return true
2021-09-05 04:46:44 +08:00
}
2021-09-04 19:35:46 +08:00
return true
2021-09-07 06:10:55 +08:00
2021-08-09 13:30:36 +08:00
}