Merge "website: easier launcher dev workflow"

This commit is contained in:
mpl 2015-05-12 22:30:48 +00:00 committed by Gerrit Code Review
commit 3ec28bef79
4 changed files with 70 additions and 13 deletions

View File

@ -129,10 +129,44 @@ type DeployHandler struct {
*log.Logger
}
// Config is the set of parameters to initialize the DeployHandler.
type Config struct {
ClientID string `json:"clientID"` // handler's credentials for OAuth. required.
ClientSecret string `json:"clientSecret"` // handler's credentials for OAuth. required.
Project string `json:"project"` // any Google Cloud project we can query to get the valid Google Cloud zones. optional.
ServiceAccount string `json:"serviceAccount"` // JSON file with credentials to Project. optional.
DataDir string `json:"dataDir"` // where to store the instances configurations and states. optional.
}
// NewDeployHandlerFromConfig initializes a DeployHandler from the JSON config file.
// Host and prefix have the same meaning as for NewDeployHandler.
func NewDeployHandlerFromConfig(host, prefix, configFile string) (http.Handler, error) {
var cfg Config
data, err := ioutil.ReadFile(configFile)
if err != nil {
return nil, fmt.Errorf("Could not read handler's config at %v: %v", configFile, err)
}
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("Could not JSON decode config at %v: %v", configFile, err)
}
if cfg.ClientID == "" {
return nil, errors.New("oauth2 clientID required in config")
}
if cfg.ClientSecret == "" {
return nil, errors.New("oauth2 clientSecret required in config")
}
os.Setenv("CAMLI_GCE_CLIENTID", cfg.ClientID)
os.Setenv("CAMLI_GCE_CLIENTSECRET", cfg.ClientSecret)
os.Setenv("CAMLI_GCE_PROJECT", cfg.Project)
os.Setenv("CAMLI_GCE_SERVICE_ACCOUNT", cfg.ServiceAccount)
os.Setenv("CAMLI_GCE_DATA", cfg.DataDir)
return NewDeployHandler(host, prefix)
}
// NewDeployHandler initializes a DeployHandler that serves at https://host/prefix/ and returns it.
// A Google account client ID should be set in CAMLI_GCE_CLIENTID with its corresponding client
// secret in CAMLI_GCE_CLIENTSECRET.
func NewDeployHandler(host string, prefix string) (http.Handler, error) {
func NewDeployHandler(host, prefix string) (http.Handler, error) {
clientID := os.Getenv("CAMLI_GCE_CLIENTID")
if clientID == "" {
return nil, errors.New("Need an oauth2 client ID defined in CAMLI_GCE_CLIENTID")
@ -791,7 +825,7 @@ func dataStores() (blobserver.Storage, sorted.KeyValue, error) {
}
dataDir := os.Getenv("CAMLI_GCE_DATA")
if dataDir == "" {
dataDir = "camli-data"
dataDir = "camli-gce-data"
log.Printf("data dir not provided as env var CAMLI_GCE_DATA, so defaulting to %v", dataDir)
}
blobsDir := filepath.Join(dataDir, "instance-conf")

2
website/.gitignore vendored
View File

@ -1,3 +1,3 @@
camweb
latestgits
launcher-config.json

View File

@ -327,8 +327,30 @@ func runAsChild(res string) {
}()
}
func gceDeployHandler(host, prefix string) http.Handler {
gceh, err := gce.NewDeployHandler(host, prefix)
// gceDeployHandler conditionally returns an http.Handler for a GCE launcher,
// configured to run at /prefix/ (the trailing slash can be omitted).
// If CAMLI_GCE_CLIENTID is not set, the launcher-config.json file, if present,
// is used instead of environment variables to initialize the launcher. If a
// launcher isn't enabled, gceDeployHandler returns nil. If another error occurs,
// log.Fatal is called.
func gceDeployHandler(prefix string) http.Handler {
hostPort, err := netutil.HostPort("https://" + *httpsAddr)
if err != nil {
hostPort = "camlistore.org:443"
}
var gceh http.Handler
if e := os.Getenv("CAMLI_GCE_CLIENTID"); e != "" {
gceh, err = gce.NewDeployHandler(hostPort, prefix)
} else {
config := filepath.Join(*root, "launcher-config.json")
if _, err := os.Stat(config); err != nil {
if os.IsNotExist(err) {
return nil
}
log.Fatalf("Could not stat launcher-config.json: %v", err)
}
gceh, err = gce.NewDeployHandlerFromConfig(hostPort, prefix, config)
}
if err != nil {
log.Fatalf("Error initializing gce deploy handler: %v", err)
}
@ -339,6 +361,7 @@ func gceDeployHandler(host, prefix string) http.Handler {
if err := gceh.(*gce.DeployHandler).AddTemplateTheme(string(pageBytes)); err != nil {
log.Fatalf("Error initializing gce deploy handler: %v", err)
}
log.Printf("Starting Camlistore launcher on https://%s%s", hostPort, prefix)
return gceh
}
@ -382,13 +405,8 @@ func main() {
}
if *httpsAddr != "" {
if e := os.Getenv("CAMLI_GCE_CLIENTID"); e != "" {
hostPort, err := netutil.HostPort("https://" + *httpsAddr)
if err != nil {
hostPort = "camlistore.org:443"
}
log.Printf("Starting Camlistore launcher on https://%s/launch/", hostPort)
mux.Handle("/launch/", gceDeployHandler(hostPort, "/launch/"))
if launcher := gceDeployHandler("/launch/"); launcher != nil {
mux.Handle("/launch/", launcher)
}
}

View File

@ -42,7 +42,12 @@ if ($in_prod) {
print $fh "foo\n";
close($fh);
}
push @args, "--http=127.0.0.1:8080"; # localhost avoids Mac firewall warning
# These https certificate and key are the default ones used by devcam server.
die "TLS cert or key not initialized; run devcam server --tls" unless -e "$Bin/../config/tls.crt" && -e "$Bin/../config/tls.key";
push @args, "--tlscert=$Bin/../config/tls.crt";
push @args, "--tlskey=$Bin/../config/tls.key";
push @args, "--http=127.0.0.1:8080";
push @args, "--https=127.0.0.1:4430";
push @args, @ARGV;
exec(@args);
die "Failed to exec: $!";