2011-11-24 18:53:05 -07:00
|
|
|
// Copyright 2011 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package build
|
|
|
|
|
2011-12-22 08:21:59 -07:00
|
|
|
import (
|
|
|
|
"sync"
|
2011-11-24 18:53:05 -07:00
|
|
|
|
2011-12-22 08:21:59 -07:00
|
|
|
"appengine"
|
|
|
|
"appengine/datastore"
|
|
|
|
)
|
|
|
|
|
|
|
|
var theKey struct {
|
|
|
|
sync.RWMutex
|
|
|
|
BuilderKey
|
|
|
|
}
|
|
|
|
|
|
|
|
type BuilderKey struct {
|
|
|
|
Secret string
|
2011-11-24 18:53:05 -07:00
|
|
|
}
|
|
|
|
|
2011-12-22 08:21:59 -07:00
|
|
|
func (k *BuilderKey) Key(c appengine.Context) *datastore.Key {
|
|
|
|
return datastore.NewKey(c, "BuilderKey", "root", 0, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func secretKey(c appengine.Context) string {
|
|
|
|
// check with rlock
|
|
|
|
theKey.RLock()
|
|
|
|
k := theKey.Secret
|
|
|
|
theKey.RUnlock()
|
|
|
|
if k != "" {
|
|
|
|
return k
|
|
|
|
}
|
|
|
|
|
|
|
|
// prepare to fill; check with lock and keep lock
|
|
|
|
theKey.Lock()
|
|
|
|
defer theKey.Unlock()
|
|
|
|
if theKey.Secret != "" {
|
|
|
|
return theKey.Secret
|
|
|
|
}
|
|
|
|
|
|
|
|
// fill
|
|
|
|
if err := datastore.Get(c, theKey.Key(c), &theKey.BuilderKey); err != nil {
|
|
|
|
if err == datastore.ErrNoSuchEntity {
|
|
|
|
// If the key is not stored in datastore, write it.
|
|
|
|
// This only happens at the beginning of a new deployment.
|
|
|
|
// The code is left here for SDK use and in case a fresh
|
|
|
|
// deployment is ever needed. "gophers rule" is not the
|
|
|
|
// real key.
|
|
|
|
if !appengine.IsDevAppServer() {
|
|
|
|
panic("lost key from datastore")
|
|
|
|
}
|
|
|
|
theKey.Secret = "gophers rule"
|
|
|
|
datastore.Put(c, theKey.Key(c), &theKey.BuilderKey)
|
|
|
|
return theKey.Secret
|
|
|
|
}
|
2012-02-05 15:26:32 -07:00
|
|
|
panic("cannot load builder key: " + err.Error())
|
2011-12-22 08:21:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return theKey.Secret
|
|
|
|
}
|