blob: 16ac319ea979e244831f610f2dc957d889d559fb [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 (
Bogdan Caprita06829fd2014-11-06 15:56:28 -080023 name = flag.String("name", "", "name to mount the binary repository as")
Robin Thellend875f2592014-12-02 10:29:37 -080024 rootFlag = flag.String("root", "", "root directory for the binary repository")
Bogdan Caprita2f0daf12014-11-09 11:51:05 -080025 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
Robin Thellend875f2592014-12-02 10:29:37 -080056 root, err := impl.SetupRoot(*rootFlag)
Bogdan Capritae783dcc2014-11-04 14:16:55 -080057 if err != nil {
Robin Thellend875f2592014-12-02 10:29:37 -080058 vlog.Errorf("SetupRoot(%q) failed: %v", *rootFlag, err)
59 return
60 }
61 vlog.Infof("Binary repository rooted at %v", root)
62
63 state, err := impl.NewState(root, defaultDepth)
64 if err != nil {
65 vlog.Errorf("NewState(%v, %v) failed: %v", root, defaultDepth, err)
Bogdan Capritae783dcc2014-11-04 14:16:55 -080066 return
67 }
68
Bogdan Caprita06829fd2014-11-06 15:56:28 -080069 listener, err := net.Listen("tcp", *httpAddr)
70 if err != nil {
71 vlog.Errorf("Listen(%s) failed: %v", *httpAddr, err)
72 os.Exit(1)
73 }
74 vlog.Infof("Binary repository HTTP server at: %q", toIPPort(listener.Addr().String()))
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 }()
81
Jiri Simsab04fbb22014-06-27 17:38:04 -070082 server, err := runtime.NewServer()
83 if err != nil {
84 vlog.Errorf("NewServer() failed: %v", err)
85 return
86 }
87 defer server.Stop()
88 auth := vflag.NewAuthorizerOrDie()
Cosmos Nicolaouf8d4c2b2014-10-23 22:36:38 -070089 endpoint, err := server.Listen(roaming.ListenSpec)
Jiri Simsab04fbb22014-06-27 17:38:04 -070090 if err != nil {
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070091 vlog.Errorf("Listen(%s) failed: %v", roaming.ListenSpec, err)
Jiri Simsab04fbb22014-06-27 17:38:04 -070092 return
93 }
Cosmos Nicolaou92dba582014-11-05 17:24:10 -080094 if err := server.ServeDispatcher(*name, impl.NewDispatcher(state, auth)); err != nil {
95 vlog.Errorf("ServeDispatcher(%v) failed: %v", *name, err)
Jiri Simsab04fbb22014-06-27 17:38:04 -070096 return
97 }
Bogdan Caprita2f0daf12014-11-09 11:51:05 -080098 epName := naming.JoinAddressName(endpoint.String(), "")
99 if *name != "" {
100 vlog.Infof("Binary repository serving at %q (%q)", *name, epName)
101 } else {
102 vlog.Infof("Binary repository serving at %q", epName)
103 }
Jiri Simsab04fbb22014-06-27 17:38:04 -0700104 // Wait until shutdown.
Matt Rosencrantzc7fecf12014-11-27 19:58:43 -0800105 <-signals.ShutdownOnSignals(runtime)
Jiri Simsab04fbb22014-06-27 17:38:04 -0700106}