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.

165 lines
5.3 KiB

10 years ago
10 years ago
  1. package weed_server
  2. import (
  3. "errors"
  4. "fmt"
  5. "math/rand"
  6. "net/http"
  7. "strconv"
  8. "github.com/chrislusf/seaweedfs/weed/glog"
  9. "github.com/chrislusf/seaweedfs/weed/storage"
  10. "github.com/chrislusf/seaweedfs/weed/topology"
  11. "github.com/chrislusf/seaweedfs/weed/util"
  12. )
  13. func (ms *MasterServer) collectionDeleteHandler(w http.ResponseWriter, r *http.Request) {
  14. collection, ok := ms.Topo.FindCollection(r.FormValue("collection"))
  15. if !ok {
  16. writeJsonError(w, r, http.StatusBadRequest, fmt.Errorf("collection %s does not exist", r.FormValue("collection")))
  17. return
  18. }
  19. for _, server := range collection.ListVolumeServers() {
  20. _, err := util.Get("http://" + server.Ip + ":" + strconv.Itoa(server.Port) + "/admin/delete_collection?collection=" + r.FormValue("collection"))
  21. if err != nil {
  22. writeJsonError(w, r, http.StatusInternalServerError, err)
  23. return
  24. }
  25. }
  26. ms.Topo.DeleteCollection(r.FormValue("collection"))
  27. }
  28. func (ms *MasterServer) dirStatusHandler(w http.ResponseWriter, r *http.Request) {
  29. m := make(map[string]interface{})
  30. m["Version"] = util.VERSION
  31. m["Topology"] = ms.Topo.ToMap()
  32. writeJsonQuiet(w, r, http.StatusOK, m)
  33. }
  34. func (ms *MasterServer) volumeVacuumHandler(w http.ResponseWriter, r *http.Request) {
  35. gcThreshold := r.FormValue("garbageThreshold")
  36. if gcThreshold == "" {
  37. gcThreshold = ms.garbageThreshold
  38. }
  39. glog.Infoln("garbageThreshold =", gcThreshold)
  40. ms.Topo.Vacuum(gcThreshold, ms.preallocate)
  41. ms.dirStatusHandler(w, r)
  42. }
  43. func (ms *MasterServer) volumeGrowHandler(w http.ResponseWriter, r *http.Request) {
  44. count := 0
  45. option, err := ms.getVolumeGrowOption(r)
  46. if err != nil {
  47. writeJsonError(w, r, http.StatusNotAcceptable, err)
  48. return
  49. }
  50. if err == nil {
  51. if count, err = strconv.Atoi(r.FormValue("count")); err == nil {
  52. if ms.Topo.FreeSpace() < count*option.ReplicaPlacement.GetCopyCount() {
  53. err = errors.New("Only " + strconv.Itoa(ms.Topo.FreeSpace()) + " volumes left! Not enough for " + strconv.Itoa(count*option.ReplicaPlacement.GetCopyCount()))
  54. } else {
  55. count, err = ms.vg.GrowByCountAndType(count, option, ms.Topo)
  56. }
  57. } else {
  58. err = errors.New("parameter count is not found")
  59. }
  60. }
  61. if err != nil {
  62. writeJsonError(w, r, http.StatusNotAcceptable, err)
  63. } else {
  64. writeJsonQuiet(w, r, http.StatusOK, map[string]interface{}{"count": count})
  65. }
  66. }
  67. func (ms *MasterServer) volumeStatusHandler(w http.ResponseWriter, r *http.Request) {
  68. m := make(map[string]interface{})
  69. m["Version"] = util.VERSION
  70. m["Volumes"] = ms.Topo.ToVolumeMap()
  71. writeJsonQuiet(w, r, http.StatusOK, m)
  72. }
  73. func (ms *MasterServer) redirectHandler(w http.ResponseWriter, r *http.Request) {
  74. vid, _, _, _, _ := parseURLPath(r.URL.Path)
  75. volumeId, err := storage.NewVolumeId(vid)
  76. if err != nil {
  77. debug("parsing error:", err, r.URL.Path)
  78. return
  79. }
  80. collection := r.FormValue("collection")
  81. machines := ms.Topo.Lookup(collection, volumeId)
  82. if machines != nil && len(machines) > 0 {
  83. var url string
  84. if r.URL.RawQuery != "" {
  85. url = util.NormalizeUrl(machines[rand.Intn(len(machines))].PublicUrl) + r.URL.Path + "?" + r.URL.RawQuery
  86. } else {
  87. url = util.NormalizeUrl(machines[rand.Intn(len(machines))].PublicUrl) + r.URL.Path
  88. }
  89. http.Redirect(w, r, url, http.StatusMovedPermanently)
  90. } else {
  91. writeJsonError(w, r, http.StatusNotFound, fmt.Errorf("volume id %d or collection %s not found", volumeId, collection))
  92. }
  93. }
  94. func (ms *MasterServer) selfUrl(r *http.Request) string {
  95. if r.Host != "" {
  96. return r.Host
  97. }
  98. return "localhost:" + strconv.Itoa(ms.port)
  99. }
  100. func (ms *MasterServer) submitFromMasterServerHandler(w http.ResponseWriter, r *http.Request) {
  101. if ms.Topo.IsLeader() {
  102. submitForClientHandler(w, r, ms.selfUrl(r))
  103. } else {
  104. masterUrl, err := ms.Topo.Leader()
  105. if err != nil {
  106. writeJsonError(w, r, http.StatusInternalServerError, err)
  107. } else {
  108. submitForClientHandler(w, r, masterUrl)
  109. }
  110. }
  111. }
  112. func (ms *MasterServer) deleteFromMasterServerHandler(w http.ResponseWriter, r *http.Request) {
  113. if ms.Topo.IsLeader() {
  114. deleteForClientHandler(w, r, ms.selfUrl(r))
  115. } else {
  116. deleteForClientHandler(w, r, ms.Topo.RaftServer.Leader())
  117. }
  118. }
  119. func (ms *MasterServer) HasWritableVolume(option *topology.VolumeGrowOption) bool {
  120. vl := ms.Topo.GetVolumeLayout(option.Collection, option.ReplicaPlacement, option.Ttl)
  121. return vl.GetActiveVolumeCount(option) > 0
  122. }
  123. func (ms *MasterServer) getVolumeGrowOption(r *http.Request) (*topology.VolumeGrowOption, error) {
  124. replicationString := r.FormValue("replication")
  125. if replicationString == "" {
  126. replicationString = ms.defaultReplicaPlacement
  127. }
  128. replicaPlacement, err := storage.NewReplicaPlacementFromString(replicationString)
  129. if err != nil {
  130. return nil, err
  131. }
  132. ttl, err := storage.ReadTTL(r.FormValue("ttl"))
  133. if err != nil {
  134. return nil, err
  135. }
  136. preallocate := ms.preallocate
  137. if r.FormValue("preallocate") != "" {
  138. preallocate, err = strconv.ParseInt(r.FormValue("preallocate"), 10, 64)
  139. if err != nil {
  140. return nil, fmt.Errorf("Failed to parse int64 preallocate = %s: %v", r.FormValue("preallocate"), err)
  141. }
  142. }
  143. volumeGrowOption := &topology.VolumeGrowOption{
  144. Collection: r.FormValue("collection"),
  145. ReplicaPlacement: replicaPlacement,
  146. Ttl: ttl,
  147. Prealloacte: preallocate,
  148. DataCenter: r.FormValue("dataCenter"),
  149. Rack: r.FormValue("rack"),
  150. DataNode: r.FormValue("dataNode"),
  151. }
  152. return volumeGrowOption, nil
  153. }