2014-08-07 00:00:58 +00:00
/ *
Copyright 2014 The Camlistore 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 .
* /
2014-08-07 19:33:52 +00:00
// Package gce configures hooks for running Camlistore for Google Compute Engine.
2016-03-14 01:59:26 +00:00
package gce // import "camlistore.org/pkg/osutil/gce"
2014-08-07 00:00:58 +00:00
import (
"errors"
"fmt"
2015-08-18 08:03:47 +00:00
"io"
"log"
"os"
2014-08-07 19:33:52 +00:00
"path"
"strings"
2014-08-07 00:00:58 +00:00
2015-04-01 15:37:32 +00:00
"camlistore.org/pkg/env"
2014-08-07 19:33:52 +00:00
"camlistore.org/pkg/osutil"
2015-12-04 17:23:15 +00:00
2016-09-07 18:27:11 +00:00
"cloud.google.com/go/compute/metadata"
"cloud.google.com/go/logging"
2015-12-01 16:19:49 +00:00
"go4.org/jsonconfig"
2015-12-04 17:23:15 +00:00
_ "go4.org/wkfs/gcs"
2015-09-22 12:48:04 +00:00
"golang.org/x/net/context"
2014-08-07 00:00:58 +00:00
)
func init ( ) {
2015-04-01 15:37:32 +00:00
if ! env . OnGCE ( ) {
2014-08-07 00:00:58 +00:00
return
}
2014-08-07 19:33:52 +00:00
osutil . RegisterConfigDirFunc ( func ( ) string {
2015-04-01 15:37:32 +00:00
v , _ := metadata . InstanceAttributeValue ( "camlistore-config-dir" )
2014-08-07 19:33:52 +00:00
if v == "" {
return v
}
return path . Clean ( "/gcs/" + strings . TrimPrefix ( v , "gs://" ) )
} )
2014-08-07 00:00:58 +00:00
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" )
}
2015-04-01 15:37:32 +00:00
val , err := metadata . InstanceAttributeValue ( attr )
2014-08-07 00:00:58 +00:00
if err != nil {
return nil , fmt . Errorf ( "error reading GCE instance attribute %q: %v" , attr , err )
}
return val , nil
} )
}
2015-08-18 08:03:47 +00:00
// LogWriter returns an environment-specific io.Writer suitable for passing
// to log.SetOutput. It will also include writing to os.Stderr as well.
func LogWriter ( ) ( w io . Writer ) {
w = os . Stderr
if ! env . OnGCE ( ) {
return
}
projID , err := metadata . ProjectID ( )
if projID == "" {
log . Printf ( "Error getting project ID: %v" , err )
return
}
2015-08-24 22:30:30 +00:00
scopes , _ := metadata . Scopes ( "default" )
haveScope := func ( scope string ) bool {
for _ , x := range scopes {
if x == scope {
return true
}
}
return false
}
if ! haveScope ( logging . Scope ) {
log . Printf ( "when this Google Compute Engine VM instance was created, it wasn't granted enough access to use Google Cloud Logging (Scope URL: %v)." , logging . Scope )
return
}
2015-09-22 12:48:04 +00:00
logc , err := logging . NewClient ( context . Background ( ) , projID , "camlistored-stderr" )
2015-08-18 08:03:47 +00:00
if err != nil {
log . Printf ( "Error creating Google logging client: %v" , err )
return
}
return io . MultiWriter ( w , logc . Writer ( logging . Debug ) )
}