示例#1
0
func main() {
	flag.Usage = usage
	version := flag.Bool("version", false, "Display version information.")
	flag.Parse()

	if *version {
		fmt.Printf("Buckytools version: %s\n", buckytools.Version)
		os.Exit(0)
	}
	if flag.NArg() != 2 {
		usage()
		os.Exit(1)
	}

	err := fill.All(flag.Arg(0), flag.Arg(1))
	if err != nil {
		fmt.Fprintf(os.Stderr, "An error occured:\n\t%s\n", err)
		os.Exit(2)
	}
}
示例#2
0
// healMetric will use the Whisper DB in the body of the request to
// backfill the metric found at the given filesystem path.  If the metric
// doesn't exist it will be created as an identical copy of the DB found
// in the request.
func healMetric(w http.ResponseWriter, r *http.Request, path string) {
	// Does this request look sane?
	if r.Header.Get("Content-Type") != "application/octet-stream" {
		http.Error(w, "Content-Type must be application/octet-stream.",
			http.StatusBadRequest)
		log.Printf("Got send a content-type of %s, abort!", r.Header.Get("Content-Type"))
		return
	}
	i, err := strconv.Atoi(r.Header.Get("Content-Length"))
	if err != nil || i <= 28 {
		// Whisper file headers are 28 bytes and we need data too.
		// Something is wrong here
		log.Printf("Whisper data in request too small: %d bytes", i)
		http.Error(w, "Whisper data in request too small.", http.StatusBadRequest)
	}

	// Does the destination path on dist exist?
	dstExists := true
	if _, err := os.Stat(path); err != nil {
		if !os.IsNotExist(err) {
			log.Printf("Error stat'ing file %s: %s", path, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		err := os.MkdirAll(filepath.Dir(path), 0755)
		if err != nil {
			log.Printf("Error creating %s: %s", filepath.Dir(path), err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		dstExists = false
	}

	// Write request body to a tmpfile
	fd, err := ioutil.TempFile(tmpDir, "buckyd")
	if err != nil {
		log.Printf("Error creating temp file: %s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = io.Copy(fd, r.Body)
	if err != nil {
		log.Printf("Error writing to temp file: %s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		fd.Close()
		os.Remove(fd.Name())
		return
	}
	srcName := fd.Name()
	fd.Sync()
	fd.Close()
	defer os.Remove(srcName) // not concerned with errors here

	// XXX: How can we check the tmpfile for sanity?
	if dstExists {
		err := fill.All(srcName, path)
		if err != nil {
			log.Printf("Error backfilling %s => %s: %s", srcName, path, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else {
		src, err := os.Open(srcName)
		if err != nil {
			log.Printf("Error opening tmp file %s: %s", srcName, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer src.Close()
		if err = syscall.Flock(int(src.Fd()), syscall.LOCK_EX); err != nil {
			log.Printf("Error locking file %s: %s", srcName, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		dst, err := os.Create(path)
		if err != nil {
			log.Printf("Error opening metric file %s: %s", path, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer dst.Close()
		if err = syscall.Flock(int(dst.Fd()), syscall.LOCK_EX); err != nil {
			log.Printf("Error locking file %s: %s", path, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		_, err = io.Copy(dst, src)
		if err != nil {
			log.Printf("Error copying %s => %s: %s", srcName, path, err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

}