blob: 3ac83da6d7f4d9635e395e463b1f0227a9a8dd6d [file] [log] [blame]
Jiri Simsab04fbb22014-06-27 17:38:04 -07001package main
2
3import (
4 "flag"
Bogdan Caprita06829fd2014-11-06 15:56:28 -08005 "net"
Bogdan Capritae783dcc2014-11-04 14:16:55 -08006 "net/http"
Jiri Simsab04fbb22014-06-27 17:38:04 -07007 "os"
Jiri Simsab04fbb22014-06-27 17:38:04 -07008
Bogdan Caprita2f0daf12014-11-09 11:51:05 -08009 "veyron.io/veyron/veyron2/naming"
Jiri Simsa519c5072014-09-17 21:37:57 -070010 "veyron.io/veyron/veyron2/rt"
11 "veyron.io/veyron/veyron2/vlog"
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070012
Bogdan Caprita06829fd2014-11-06 15:56:28 -080013 "veyron.io/veyron/veyron/lib/netstate"
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070014 "veyron.io/veyron/veyron/lib/signals"
15 "veyron.io/veyron/veyron/profiles/roaming"
16 vflag "veyron.io/veyron/veyron/security/flag"
17 "veyron.io/veyron/veyron/services/mgmt/binary/impl"
Jiri Simsab04fbb22014-06-27 17:38:04 -070018)
19
Robin Thellend875f2592014-12-02 10:29:37 -080020const defaultDepth = 3
Jiri Simsab04fbb22014-06-27 17:38:04 -070021
Adam Sadovsky5181bdb2014-08-13 10:29:11 -070022var (
Jiri Simsa432cc2e2014-12-08 15:53:38 -080023 name = flag.String("name", "", "name to mount the binary repository as")
24 rootDirFlag = flag.String("root_dir", "", "root directory for the binary repository")
25 httpAddr = flag.String("http", ":0", "TCP address on which the HTTP server runs")
Adam Sadovsky5181bdb2014-08-13 10:29:11 -070026)
27
Bogdan Caprita06829fd2014-11-06 15:56:28 -080028// toIPPort tries to swap in the 'best' accessible IP for the host part of the
29// address, if the provided address has an unspecified IP.
30func toIPPort(addr string) string {
31 host, port, err := net.SplitHostPort(addr)
32 if err != nil {
33 vlog.Errorf("SplitHostPort(%v) failed: %v", addr, err)
34 os.Exit(1)
35 }
36 ip := net.ParseIP(host)
37 if ip.IsUnspecified() {
38 host = "127.0.0.1"
39 ips, err := netstate.GetAccessibleIPs()
40 if err == nil {
41 if a, err := roaming.ListenSpec.AddressChooser("tcp", ips); err == nil && len(a) > 0 {
42 host = a[0].Address().String()
43 }
44 }
45 }
46 return net.JoinHostPort(host, port)
47}
48
Jiri Simsab04fbb22014-06-27 17:38:04 -070049func main() {
Matt Rosencrantz5180d162014-12-03 13:48:40 -080050 runtime, err := rt.New()
51 if err != nil {
52 vlog.Fatalf("Could not initialize runtime: %v", err)
53 }
Bogdan Caprita06829fd2014-11-06 15:56:28 -080054 defer runtime.Cleanup()
Matt Rosencrantz5180d162014-12-03 13:48:40 -080055
Jiri Simsa432cc2e2014-12-08 15:53:38 -080056 rootDir, err := impl.SetupRootDir(*rootDirFlag)
Bogdan Capritae783dcc2014-11-04 14:16:55 -080057 if err != nil {
Jiri Simsa432cc2e2014-12-08 15:53:38 -080058 vlog.Errorf("SetupRootDir(%q) failed: %v", *rootDirFlag, err)
Robin Thellend875f2592014-12-02 10:29:37 -080059 return
60 }
Jiri Simsa432cc2e2014-12-08 15:53:38 -080061 vlog.Infof("Binary repository rooted at %v", rootDir)
Bogdan Capritae783dcc2014-11-04 14:16:55 -080062
Bogdan Caprita06829fd2014-11-06 15:56:28 -080063 listener, err := net.Listen("tcp", *httpAddr)
64 if err != nil {
65 vlog.Errorf("Listen(%s) failed: %v", *httpAddr, err)
66 os.Exit(1)
67 }
Jiri Simsa432cc2e2014-12-08 15:53:38 -080068 rootURL := toIPPort(listener.Addr().String())
69 state, err := impl.NewState(rootDir, rootURL, defaultDepth)
70 if err != nil {
71 vlog.Errorf("NewState(%v, %v, %v) failed: %v", rootDir, rootURL, defaultDepth, err)
72 return
73 }
74 vlog.Infof("Binary repository HTTP server at: %q", rootURL)
Bogdan Capritae783dcc2014-11-04 14:16:55 -080075 go func() {
Bogdan Caprita06829fd2014-11-06 15:56:28 -080076 if err := http.Serve(listener, http.FileServer(impl.NewHTTPRoot(state))); err != nil {
77 vlog.Errorf("Serve() failed: %v", err)
Bogdan Capritae783dcc2014-11-04 14:16:55 -080078 os.Exit(1)
79 }
80 }()
Jiri Simsab04fbb22014-06-27 17:38:04 -070081 server, err := runtime.NewServer()
82 if err != nil {
83 vlog.Errorf("NewServer() failed: %v", err)
84 return
85 }
86 defer server.Stop()
87 auth := vflag.NewAuthorizerOrDie()
Cosmos Nicolaouf8d4c2b2014-10-23 22:36:38 -070088 endpoint, err := server.Listen(roaming.ListenSpec)
Jiri Simsab04fbb22014-06-27 17:38:04 -070089 if err != nil {
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070090 vlog.Errorf("Listen(%s) failed: %v", roaming.ListenSpec, err)
Jiri Simsab04fbb22014-06-27 17:38:04 -070091 return
92 }
Cosmos Nicolaou92dba582014-11-05 17:24:10 -080093 if err := server.ServeDispatcher(*name, impl.NewDispatcher(state, auth)); err != nil {
94 vlog.Errorf("ServeDispatcher(%v) failed: %v", *name, err)
Jiri Simsab04fbb22014-06-27 17:38:04 -070095 return
96 }
Bogdan Caprita2f0daf12014-11-09 11:51:05 -080097 epName := naming.JoinAddressName(endpoint.String(), "")
98 if *name != "" {
99 vlog.Infof("Binary repository serving at %q (%q)", *name, epName)
100 } else {
101 vlog.Infof("Binary repository serving at %q", epName)
102 }
Jiri Simsab04fbb22014-06-27 17:38:04 -0700103 // Wait until shutdown.
Matt Rosencrantzc7fecf12014-11-27 19:58:43 -0800104 <-signals.ShutdownOnSignals(runtime)
Jiri Simsab04fbb22014-06-27 17:38:04 -0700105}