You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
8.7 KiB

11 years ago
11 years ago
11 years ago
6 years ago
11 years ago
5 years ago
7 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
4 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
5 years ago
11 years ago
  1. package command
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "google.golang.org/grpc/reflection"
  10. "github.com/chrislusf/seaweedfs/weed/glog"
  11. "github.com/chrislusf/seaweedfs/weed/pb"
  12. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  13. "github.com/chrislusf/seaweedfs/weed/security"
  14. "github.com/chrislusf/seaweedfs/weed/server"
  15. stats_collect "github.com/chrislusf/seaweedfs/weed/stats"
  16. "github.com/chrislusf/seaweedfs/weed/util"
  17. )
  18. var (
  19. f FilerOptions
  20. filerStartS3 *bool
  21. filerS3Options S3Options
  22. filerStartWebDav *bool
  23. filerWebDavOptions WebDavOption
  24. )
  25. type FilerOptions struct {
  26. masters *string
  27. ip *string
  28. bindIp *string
  29. port *int
  30. publicPort *int
  31. collection *string
  32. defaultReplicaPlacement *string
  33. disableDirListing *bool
  34. maxMB *int
  35. dirListingLimit *int
  36. dataCenter *string
  37. rack *string
  38. enableNotification *bool
  39. disableHttp *bool
  40. cipher *bool
  41. peers *string
  42. metricsHttpPort *int
  43. saveToFilerLimit *int
  44. defaultLevelDbDirectory *string
  45. }
  46. func init() {
  47. cmdFiler.Run = runFiler // break init cycle
  48. f.masters = cmdFiler.Flag.String("master", "localhost:9333", "comma-separated master servers")
  49. f.collection = cmdFiler.Flag.String("collection", "", "all data will be stored in this default collection")
  50. f.ip = cmdFiler.Flag.String("ip", util.DetectedHostAddress(), "filer server http listen ip address")
  51. f.bindIp = cmdFiler.Flag.String("ip.bind", "0.0.0.0", "ip address to bind to")
  52. f.port = cmdFiler.Flag.Int("port", 8888, "filer server http listen port")
  53. f.publicPort = cmdFiler.Flag.Int("port.readonly", 0, "readonly port opened to public")
  54. f.defaultReplicaPlacement = cmdFiler.Flag.String("defaultReplicaPlacement", "", "default replication type. If not specified, use master setting.")
  55. f.disableDirListing = cmdFiler.Flag.Bool("disableDirListing", false, "turn off directory listing")
  56. f.maxMB = cmdFiler.Flag.Int("maxMB", 32, "split files larger than the limit")
  57. f.dirListingLimit = cmdFiler.Flag.Int("dirListLimit", 100000, "limit sub dir listing size")
  58. f.dataCenter = cmdFiler.Flag.String("dataCenter", "", "prefer to read and write to volumes in this data center")
  59. f.rack = cmdFiler.Flag.String("rack", "", "prefer to write to volumes in this rack")
  60. f.disableHttp = cmdFiler.Flag.Bool("disableHttp", false, "disable http request, only gRpc operations are allowed")
  61. f.cipher = cmdFiler.Flag.Bool("encryptVolumeData", false, "encrypt data on volume servers")
  62. f.peers = cmdFiler.Flag.String("peers", "", "all filers sharing the same filer store in comma separated ip:port list")
  63. f.metricsHttpPort = cmdFiler.Flag.Int("metricsPort", 0, "Prometheus metrics listen port")
  64. f.saveToFilerLimit = cmdFiler.Flag.Int("saveToFilerLimit", 0, "files smaller than this limit will be saved in filer store")
  65. f.defaultLevelDbDirectory = cmdFiler.Flag.String("defaultStoreDir", ".", "if filer.toml is empty, use an embedded filer store in the directory")
  66. // start s3 on filer
  67. filerStartS3 = cmdFiler.Flag.Bool("s3", false, "whether to start S3 gateway")
  68. filerS3Options.port = cmdFiler.Flag.Int("s3.port", 8333, "s3 server http listen port")
  69. filerS3Options.domainName = cmdFiler.Flag.String("s3.domainName", "", "suffix of the host name in comma separated list, {bucket}.{domainName}")
  70. filerS3Options.tlsPrivateKey = cmdFiler.Flag.String("s3.key.file", "", "path to the TLS private key file")
  71. filerS3Options.tlsCertificate = cmdFiler.Flag.String("s3.cert.file", "", "path to the TLS certificate file")
  72. filerS3Options.config = cmdFiler.Flag.String("s3.config", "", "path to the config file")
  73. filerS3Options.allowEmptyFolder = cmdFiler.Flag.Bool("s3.allowEmptyFolder", false, "allow empty folders")
  74. // start webdav on filer
  75. filerStartWebDav = cmdFiler.Flag.Bool("webdav", false, "whether to start webdav gateway")
  76. filerWebDavOptions.port = cmdFiler.Flag.Int("webdav.port", 7333, "webdav server http listen port")
  77. filerWebDavOptions.collection = cmdFiler.Flag.String("webdav.collection", "", "collection to create the files")
  78. filerWebDavOptions.replication = cmdFiler.Flag.String("webdav.replication", "", "replication to create the files")
  79. filerWebDavOptions.disk = cmdFiler.Flag.String("webdav.disk", "", "[hdd|ssd] hard drive or solid state drive")
  80. filerWebDavOptions.tlsPrivateKey = cmdFiler.Flag.String("webdav.key.file", "", "path to the TLS private key file")
  81. filerWebDavOptions.tlsCertificate = cmdFiler.Flag.String("webdav.cert.file", "", "path to the TLS certificate file")
  82. filerWebDavOptions.cacheDir = cmdFiler.Flag.String("webdav.cacheDir", os.TempDir(), "local cache directory for file chunks")
  83. filerWebDavOptions.cacheSizeMB = cmdFiler.Flag.Int64("webdav.cacheCapacityMB", 1000, "local cache capacity in MB")
  84. }
  85. var cmdFiler = &Command{
  86. UsageLine: "filer -port=8888 -master=<ip:port>[,<ip:port>]*",
  87. Short: "start a file server that points to a master server, or a list of master servers",
  88. Long: `start a file server which accepts REST operation for any files.
  89. //create or overwrite the file, the directories /path/to will be automatically created
  90. POST /path/to/file
  91. //get the file content
  92. GET /path/to/file
  93. //create or overwrite the file, the filename in the multipart request will be used
  94. POST /path/to/
  95. //return a json format subdirectory and files listing
  96. GET /path/to/
  97. The configuration file "filer.toml" is read from ".", "$HOME/.seaweedfs/", "/usr/local/etc/seaweedfs/", or "/etc/seaweedfs/", in that order.
  98. If the "filer.toml" is not found, an embedded filer store will be craeted under "-defaultStoreDir".
  99. The example filer.toml configuration file can be generated by "weed scaffold -config=filer"
  100. `,
  101. }
  102. func runFiler(cmd *Command, args []string) bool {
  103. util.LoadConfiguration("security", false)
  104. go stats_collect.StartMetricsServer(*f.metricsHttpPort)
  105. if *filerStartS3 {
  106. filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
  107. filerS3Options.filer = &filerAddress
  108. go func() {
  109. time.Sleep(2 * time.Second)
  110. filerS3Options.startS3Server()
  111. }()
  112. }
  113. if *filerStartWebDav {
  114. filerAddress := fmt.Sprintf("%s:%d", *f.ip, *f.port)
  115. filerWebDavOptions.filer = &filerAddress
  116. go func() {
  117. time.Sleep(2 * time.Second)
  118. filerWebDavOptions.startWebDav()
  119. }()
  120. }
  121. f.startFiler()
  122. return true
  123. }
  124. func (fo *FilerOptions) startFiler() {
  125. defaultMux := http.NewServeMux()
  126. publicVolumeMux := defaultMux
  127. if *fo.publicPort != 0 {
  128. publicVolumeMux = http.NewServeMux()
  129. }
  130. defaultLevelDbDirectory := util.ResolvePath(*fo.defaultLevelDbDirectory + "/filerldb2")
  131. var peers []string
  132. if *fo.peers != "" {
  133. peers = strings.Split(*fo.peers, ",")
  134. }
  135. fs, nfs_err := weed_server.NewFilerServer(defaultMux, publicVolumeMux, &weed_server.FilerOption{
  136. Masters: strings.Split(*fo.masters, ","),
  137. Collection: *fo.collection,
  138. DefaultReplication: *fo.defaultReplicaPlacement,
  139. DisableDirListing: *fo.disableDirListing,
  140. MaxMB: *fo.maxMB,
  141. DirListingLimit: *fo.dirListingLimit,
  142. DataCenter: *fo.dataCenter,
  143. Rack: *fo.rack,
  144. DefaultLevelDbDir: defaultLevelDbDirectory,
  145. DisableHttp: *fo.disableHttp,
  146. Host: *fo.ip,
  147. Port: uint32(*fo.port),
  148. Cipher: *fo.cipher,
  149. SaveToFilerLimit: *fo.saveToFilerLimit,
  150. Filers: peers,
  151. })
  152. if nfs_err != nil {
  153. glog.Fatalf("Filer startup error: %v", nfs_err)
  154. }
  155. if *fo.publicPort != 0 {
  156. publicListeningAddress := *fo.bindIp + ":" + strconv.Itoa(*fo.publicPort)
  157. glog.V(0).Infoln("Start Seaweed filer server", util.Version(), "public at", publicListeningAddress)
  158. publicListener, e := util.NewListener(publicListeningAddress, 0)
  159. if e != nil {
  160. glog.Fatalf("Filer server public listener error on port %d:%v", *fo.publicPort, e)
  161. }
  162. go func() {
  163. if e := http.Serve(publicListener, publicVolumeMux); e != nil {
  164. glog.Fatalf("Volume server fail to serve public: %v", e)
  165. }
  166. }()
  167. }
  168. glog.V(0).Infof("Start Seaweed Filer %s at %s:%d", util.Version(), *fo.ip, *fo.port)
  169. filerListener, e := util.NewListener(
  170. *fo.bindIp+":"+strconv.Itoa(*fo.port),
  171. time.Duration(10)*time.Second,
  172. )
  173. if e != nil {
  174. glog.Fatalf("Filer listener error: %v", e)
  175. }
  176. // starting grpc server
  177. grpcPort := *fo.port + 10000
  178. grpcL, err := util.NewListener(*fo.bindIp+":"+strconv.Itoa(grpcPort), 0)
  179. if err != nil {
  180. glog.Fatalf("failed to listen on grpc port %d: %v", grpcPort, err)
  181. }
  182. grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.filer"))
  183. filer_pb.RegisterSeaweedFilerServer(grpcS, fs)
  184. reflection.Register(grpcS)
  185. go grpcS.Serve(grpcL)
  186. httpS := &http.Server{Handler: defaultMux}
  187. if err := httpS.Serve(filerListener); err != nil {
  188. glog.Fatalf("Filer Fail to serve: %v", e)
  189. }
  190. }