Browse Source
Volume server add `/admin/setting` interface, support set volume replication and readonly
pull/279/head
Volume server add `/admin/setting` interface, support set volume replication and readonly
pull/279/head
5 changed files with 168 additions and 136 deletions
-
25go/weed/weed_server/master_server_handlers_admin.go
-
2go/weed/weed_server/volume_server.go
-
86go/weed/weed_server/volume_server_handlers_admin.go
-
130go/weed/weed_server/volume_server_handlers_replicate.go
-
61go/weed/weed_server/volume_server_handlers_sync.go
@ -1,130 +0,0 @@ |
|||
package weed_server |
|||
|
|||
import ( |
|||
"fmt" |
|||
"io" |
|||
"net/http" |
|||
"strconv" |
|||
|
|||
"github.com/chrislusf/seaweedfs/go/glog" |
|||
"github.com/chrislusf/seaweedfs/go/storage" |
|||
"github.com/pierrec/lz4" |
|||
"strings" |
|||
) |
|||
|
|||
func (vs *VolumeServer) getVolumeCleanDataHandler(w http.ResponseWriter, r *http.Request) { |
|||
v, e := vs.getVolume("volume", r) |
|||
if v == nil { |
|||
http.Error(w, fmt.Sprintf("Not Found volume: %v", e), http.StatusBadRequest) |
|||
return |
|||
} |
|||
//set read only when replicating
|
|||
v.SetReadOnly(true) |
|||
defer v.SetReadOnly(false) |
|||
cr, e := v.GetVolumeCleanReader() |
|||
if e != nil { |
|||
http.Error(w, fmt.Sprintf("Get volume clean reader: %v", e), http.StatusInternalServerError) |
|||
return |
|||
} |
|||
totalSize, e := cr.Size() |
|||
if e != nil { |
|||
http.Error(w, fmt.Sprintf("Get volume size: %v", e), http.StatusInternalServerError) |
|||
return |
|||
} |
|||
w.Header().Set("Accept-Ranges", "bytes") |
|||
w.Header().Set("Content-Disposition", fmt.Sprintf(`filename="%d.dat.lz4"`, v.Id)) |
|||
|
|||
rangeReq := r.Header.Get("Range") |
|||
if rangeReq == "" { |
|||
w.Header().Set("Content-Length", strconv.FormatInt(totalSize, 10)) |
|||
w.Header().Set("Content-Encoding", "lz4") |
|||
lz4w := lz4.NewWriter(w) |
|||
if _, e = io.Copy(lz4w, cr); e != nil { |
|||
glog.V(4).Infoln("response write error:", e) |
|||
} |
|||
lz4w.Close() |
|||
return |
|||
} |
|||
ranges, e := parseRange(rangeReq, totalSize) |
|||
if e != nil { |
|||
http.Error(w, e.Error(), http.StatusRequestedRangeNotSatisfiable) |
|||
return |
|||
} |
|||
if len(ranges) != 1 { |
|||
http.Error(w, "Only support one range", http.StatusNotImplemented) |
|||
return |
|||
} |
|||
ra := ranges[0] |
|||
if _, e := cr.Seek(ra.start, 0); e != nil { |
|||
http.Error(w, e.Error(), http.StatusInternalServerError) |
|||
return |
|||
} |
|||
w.Header().Set("Content-Length", strconv.FormatInt(ra.length, 10)) |
|||
w.Header().Set("Content-Range", ra.contentRange(totalSize)) |
|||
w.Header().Set("Content-Encoding", "lz4") |
|||
w.WriteHeader(http.StatusPartialContent) |
|||
lz4w := lz4.NewWriter(w) |
|||
if _, e = io.CopyN(lz4w, cr, ra.length); e != nil { |
|||
glog.V(2).Infoln("response write error:", e) |
|||
} |
|||
lz4w.Close() |
|||
} |
|||
|
|||
type VolumeOptError struct { |
|||
Volume string `json:"volume"` |
|||
Err string `json:"err"` |
|||
} |
|||
|
|||
func (vs *VolumeServer) setVolumeReplicaHandler(w http.ResponseWriter, r *http.Request) { |
|||
r.ParseForm() |
|||
replica, e := storage.NewReplicaPlacementFromString(r.FormValue("replication")) |
|||
if e != nil { |
|||
writeJsonError(w, r, http.StatusBadRequest, e) |
|||
return |
|||
} |
|||
errs := []VolumeOptError{} |
|||
all, _ := strconv.ParseBool(r.FormValue("all")) |
|||
if all { |
|||
vs.store.WalkVolume(func(v *storage.Volume) (e error) { |
|||
if e := v.SetReplica(replica); e != nil { |
|||
errs = append(errs, VolumeOptError{ |
|||
Volume: v.Id.String(), |
|||
Err: e.Error(), |
|||
}) |
|||
} |
|||
return nil |
|||
}) |
|||
} else { |
|||
volumesSet := make(map[string]bool) |
|||
for _, volume := range r.Form["volume"] { |
|||
volumesSet[strings.TrimSpace(volume)] = true |
|||
} |
|||
collectionsSet := make(map[string]bool) |
|||
for _, c := range r.Form["collection"] { |
|||
collectionsSet[strings.TrimSpace(c)] = true |
|||
} |
|||
if len(collectionsSet) > 0 || len(volumesSet) > 0 { |
|||
vs.store.WalkVolume(func(v *storage.Volume) (e error) { |
|||
if !collectionsSet[v.Collection] && !volumesSet[v.Id.String()] { |
|||
return nil |
|||
} |
|||
if e := v.SetReplica(replica); e != nil { |
|||
errs = append(errs, VolumeOptError{ |
|||
Volume: v.Id.String(), |
|||
Err: e.Error(), |
|||
}) |
|||
} |
|||
return nil |
|||
}) |
|||
} |
|||
|
|||
} |
|||
|
|||
result := make(map[string]interface{}) |
|||
if len(errs) > 0 { |
|||
result["error"] = "set volume replica error." |
|||
result["errors"] = errs |
|||
} |
|||
|
|||
writeJson(w, r, http.StatusAccepted, result) |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue