Example #1
0
func main() {
	flag.Usage = usage
	flag.Parse()

	if *createTorrent != "" {
		err := torrent.WriteMetaInfoBytes(*createTorrent, os.Stdout)
		if err != nil {
			log.Fatal("Could not create torrent file:", err)
		}
		return
	}

	if *createTracker != "" {
		err := startTracker(*createTracker, flag.Args())
		if err != nil {
			log.Fatal("Tracker returned error:", err)
		}
		return
	}

	args := flag.Args()
	narg := flag.NArg()
	if narg != 1 {
		if narg < 1 {
			log.Println("Too few arguments. Torrent file or torrent URL required.")
		} else {
			log.Printf("Too many arguments. (Expected 1): %v", args)
		}
		usage()
	}

	torrentFlags := parseTorrentFlags()

	if *cpuprofile != "" {
		cpuf, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(cpuf)
		defer pprof.StopCPUProfile()
	}

	if *memprofile != "" {
		defer func(file string) {
			memf, err := os.Create(file)
			if err != nil {
				log.Fatal(err)
			}
			pprof.WriteHeapProfile(memf)
		}(*memprofile)
	}

	log.Println("Starting.")

	err := torrent.RunTorrents(torrentFlags, args)
	if err != nil {
		log.Fatal("Could not run torrents", args, err)
	}
}
Example #2
0
func testHelperProcessImp(args []string) (err error) {
	for len(args) > 0 {
		if args[0] == "--" {
			args = args[1:]
			break
		}
		args = args[1:]
	}

	if len(args) == 0 {
		err = fmt.Errorf("No commands\n")
		return
	}

	cmd, args := args[0], args[1:]
	switch cmd {
	case "tracker":
		if len(args) < 2 {
			err = fmt.Errorf("tracker expected 2 or more args\n")
			return
		}
		addr, torrentFiles := args[0], args[1:]

		err = StartTracker(addr, torrentFiles)
		if err != nil {
			return
		}
	case "client":
		if len(args) < 4 {
			err = fmt.Errorf("client expected 4 or more args\n")
			return
		}
		portStr, fileDir, seedRatioStr, torrentFiles :=
			args[0], args[1], args[2], args[3:]
		var port uint64
		port, err = strconv.ParseUint(portStr, 10, 16)
		if err != nil {
			return
		}
		var seedRatio float64
		seedRatio, err = strconv.ParseFloat(seedRatioStr, 64)
		torrentFlags := torrent.TorrentFlags{
			Port:      int(port),
			FileDir:   fileDir,
			SeedRatio: seedRatio,
		}
		err = torrent.RunTorrents(&torrentFlags, torrentFiles)
		if err != nil {
			return
		}
	default:
		err = fmt.Errorf("Unknown command %q\n", cmd)
		return
	}
	return
}
Example #3
0
func main() {
	tracker := flag.String("tracker", "", "tracker url: http://host:port/")
	listen := flag.String("listen", "0.0.0.0:8888", "bind location")
	root := flag.String("root", "", "root dir to keep working files")
	flag.Parse()

	if *tracker == "" || *root == "" {
		flag.PrintDefaults()
		return
	}

	tu, err := url.Parse(*tracker)
	if err != nil {
		log.Fatal(err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		u := *req.URL
		u.Host = strings.TrimPrefix(req.Host, "p2p-")

		if req.TLS != nil {
			u.Scheme = "https"
		} else {
			u.Scheme = "http"
		}

		log.Println("got request:", req.Method, u.String())

		if req.Method == "PUT" || !strings.HasPrefix(u.Path, "/v1/images/") || !strings.HasSuffix(u.Path, "/layer") {
			pu := u
			pu.Path = "/"
			proxy := httputil.NewSingleHostReverseProxy(&pu)
			proxy.ServeHTTP(w, req)
			return
		}

		tu := *tu
		q := tu.Query()
		q.Set("url", u.String())

		log.Println(tu.String() + "?" + q.Encode())

		resp, err := http.Get(tu.String() + "?" + q.Encode())
		if err != nil {
			http.Error(w, "getting torrent failed", http.StatusInternalServerError)
			return
		}

		defer resp.Body.Close()

		f, err := ioutil.TempFile(*root, "image-torrent-")
		if err != nil {
			http.Error(w, "torrent file creation failed", http.StatusInternalServerError)
			return
		}

		defer func() {
			f.Close()
			os.Remove(f.Name())
		}()

		_, err = io.Copy(f, resp.Body)
		if err != nil {
			http.Error(w, "reading torrent contents failed", http.StatusInternalServerError)
			return
		}

		m, err := torrent.GetMetaInfo(nil, f.Name())
		if err != nil {
			http.Error(w, "reading torrent failed", http.StatusInternalServerError)
			return
		}

		err = torrent.RunTorrents(&torrent.TorrentFlags{
			FileDir:   *root,
			SeedRatio: 0,
		}, []string{f.Name()})

		lf := path.Join(*root, m.Info.Name)

		defer os.Remove(lf)

		// TODO: start another RunTorrents for configured interval
		// TODO: and remove data after that
		// TODO: or to hell with it

		if err != nil {
			http.Error(w, "downloading torrent failed", http.StatusInternalServerError)
			return
		}

		l, err := os.Open(lf)
		if err != nil {
			http.Error(w, "layer file open failed", http.StatusInternalServerError)
			return
		}

		defer l.Close()

		io.Copy(w, l)
	})

	err = http.ListenAndServe(*listen, mux)
	if err != nil {
		log.Fatal(err)
	}
}
Example #4
0
func main() {
	flag.Usage = usage
	flag.Parse()

	if *createTorrent != "" {
		err := torrent.WriteMetaInfoBytes(*createTorrent, *createTracker, os.Stdout)
		if err != nil {
			log.Fatal("Could not create torrent file:", err)
		}
		return
	}

	if *createTracker != "" {
		err := startTracker(*createTracker, flag.Args())
		if err != nil {
			log.Fatal("Tracker returned error:", err)
		}
		return
	}

	args := flag.Args()
	narg := flag.NArg()
	if narg < 1 {
		log.Println("Too few arguments. Torrent file or torrent URL required.")
		usage()
	}

	torrentFlags, err := parseTorrentFlags()
	if err != nil {
		log.Fatal("Could not parse flags:", err)
	}

	if *cpuprofile != "" {
		cpuf, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(cpuf)
		defer pprof.StopCPUProfile()
	}

	if *memprofile != "" {
		defer func(file string) {
			memf, err := os.Create(file)
			if err != nil {
				log.Fatal(err)
			}
			pprof.WriteHeapProfile(memf)
		}(*memprofile)
	}

	if (*memoryPerTorrent) >= 0 { //User is worried about memory use.
		debug.SetGCPercent(20) //Set the GC to clear memory more often.
	}

	log.Println("Starting.")

	err = torrent.RunTorrents(torrentFlags, args)
	if err != nil {
		log.Fatal("Could not run torrents", args, err)
	}
}
Example #5
0
func main() {
	tracker := flag.String("tracker", "", "tracker url: http://host:port/")
	listen := flag.String("listen", "0.0.0.0:8888", "bind location")
	root := flag.String("root", "", "root dir to keep working files")
	flag.Parse()

	if *tracker == "" || *root == "" {
		flag.PrintDefaults()
		return
	}

	tu, err := url.Parse(*tracker)
	if err != nil {
		log.Fatal(err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		u := *req.URL
		u.Host = strings.TrimPrefix(req.Host, "p2p-")

		if req.TLS != nil {
			u.Scheme = "https"
		} else {
			u.Scheme = "http"
		}

		log.Println("got request:", req.Method, u.String())

		// should be support V2 registry api
		if req.Method == "PUT" ||
			strings.HasPrefix(u.Path, "/v2/") ||
			strings.Contains(u.Path, "ping") {
			pu := u
			pu.Path = "/"
			proxy := httputil.NewSingleHostReverseProxy(&pu)
			proxy.ServeHTTP(w, req)
			return
		}

		tu := *tu
		q := tu.Query()
		q.Set("url", u.String())

		log.Println(tu.String() + "?" + q.Encode())

		resp, err := http.Get(tu.String() + "?" + q.Encode())
		if err != nil {
			http.Error(w, "getting torrent failed", http.StatusInternalServerError)
			return
		}

		defer resp.Body.Close()

		f, err := ioutil.TempFile(*root, "image-torrent-")
		if err != nil {
			http.Error(w, "torrent file creation failed", http.StatusInternalServerError)
			return
		}

		defer func() {
			f.Close()
			os.Remove(f.Name())
		}()

		_, err = io.Copy(f, resp.Body)
		if err != nil {
			http.Error(w, "reading torrent contents failed", http.StatusInternalServerError)
			return
		}

		m, err := torrent.GetMetaInfo(nil, f.Name())
		if err != nil {
			http.Error(w, "reading torrent failed", http.StatusInternalServerError)
			return
		}
		log.Printf("============> get metainfo %p", m)

		err = torrent.RunTorrents(&torrent.TorrentFlags{
			FileDir:            *root,
			SeedRatio:          math.Inf(0),
			FileSystemProvider: torrent.OsFsProvider{},
			InitialCheck:       true,
			MaxActive:          1,
			ExecOnSeeding:      "",
			Cacher:             torrent.NewRamCacheProvider(1),
		}, []string{f.Name()})

		lf := path.Join(*root, m.Info.Name)
		log.Println("==============>ls path:", lf)

		defer os.Remove(lf)

		// TODO: start another RunTorrents for configured interval
		// TODO: and remove data after that
		// TODO: or to hell with it

		if err != nil {
			http.Error(w, "downloading torrent failed", http.StatusInternalServerError)
			return
		}

		l, err := os.Open(lf)
		if err != nil {
			http.Error(w, "layer file open failed", http.StatusInternalServerError)
			return
		}

		defer l.Close()

		io.Copy(w, l)
	})

	cert := "cert.pem"
	key := "key.pem"
	err = http.ListenAndServeTLS(*listen, cert, key, mux)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}