-
Notifications
You must be signed in to change notification settings - Fork 288
/
controller.go
150 lines (126 loc) · 4.14 KB
/
controller.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package server
import (
"context"
"fmt"
"net"
"net/http"
"time"
"github.com/gorilla/mux"
genericapiserver "k8s.io/apiserver/pkg/server"
"github.com/tilt-dev/tilt/internal/store"
"github.com/tilt-dev/tilt/pkg/assets"
"github.com/tilt-dev/tilt/pkg/model"
)
type HeadsUpServerController struct {
host model.WebHost
port model.WebPort
hudServer *HeadsUpServer
assetServer assets.Server
apiServer *http.Server
webServer *http.Server
webURL model.WebURL
apiServerConfig *APIServerConfig
shutdown func()
}
func ProvideHeadsUpServerController(
host model.WebHost,
port model.WebPort,
apiServerConfig *APIServerConfig,
hudServer *HeadsUpServer,
assetServer assets.Server,
webURL model.WebURL) *HeadsUpServerController {
emptyCh := make(chan struct{})
close(emptyCh)
return &HeadsUpServerController{
host: host,
port: port,
hudServer: hudServer,
assetServer: assetServer,
webURL: webURL,
apiServerConfig: apiServerConfig,
shutdown: func() {},
}
}
func (s *HeadsUpServerController) TearDown(ctx context.Context) {
s.shutdown()
s.assetServer.TearDown(ctx)
ctxWeb, cancelWeb := context.WithTimeout(ctx, 10*time.Millisecond)
defer cancelWeb()
_ = s.webServer.Shutdown(ctxWeb)
ctxApi, cancelApi := context.WithTimeout(ctx, 10*time.Millisecond)
defer cancelApi()
_ = s.apiServer.Shutdown(ctxApi)
}
func (s *HeadsUpServerController) OnChange(ctx context.Context, st store.RStore, _ store.ChangeSummary) {
}
// Merge the APIServer and the Tilt Web server into a single handler,
// and attach them both to the public listener.
func (s *HeadsUpServerController) SetUp(ctx context.Context, st store.RStore) error {
ctx, cancel := context.WithCancel(ctx)
s.shutdown = cancel
err := s.setUpHelper(ctx, st)
if err != nil {
return fmt.Errorf("Cannot start the tilt-apiserver: %v", err)
}
return nil
}
func (s *HeadsUpServerController) setUpHelper(ctx context.Context, st store.RStore) error {
stopCh := ctx.Done()
config := s.apiServerConfig
server, err := config.Complete().New()
if err != nil {
return err
}
err = server.GenericAPIServer.AddPostStartHook("start-tilt-server-informers", func(context genericapiserver.PostStartHookContext) error {
if config.GenericConfig.SharedInformerFactory != nil {
config.GenericConfig.SharedInformerFactory.Start(context.StopCh)
}
return nil
})
if err != nil {
return err
}
prepared := server.GenericAPIServer.PrepareRun()
apiserverHandler := prepared.Handler
serving := config.ExtraConfig.ServingInfo
r := mux.NewRouter()
r.Path("/api").Handler(http.NotFoundHandler())
r.PathPrefix("/apis").Handler(apiserverHandler)
r.PathPrefix("/healthz").Handler(apiserverHandler)
r.PathPrefix("/livez").Handler(apiserverHandler)
r.PathPrefix("/metrics").Handler(apiserverHandler)
r.PathPrefix("/openapi").Handler(apiserverHandler)
r.PathPrefix("/readyz").Handler(apiserverHandler)
r.PathPrefix("/swagger").Handler(apiserverHandler)
r.PathPrefix("/version").Handler(apiserverHandler)
r.PathPrefix("/debug").Handler(http.DefaultServeMux) // for /debug/pprof
r.PathPrefix("/").Handler(s.hudServer.Router())
webListener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", string(s.host), int(s.port)))
if err != nil {
return fmt.Errorf("Tilt cannot start because you already have another process on port %d\n"+
"If you want to run multiple Tilt instances simultaneously,\n"+
"use the --port flag or TILT_PORT env variable to set a custom port\nOriginal error: %v",
s.port, err)
}
s.webServer = &http.Server{
Addr: webListener.Addr().String(),
Handler: s.hudServer.Router(),
}
runServer(ctx, s.webServer, webListener)
s.apiServer = &http.Server{
Addr: serving.Listener.Addr().String(),
Handler: r,
MaxHeaderBytes: 1 << 20,
}
runServer(ctx, s.apiServer, serving.Listener)
server.GenericAPIServer.RunPostStartHooks(stopCh)
go func() {
err := s.assetServer.Serve(ctx)
if err != nil && ctx.Err() == nil {
st.Dispatch(store.NewErrorAction(err))
}
}()
return nil
}
var _ store.SetUpper = &HeadsUpServerController{}
var _ store.TearDowner = &HeadsUpServerController{}