perkeep/pkg/serverinit/env.go

113 lines
4.0 KiB
Go

/*
Copyright 2014 The Perkeep Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package serverinit
import (
"fmt"
"os"
"strings"
"perkeep.org/internal/osutil"
"perkeep.org/pkg/env"
"perkeep.org/pkg/types/serverconfig"
"cloud.google.com/go/compute/metadata"
)
// For getting a name in camlistore.net
const (
// CamliNetDNS is the hostname of the camlistore.net DNS server.
CamliNetDNS = "camnetdns.camlistore.org"
// CamliNetDomain is the camlistore.net domain name. It is relevant to
// Camlistore, because a deployment through the Camlistore on Google Cloud launcher
// automatically offers a subdomain name in this domain to any instance.
CamliNetDomain = "camlistore.net"
)
// 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:" + user + ":" + 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
}
highConf := &serverconfig.Config{
Auth: auth,
HTTPS: true,
Identity: keyId,
IdentitySecretRing: secRing,
GoogleCloudStorage: ":" + strings.TrimPrefix(blobBucket, "gs://"),
DBNames: map[string]string{},
PackRelated: true,
ShareHandler: true,
}
externalIP, _ := metadata.ExternalIP()
hostName, _ := metadata.InstanceAttributeValue("camlistore-hostname")
// If they specified a hostname (probably with pk-deploy), then:
// if it looks like an FQDN, camlistored is going to rely on Let's
// Encrypt, else camlistored is going to generate some self-signed for that
// hostname.
// Also, if the hostname is in camlistore.net, we want Camlistore to initialize
// exactly as if the instance had no hostname, so that it registers its hostname/IP
// with the camlistore.net DNS server (possibly needlessly, if the instance IP has
// not changed) again.
if hostName != "" && !strings.HasSuffix(hostName, CamliNetDomain) {
highConf.BaseURL = fmt.Sprintf("https://%s", hostName)
highConf.Listen = "0.0.0.0:443"
} else {
highConf.CamliNetIP = externalIP
}
// 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)
}