@@ -41,6 +41,8 @@ import (
41
41
"time"
42
42
43
43
"cloud.google.com/go/compute/metadata"
44
+ "github.com/aws/aws-sdk-go/aws/ec2metadata"
45
+ "github.com/aws/aws-sdk-go/aws/session"
44
46
"golang.org/x/build/buildlet"
45
47
"golang.org/x/build/pargzip"
46
48
)
@@ -84,12 +86,13 @@ func defaultListenAddr() string {
84
86
// root).
85
87
return ":5936"
86
88
}
87
- if ! metadata .OnGCE () {
89
+ // check if if env is dev
90
+ if ! metadata .OnGCE () && ! onEC2 () {
88
91
return "localhost:5936"
89
92
}
90
93
// In production, default to port 80 or 443, depending on
91
94
// whether TLS is configured.
92
- if metadataValue ("tls-cert" ) != "" {
95
+ if metadataValue (metaKeyTLSCert ) != "" {
93
96
return ":443"
94
97
}
95
98
return ":80"
@@ -109,6 +112,12 @@ var (
109
112
processGoCacheEnv string
110
113
)
111
114
115
+ const (
116
+ metaKeyPassword = "password"
117
+ metaKeyTLSCert = "tls-cert"
118
+ metaKeyTLSkey = "tls-key"
119
+ )
120
+
112
121
func main () {
113
122
builderEnv := os .Getenv ("GO_BUILDER_ENV" )
114
123
@@ -164,7 +173,7 @@ func main() {
164
173
* listenAddr = v
165
174
}
166
175
167
- if ! onGCE && ! isReverse && ! strings .HasPrefix (* listenAddr , "localhost:" ) {
176
+ if ! onGCE && ! isReverse && ! onEC2 () && ! strings .HasPrefix (* listenAddr , "localhost:" ) {
168
177
log .Printf ("** WARNING *** This server is unsafe and offers no security. Be careful." )
169
178
}
170
179
if onGCE {
@@ -215,7 +224,7 @@ func main() {
215
224
216
225
var password string
217
226
if ! isReverse {
218
- password = metadataValue ("password" )
227
+ password = metadataValue (metaKeyPassword )
219
228
}
220
229
requireAuth := func (handler func (w http.ResponseWriter , r * http.Request )) http.Handler {
221
230
return requirePasswordHandler {http .HandlerFunc (handler ), password }
@@ -254,7 +263,7 @@ func initGorootBootstrap() {
254
263
}
255
264
256
265
func listenForCoordinator () {
257
- tlsCert , tlsKey := metadataValue ("tls-cert" ), metadataValue ("tls-key" )
266
+ tlsCert , tlsKey := metadataValue (metaKeyTLSCert ), metadataValue (metaKeyTLSkey )
258
267
if (tlsCert == "" ) != (tlsKey == "" ) {
259
268
log .Fatalf ("tls-cert and tls-key must both be supplied, or neither." )
260
269
}
@@ -310,10 +319,48 @@ var registerSignal func(chan<- os.Signal)
310
319
311
320
var inKube = os .Getenv ("KUBERNETES_SERVICE_HOST" ) != ""
312
321
322
+ var (
323
+ // ec2UD contains a copy of the EC2 vm user data retrieved from the metadata.
324
+ ec2UD * buildlet.EC2UserData
325
+ // ec2MdC is an EC2 metadata client.
326
+ ec2MdC * ec2metadata.EC2Metadata
327
+ )
328
+
329
+ // onEC2 evaluates if the buildlet is running on an EC2 instance.
330
+ func onEC2 () bool {
331
+ if ec2MdC != nil {
332
+ return ec2MdC .Available ()
333
+ }
334
+ ses , err := session .NewSession ()
335
+ if err != nil {
336
+ log .Printf ("unable to create aws session: %s" , err )
337
+ return false
338
+ }
339
+ ec2MdC = ec2metadata .New (ses )
340
+ return ec2MdC .Available ()
341
+ }
342
+
343
+ // mdValueFromUserData maps a metadata key value into the corresponding
344
+ // EC2UserData value. If a mapping is not found, an empty string is returned.
345
+ func mdValueFromUserData (ud * buildlet.EC2UserData , key string ) string {
346
+ switch key {
347
+ case metaKeyTLSCert :
348
+ return ud .TLSCert
349
+ case metaKeyTLSkey :
350
+ return ud .TLSKey
351
+ case metaKeyPassword :
352
+ return ud .TLSPassword
353
+ default :
354
+ return ""
355
+ }
356
+ }
357
+
313
358
// metadataValue returns the GCE metadata instance value for the given key.
359
+ // If the instance is on EC2 the corresponding value will be extracted from
360
+ // the user data available via the metadata.
314
361
// If the metadata is not defined, the returned string is empty.
315
362
//
316
- // If not running on GCE, it falls back to using environment variables
363
+ // If not running on GCE or EC2 , it falls back to using environment variables
317
364
// for local development.
318
365
func metadataValue (key string ) string {
319
366
// The common case (on GCE, but not in Kubernetes):
@@ -328,6 +375,24 @@ func metadataValue(key string) string {
328
375
return v
329
376
}
330
377
378
+ if onEC2 () {
379
+ if ec2UD != nil {
380
+ return mdValueFromUserData (ec2UD , key )
381
+ }
382
+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
383
+ defer cancel ()
384
+ ec2MetaJson , err := ec2MdC .GetUserDataWithContext (ctx )
385
+ if err != nil {
386
+ log .Fatalf ("unable to retrieve EC2 user data: %v" , err )
387
+ }
388
+ ec2UD = & buildlet.EC2UserData {}
389
+ err = json .Unmarshal ([]byte (ec2MetaJson ), ec2UD )
390
+ if err != nil {
391
+ log .Fatalf ("unable to unmarshal user data json: %v" , err )
392
+ }
393
+ return mdValueFromUserData (ec2UD , key )
394
+ }
395
+
331
396
// Else allow use of environment variables to fake
332
397
// metadata keys, for Kubernetes pods or local testing.
333
398
envKey := "META_" + strings .Replace (key , "-" , "_" , - 1 )
0 commit comments