@@ -6,33 +6,20 @@ package main
6
6
import (
7
7
"context"
8
8
"errors"
9
- "expvar"
10
9
"fmt"
11
10
"io"
12
11
"log"
13
12
"net"
14
13
"net/http"
15
14
"os"
16
15
"os/signal"
17
- "path"
18
- "path/filepath"
19
16
"strconv"
20
- "strings"
21
17
"syscall"
22
18
"time"
23
19
24
- "github.com/aws/aws-sdk-go-v2/config"
25
- "github.com/aws/aws-sdk-go-v2/service/s3"
26
20
"github.com/creachadair/command"
27
21
"github.com/creachadair/gocache"
28
- "github.com/creachadair/gocache/cachedir"
29
22
"github.com/creachadair/taskgroup"
30
- "github.com/goproxy/goproxy"
31
- "github.com/tailscale/go-cache-plugin/internal/s3util"
32
- "github.com/tailscale/go-cache-plugin/revproxy"
33
- "github.com/tailscale/go-cache-plugin/s3cache"
34
- "github.com/tailscale/go-cache-plugin/s3proxy"
35
- "tailscale.com/tsweb"
36
23
)
37
24
38
25
var flags struct {
@@ -49,63 +36,6 @@ var flags struct {
49
36
DebugLog bool `flag:"debug,default=$GOCACHE_DEBUG,Enable detailed per-request debug logging (noisy)"`
50
37
}
51
38
52
- func initCacheServer (env * command.Env ) (* gocache.Server , * s3util.Client , error ) {
53
- switch {
54
- case flags .CacheDir == "" :
55
- return nil , nil , env .Usagef ("you must provide a --cache-dir" )
56
- case flags .S3Bucket == "" :
57
- return nil , nil , env .Usagef ("you must provide an S3 --bucket name" )
58
- }
59
- region , err := getBucketRegion (env .Context (), flags .S3Bucket )
60
- if err != nil {
61
- return nil , nil , env .Usagef ("you must provide an S3 --region name" )
62
- }
63
-
64
- dir , err := cachedir .New (flags .CacheDir )
65
- if err != nil {
66
- return nil , nil , fmt .Errorf ("create local cache: %w" , err )
67
- }
68
-
69
- cfg , err := config .LoadDefaultConfig (env .Context (), config .WithRegion (region ))
70
- if err != nil {
71
- return nil , nil , fmt .Errorf ("laod AWS config: %w" , err )
72
- }
73
-
74
- vprintf ("local cache directory: %s" , flags .CacheDir )
75
- vprintf ("S3 cache bucket %q (%s)" , flags .S3Bucket , region )
76
- client := & s3util.Client {
77
- Client : s3 .NewFromConfig (cfg ),
78
- Bucket : flags .S3Bucket ,
79
- }
80
- cache := & s3cache.Cache {
81
- Local : dir ,
82
- S3Client : client ,
83
- KeyPrefix : flags .KeyPrefix ,
84
- MinUploadSize : flags .MinUploadSize ,
85
- UploadConcurrency : flags .S3Concurrency ,
86
- }
87
- cache .SetMetrics (env .Context (), expvar .NewMap ("gocache_host" ))
88
-
89
- close := cache .Close
90
- if flags .Expiration > 0 {
91
- dirClose := dir .Cleanup (flags .Expiration )
92
- close = func (ctx context.Context ) error {
93
- return errors .Join (cache .Close (ctx ), dirClose (ctx ))
94
- }
95
- }
96
- s := & gocache.Server {
97
- Get : cache .Get ,
98
- Put : cache .Put ,
99
- Close : close ,
100
- SetMetrics : cache .SetMetrics ,
101
- MaxRequests : flags .Concurrency ,
102
- Logf : vprintf ,
103
- LogRequests : flags .DebugLog ,
104
- }
105
- expvar .Publish ("gocache_server" , s .Metrics ().Get ("server" ))
106
- return s , client , nil
107
- }
108
-
109
39
// runDirect runs a cache communicating on stdin/stdout, for use as a direct
110
40
// GOCACHEPROG plugin.
111
41
func runDirect (env * command.Env ) error {
@@ -160,93 +90,41 @@ func runServe(env *command.Env) error {
160
90
var g taskgroup.Group
161
91
g .Go (taskgroup .NoError (func () {
162
92
<- ctx .Done ()
163
- log .Printf ("signal received, closing listener" )
93
+ log .Printf ("closing plugin listener" )
164
94
lst .Close ()
165
95
}))
166
96
167
- // If an HTTP server is enabled, start it up with debug routes.
168
- // If enabled, the module proxy and reverse cache attach to mux below.
169
- var mux * http.ServeMux
97
+ // If a module proxy is enabled, start it.
98
+ modProxy , modCleanup , err := initModProxy (env .SetContext (ctx ), s3c )
99
+ if err != nil {
100
+ lst .Close ()
101
+ return fmt .Errorf ("module proxy: %w" , err )
102
+ }
103
+ defer modCleanup ()
104
+
105
+ // If a reverse proxy is enabled, start it.
106
+ revProxy , err := initRevProxy (env .SetContext (ctx ), s3c , & g )
107
+ if err != nil {
108
+ lst .Close ()
109
+ return fmt .Errorf ("reverse proxy: %w" , err )
110
+ }
111
+
112
+ // If an HTTP server is enabled, start it up with debug routes
113
+ // and whatever other services were requested.
170
114
if serveFlags .HTTP != "" {
171
- mux = http .NewServeMux ()
172
- tsweb .Debugger (mux )
173
115
srv := & http.Server {
174
116
Addr : serveFlags .HTTP ,
175
- Handler : mux ,
117
+ Handler : makeHandler ( modProxy , revProxy ) ,
176
118
}
177
119
g .Go (srv .ListenAndServe )
178
120
vprintf ("HTTP server listening at %q" , serveFlags .HTTP )
179
121
g .Go (taskgroup .NoError (func () {
180
122
<- ctx .Done ()
181
- vprintf ("signal received, stopping HTTP service" )
123
+ vprintf ("stopping HTTP service" )
182
124
srv .Shutdown (context .Background ())
183
125
}))
184
126
}
185
127
186
- // If a module proxy is enabled, start it.
187
- if serveFlags .ModProxy {
188
- if mux == nil {
189
- return env .Usagef ("you must set --http to enable --modproxy" )
190
- }
191
- modCachePath := filepath .Join (flags .CacheDir , "module" )
192
- if err := os .MkdirAll (modCachePath , 0700 ); err != nil {
193
- lst .Close ()
194
- return fmt .Errorf ("create module cache: %w" , err )
195
- }
196
- cacher := & s3proxy.Cacher {
197
- Local : modCachePath ,
198
- S3Client : s3c ,
199
- KeyPrefix : path .Join (flags .KeyPrefix , "module" ),
200
- MaxTasks : flags .S3Concurrency ,
201
- LogRequests : flags .DebugLog ,
202
- Logf : vprintf ,
203
- }
204
- defer func () {
205
- vprintf ("close cacher (err=%v)" , cacher .Close ())
206
- }()
207
- proxy := & goproxy.Goproxy {
208
- Fetcher : & goproxy.GoFetcher {
209
- // As configured, the fetcher should never shell out to the go
210
- // tool. Specifically, because we set GOPROXY and do not set any
211
- // bypass via GONOPROXY, GOPRIVATE, etc., we will only attempt to
212
- // proxy for the specific server(s) listed in Env.
213
- GoBin : "/bin/false" ,
214
- Env : []string {"GOPROXY=https://proxy.golang.org" },
215
- },
216
- Cacher : cacher ,
217
- ProxiedSumDBs : []string {"sum.golang.org" }, // default, see below
218
- }
219
- vprintf ("enabling Go module proxy" )
220
- if serveFlags .SumDB != "" {
221
- proxy .ProxiedSumDBs = strings .Split (serveFlags .SumDB , "," )
222
- vprintf ("enabling sum DB proxy for %s" , strings .Join (proxy .ProxiedSumDBs , ", " ))
223
- }
224
- expvar .Publish ("modcache" , cacher .Metrics ())
225
- mux .Handle ("/mod/" , http .StripPrefix ("/mod" , proxy ))
226
- }
227
-
228
- // If a reverse proxy is enabled, start it.
229
- if serveFlags .RevProxy != "" {
230
- if mux == nil {
231
- return env .Usagef ("you must set --http to enable --revproxy" )
232
- }
233
- revCachePath := filepath .Join (flags .CacheDir , "revproxy" )
234
- if err := os .MkdirAll (revCachePath , 0700 ); err != nil {
235
- lst .Close ()
236
- return fmt .Errorf ("create revproxy cache: %w" , err )
237
- }
238
- proxy := & revproxy.Server {
239
- Targets : strings .Split (serveFlags .RevProxy , "," ),
240
- Local : revCachePath ,
241
- S3Client : s3c ,
242
- KeyPrefix : path .Join (flags .KeyPrefix , "revproxy" ),
243
- Logf : vprintf ,
244
- }
245
- expvar .Publish ("revcache" , proxy .Metrics ())
246
- vprintf ("enabling reverse proxy for %s" , strings .Join (proxy .Targets , ", " ))
247
- mux .Handle ("/" , proxy )
248
- }
249
-
250
128
for {
251
129
conn , err := lst .Accept ()
252
130
if err != nil {
0 commit comments