2021-08-08 08:21:42 +00:00
package command
import (
2021-08-09 00:55:03 +00:00
"context"
2021-08-08 08:21:42 +00:00
"fmt"
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/pb"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
2021-08-26 22:18:34 +00:00
"github.com/chrislusf/seaweedfs/weed/pb/remote_pb"
2021-08-08 08:21:42 +00:00
"github.com/chrislusf/seaweedfs/weed/replication/source"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/util"
"google.golang.org/grpc"
2021-09-06 22:10:55 +00:00
"os"
2021-08-08 08:21:42 +00:00
"time"
)
type RemoteSyncOptions struct {
2021-09-05 05:46:28 +00:00
filerAddress * string
grpcDialOption grpc . DialOption
readChunkFromFiler * bool
debug * bool
timeAgo * time . Duration
dir * string
createBucketAt * string
createBucketRandomSuffix * bool
2021-09-04 11:35:46 +00:00
mappings * remote_pb . RemoteStorageMapping
remoteConfs map [ string ] * remote_pb . RemoteConf
bucketsDir string
2021-08-08 08:21:42 +00:00
}
var _ = filer_pb . FilerClient ( & RemoteSyncOptions { } )
func ( option * RemoteSyncOptions ) WithFilerClient ( fn func ( filer_pb . SeaweedFilerClient ) error ) error {
return pb . WithFilerClient ( * option . filerAddress , option . grpcDialOption , func ( client filer_pb . SeaweedFilerClient ) error {
return fn ( client )
} )
}
func ( option * RemoteSyncOptions ) AdjustedUrl ( location * filer_pb . Location ) string {
return location . Url
}
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-06 22:10:55 +00:00
remoteSyncOptions . dir = cmdFilerRemoteSynchronize . Flag . String ( "dir" , "" , "a mounted directory on filer" )
2021-09-04 11:35:46 +00:00
remoteSyncOptions . createBucketAt = cmdFilerRemoteSynchronize . Flag . String ( "createBucketAt" , "" , "one remote storage name to create new buckets in" )
2021-09-06 22:14:26 +00:00
remoteSyncOptions . createBucketRandomSuffix = cmdFilerRemoteSynchronize . Flag . Bool ( "createBucketWithRandomSuffix" , true , "add randomized suffix to bucket name to avoid conflicts" )
2021-08-08 08:21:42 +00:00
remoteSyncOptions . readChunkFromFiler = cmdFilerRemoteSynchronize . Flag . Bool ( "filerProxy" , false , "read file chunks from filer instead of volume servers" )
remoteSyncOptions . debug = cmdFilerRemoteSynchronize . Flag . Bool ( "debug" , false , "debug mode to print out filer updated remote files" )
remoteSyncOptions . timeAgo = cmdFilerRemoteSynchronize . Flag . Duration ( "timeAgo" , 0 , "start time before now. \"300ms\", \"1.5h\" or \"2h45m\". Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\"" )
}
var cmdFilerRemoteSynchronize = & Command {
2021-09-06 23:16:22 +00:00
UsageLine : "filer.remote.sync" ,
2021-09-04 11:35:46 +00:00
Short : "resumable continuously write back updates to remote storage" ,
Long : ` resumable continuously write back updates to remote storage
2021-08-08 08:21:42 +00: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 11:35:46 +00:00
There are two modes :
2021-09-06 22:10:55 +00:00
2021-09-06 23:16:22 +00:00
1 ) By default , watch / buckets folder and write back all changes .
2021-09-06 22:10:55 +00:00
# if there is only one remote storage configured
weed filer . remote . sync
# if there are multiple remote storages configured
2021-09-06 23:16:22 +00:00
# specify a remote storage to create new buckets .
2021-09-04 11:35:46 +00:00
weed filer . remote . sync - createBucketAt = cloud1
2021-09-06 23:16:22 +00:00
2 ) Write back one mounted folder to remote storage
weed filer . remote . sync - dir = / mount / s3_on_cloud
2021-08-08 08:21:42 +00:00
` ,
}
func runFilerRemoteSynchronize ( cmd * Command , args [ ] string ) bool {
util . LoadConfiguration ( "security" , false )
grpcDialOption := security . LoadClientTLS ( util . GetViper ( ) , "grpc.client" )
remoteSyncOptions . grpcDialOption = grpcDialOption
2021-08-15 19:38:26 +00:00
dir := * remoteSyncOptions . dir
filerAddress := * remoteSyncOptions . filerAddress
2021-08-08 08:21:42 +00:00
filerSource := & source . FilerSource { }
filerSource . DoInitialize (
2021-08-15 19:38:26 +00:00
filerAddress ,
pb . ServerToGrpcAddress ( filerAddress ) ,
2021-08-08 08:21:42 +00:00
"/" , // does not matter
* remoteSyncOptions . readChunkFromFiler ,
)
2021-09-06 22:10:55 +00:00
remoteSyncOptions . bucketsDir = "/buckets"
// check buckets again
remoteSyncOptions . WithFilerClient ( func ( filerClient filer_pb . SeaweedFilerClient ) error {
resp , err := filerClient . GetFilerConfiguration ( context . Background ( ) , & filer_pb . GetFilerConfigurationRequest { } )
if err != nil {
return err
}
remoteSyncOptions . bucketsDir = resp . DirBuckets
return nil
} )
2021-08-09 00:55:03 +00:00
2021-09-06 22:10:55 +00:00
if dir != "" && dir != remoteSyncOptions . bucketsDir {
2021-09-04 20:46:44 +00:00
fmt . Printf ( "synchronize %s to remote storage...\n" , dir )
util . RetryForever ( "filer.remote.sync " + dir , func ( ) error {
return followUpdatesAndUploadToRemote ( & remoteSyncOptions , filerSource , dir )
} , func ( err error ) bool {
if err != nil {
glog . Errorf ( "synchronize %s: %v" , dir , err )
}
return true
} )
2021-09-06 22:10:55 +00:00
return true
2021-09-04 20:46:44 +00:00
}
2021-09-06 22:10:55 +00:00
// read filer remote storage mount mappings
if detectErr := remoteSyncOptions . collectRemoteStorageConf ( ) ; detectErr != nil {
fmt . Fprintf ( os . Stderr , "read mount info: %v\n" , detectErr )
return true
}
// synchronize /buckets folder
fmt . Printf ( "synchronize buckets in %s ...\n" , remoteSyncOptions . bucketsDir )
util . RetryForever ( "filer.remote.sync buckets" , func ( ) error {
return remoteSyncOptions . followBucketUpdatesAndUploadToRemote ( filerSource )
} , func ( err error ) bool {
if err != nil {
glog . Errorf ( "synchronize %s: %v" , remoteSyncOptions . bucketsDir , err )
}
return true
} )
2021-09-04 11:35:46 +00:00
return true
2021-09-06 22:10:55 +00:00
2021-08-09 05:30:36 +00:00
}