filer.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package command
  2. import (
  3. "net/http"
  4. "os"
  5. "strconv"
  6. "time"
  7. "github.com/chrislusf/seaweedfs/weed/glog"
  8. "github.com/chrislusf/seaweedfs/weed/server"
  9. "github.com/chrislusf/seaweedfs/weed/util"
  10. "github.com/soheilhy/cmux"
  11. "google.golang.org/grpc/reflection"
  12. "google.golang.org/grpc"
  13. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  14. )
  15. var (
  16. f FilerOptions
  17. )
  18. type FilerOptions struct {
  19. master *string
  20. ip *string
  21. port *int
  22. publicPort *int
  23. collection *string
  24. defaultReplicaPlacement *string
  25. dir *string
  26. redirectOnRead *bool
  27. disableDirListing *bool
  28. confFile *string
  29. maxMB *int
  30. secretKey *string
  31. cassandra_server *string
  32. cassandra_keyspace *string
  33. redis_server *string
  34. redis_password *string
  35. redis_database *int
  36. }
  37. func init() {
  38. cmdFiler.Run = runFiler // break init cycle
  39. f.master = cmdFiler.Flag.String("master", "localhost:9333", "master server location")
  40. f.collection = cmdFiler.Flag.String("collection", "", "all data will be stored in this collection")
  41. f.ip = cmdFiler.Flag.String("ip", "", "filer server http listen ip address")
  42. f.port = cmdFiler.Flag.Int("port", 8888, "filer server http listen port")
  43. f.publicPort = cmdFiler.Flag.Int("port.public", 0, "port opened to public")
  44. f.dir = cmdFiler.Flag.String("dir", os.TempDir(), "directory to store meta data")
  45. f.defaultReplicaPlacement = cmdFiler.Flag.String("defaultReplicaPlacement", "000", "default replication type if not specified")
  46. f.redirectOnRead = cmdFiler.Flag.Bool("redirectOnRead", false, "whether proxy or redirect to volume server during file GET request")
  47. f.disableDirListing = cmdFiler.Flag.Bool("disableDirListing", false, "turn off directory listing")
  48. f.confFile = cmdFiler.Flag.String("confFile", "", "json encoded filer conf file")
  49. f.maxMB = cmdFiler.Flag.Int("maxMB", 32, "split files larger than the limit")
  50. f.cassandra_server = cmdFiler.Flag.String("cassandra.server", "", "host[:port] of the cassandra server")
  51. f.cassandra_keyspace = cmdFiler.Flag.String("cassandra.keyspace", "seaweed", "keyspace of the cassandra server")
  52. f.redis_server = cmdFiler.Flag.String("redis.server", "", "comma separated host:port[,host2:port2]* of the redis server, e.g., 127.0.0.1:6379")
  53. f.redis_password = cmdFiler.Flag.String("redis.password", "", "password in clear text")
  54. f.redis_database = cmdFiler.Flag.Int("redis.database", 0, "the database on the redis server")
  55. f.secretKey = cmdFiler.Flag.String("secure.secret", "", "secret to encrypt Json Web Token(JWT)")
  56. }
  57. var cmdFiler = &Command{
  58. UsageLine: "filer -port=8888 -dir=/tmp -master=<ip:port>",
  59. Short: "start a file server that points to a master server",
  60. Long: `start a file server which accepts REST operation for any files.
  61. //create or overwrite the file, the directories /path/to will be automatically created
  62. POST /path/to/file
  63. //get the file content
  64. GET /path/to/file
  65. //create or overwrite the file, the filename in the multipart request will be used
  66. POST /path/to/
  67. //return a json format subdirectory and files listing
  68. GET /path/to/
  69. Current <fullpath~fileid> mapping metadata store is local embedded leveldb.
  70. It should be highly scalable to hundreds of millions of files on a modest machine.
  71. Future we will ensure it can avoid of being SPOF.
  72. `,
  73. }
  74. func runFiler(cmd *Command, args []string) bool {
  75. if err := util.TestFolderWritable(*f.dir); err != nil {
  76. glog.Fatalf("Check Meta Folder (-dir) Writable %s : %s", *f.dir, err)
  77. }
  78. f.start()
  79. return true
  80. }
  81. func (fo *FilerOptions) start() {
  82. defaultMux := http.NewServeMux()
  83. publicVolumeMux := defaultMux
  84. if *fo.publicPort != 0 {
  85. publicVolumeMux = http.NewServeMux()
  86. }
  87. fs, nfs_err := weed_server.NewFilerServer(defaultMux, publicVolumeMux,
  88. *fo.ip, *fo.port, *fo.master, *fo.dir, *fo.collection,
  89. *fo.defaultReplicaPlacement, *fo.redirectOnRead, *fo.disableDirListing,
  90. *fo.confFile,
  91. *fo.maxMB,
  92. *fo.secretKey,
  93. *fo.cassandra_server, *fo.cassandra_keyspace,
  94. *fo.redis_server, *fo.redis_password, *fo.redis_database,
  95. )
  96. if nfs_err != nil {
  97. glog.Fatalf("Filer startup error: %v", nfs_err)
  98. }
  99. if *fo.publicPort != 0 {
  100. publicListeningAddress := *fo.ip + ":" + strconv.Itoa(*fo.publicPort)
  101. glog.V(0).Infoln("Start Seaweed filer server", util.VERSION, "public at", publicListeningAddress)
  102. publicListener, e := util.NewListener(publicListeningAddress, 0)
  103. if e != nil {
  104. glog.Fatalf("Filer server public listener error on port %d:%v", *fo.publicPort, e)
  105. }
  106. go func() {
  107. if e := http.Serve(publicListener, publicVolumeMux); e != nil {
  108. glog.Fatalf("Volume server fail to serve public: %v", e)
  109. }
  110. }()
  111. }
  112. glog.V(0).Infoln("Start Seaweed Filer", util.VERSION, "at port", strconv.Itoa(*fo.port))
  113. filerListener, e := util.NewListener(
  114. ":"+strconv.Itoa(*fo.port),
  115. time.Duration(10)*time.Second,
  116. )
  117. if e != nil {
  118. glog.Fatalf("Filer listener error: %v", e)
  119. }
  120. m := cmux.New(filerListener)
  121. grpcL := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
  122. httpL := m.Match(cmux.Any())
  123. // Create your protocol servers.
  124. grpcS := grpc.NewServer()
  125. filer_pb.RegisterSeaweedFilerServer(grpcS, fs)
  126. reflection.Register(grpcS)
  127. httpS := &http.Server{Handler: defaultMux}
  128. go grpcS.Serve(grpcL)
  129. go httpS.Serve(httpL)
  130. if err := m.Serve(); err != nil {
  131. glog.Fatalf("Filer Fail to serve: %v", e)
  132. }
  133. }