6 "github.com/gorilla/mux"
14 const DEFAULT_PORT = 25107
16 var KeepVolumes []string
19 // Look for local keep volumes.
20 KeepVolumes = FindKeepVolumes()
21 if len(KeepVolumes) == 0 {
22 log.Fatal("could not find any keep volumes")
24 for _, v := range KeepVolumes {
25 log.Println("keep volume:", v)
28 // Set up REST handlers.
29 rest := mux.NewRouter()
30 rest.HandleFunc("/{hash}", GetBlock).Methods("GET")
31 http.Handle("/", rest)
33 port := fmt.Sprintf(":%d", DEFAULT_PORT)
34 http.ListenAndServe(port, nil)
37 func GetBlock(w http.ResponseWriter, req *http.Request) {
38 hash := mux.Vars(req)["hash"]
40 // Attempt to read the requested hash from a keep volume.
41 for _, vol := range KeepVolumes {
42 path := fmt.Sprintf("%s/%s/%s", vol, hash[0:3], hash)
43 if f, err := os.Open(path); err == nil {
47 log.Printf("%s: reading block %s: %s\n", vol, hash, err)
53 // Returns a list of Keep volumes mounted on this system.
55 // A Keep volume is a normal or tmpfs volume with a /keep
56 // directory at the top level of the mount point.
58 func FindKeepVolumes() []string {
59 vols := make([]string, 0)
61 if f, err := os.Open("/proc/mounts"); err != nil {
62 log.Fatal("could not read /proc/mounts: ", err)
64 scanner := bufio.NewScanner(f)
66 args := strings.Fields(scanner.Text())
67 dev, mount := args[0], args[1]
68 if (dev == "tmpfs" || strings.HasPrefix(dev, "/dev/")) && mount != "/" {
69 keep := mount + "/keep"
70 if st, err := os.Stat(keep); err == nil && st.IsDir() {
71 vols = append(vols, keep)
75 if err := scanner.Err(); err != nil {