func init() { if !env.OnGCE() { return } osutil.RegisterConfigDirFunc(func() string { v, _ := metadata.InstanceAttributeValue("camlistore-config-dir") if v == "" { return v } return path.Clean("/gcs/" + strings.TrimPrefix(v, "gs://")) }) jsonconfig.RegisterFunc("_gce_instance_meta", func(c *jsonconfig.ConfigParser, v []interface{}) (interface{}, error) { if len(v) != 1 { return nil, errors.New("only 1 argument supported after _gce_instance_meta") } attr, ok := v[0].(string) if !ok { return nil, errors.New("expected argument after _gce_instance_meta to be a string") } val, err := metadata.InstanceAttributeValue(attr) if err != nil { return nil, fmt.Errorf("error reading GCE instance attribute %q: %v", attr, err) } return val, nil }) }
func detectGCE() { if !metadata.OnGCE() { return } v, _ := metadata.InstanceAttributeValue("camlistore-config-dir") isGCE = v != "" }
// DefaultEnvConfig returns the default configuration when running on a known // environment. Currently this just includes Google Compute Engine. // If the environment isn't known (nil, nil) is returned. func DefaultEnvConfig() (*Config, error) { if !env.OnGCE() { return nil, nil } auth := "none" user, _ := metadata.InstanceAttributeValue("camlistore-username") pass, _ := metadata.InstanceAttributeValue("camlistore-password") confBucket, err := metadata.InstanceAttributeValue("camlistore-config-dir") if confBucket == "" || err != nil { return nil, fmt.Errorf("VM instance metadata key 'camlistore-config-dir' not set: %v", err) } blobBucket, err := metadata.InstanceAttributeValue("camlistore-blob-dir") if blobBucket == "" || err != nil { return nil, fmt.Errorf("VM instance metadata key 'camlistore-blob-dir' not set: %v", err) } if user != "" && pass != "" { auth = "userpass:"******":" + pass } if v := osutil.SecretRingFile(); !strings.HasPrefix(v, "/gcs/") { return nil, fmt.Errorf("Internal error: secret ring path on GCE should be at /gcs/, not %q", v) } keyId, secRing, err := getOrMakeKeyring() if err != nil { return nil, err } ipOrHost, _ := metadata.ExternalIP() host, _ := metadata.InstanceAttributeValue("camlistore-hostname") if host != "" && host != "localhost" { ipOrHost = host } highConf := &serverconfig.Config{ Auth: auth, BaseURL: fmt.Sprintf("https://%s", ipOrHost), HTTPS: true, Listen: "0.0.0.0:443", Identity: keyId, IdentitySecretRing: secRing, GoogleCloudStorage: ":" + strings.TrimPrefix(blobBucket, "gs://"), DBNames: map[string]string{}, PackRelated: true, // SourceRoot is where we look for the UI js/css/html files, and the Closure resources. // Must be in sync with misc/docker/server/Dockerfile. SourceRoot: "/camlistore", } // Detect a linked Docker MySQL container. It must have alias "mysqldb". if v := os.Getenv("MYSQLDB_PORT"); strings.HasPrefix(v, "tcp://") { hostPort := strings.TrimPrefix(v, "tcp://") highConf.MySQL = "root@" + hostPort + ":" // no password highConf.DBNames["queue-sync-to-index"] = "sync_index_queue" highConf.DBNames["ui_thumbcache"] = "ui_thumbmeta_cache" highConf.DBNames["blobpacked_index"] = "blobpacked_index" } else { // TODO: also detect Cloud SQL. highConf.KVFile = "/index.kv" } return genLowLevelConfig(highConf) }