Chromium Code Reviews| Index: server/internal/logdog/service/service.go |
| diff --git a/server/internal/logdog/service/service.go b/server/internal/logdog/service/service.go |
| index b3d5874eec9d1c9c4f5fca65424e8f65e8c0953e..0850cf501e52bc3f0a5197fe08c1412e9fc1d903 100644 |
| --- a/server/internal/logdog/service/service.go |
| +++ b/server/internal/logdog/service/service.go |
| @@ -14,10 +14,12 @@ import ( |
| "path/filepath" |
| "runtime/pprof" |
| "sync/atomic" |
| + "time" |
| "github.com/luci/luci-go/client/authcli" |
| "github.com/luci/luci-go/common/api/logdog_coordinator/services/v1" |
| "github.com/luci/luci-go/common/auth" |
| + luciConfig "github.com/luci/luci-go/common/config" |
| "github.com/luci/luci-go/common/gcloud/gs" |
| log "github.com/luci/luci-go/common/logging" |
| "github.com/luci/luci-go/common/logging/gologger" |
| @@ -32,6 +34,7 @@ import ( |
| "github.com/luci/luci-go/server/logdog/storage/bigtable" |
| "golang.org/x/net/context" |
| "google.golang.org/cloud" |
| + "google.golang.org/cloud/compute/metadata" |
| ) |
| var ( |
| @@ -49,6 +52,10 @@ var ( |
| "Set to one when service is present and ready. Alert on missing values.") |
| ) |
| +// projectConfigCacheDuration is the amount of time to cache a project's |
| +// configuration before reloading. |
| +const projectConfigCacheDuration = 30 * time.Minute |
| + |
| // Service is a base class full of common LogDog service application parameters. |
| type Service struct { |
| // Name is the name of this service. It is used for logging, metrics, and |
| @@ -68,12 +75,15 @@ type Service struct { |
| coordinatorHost string |
| coordinatorInsecure bool |
| + projectID string |
| storageCredentialJSONPath string |
| cpuProfilePath string |
| heapProfilePath string |
| coord logdog.ServicesClient |
| config *config.Manager |
| + |
| + onGCE bool |
| } |
| // Run performs service-wide initialization and invokes the specified run |
| @@ -141,6 +151,17 @@ func (s *Service) runImpl(c context.Context, f func(context.Context) error) erro |
| }() |
| } |
| + // Are we running on a GCE intance? |
| + if err := s.probeGCEEnvironment(c); err != nil { |
| + log.WithError(err).Errorf(c, "Failed to probe GCE environment.") |
| + return err |
| + } |
| + |
| + // Validate the runtime environment. |
| + if s.projectID == "" { |
| + return errors.New("no project ID was configured") |
| + } |
| + |
| // Configure our signal handler. It will listen for terminating signals and |
| // issue a shutdown signal if one is received. |
| signalC := make(chan os.Signal) |
| @@ -221,6 +242,10 @@ func (s *Service) addFlags(c context.Context, fs *flag.FlagSet) { |
| s.authFlags.Register(fs, auth.Options{}) |
| s.configFlags.AddToFlagSet(fs) |
| + fs.StringVar(&s.projectID, "project-id", "", |
| + "Specify the cloud project ID that this instance is supporting. If empty, the project ID "+ |
|
nodir
2016/05/18 16:25:51
Please rename to "app-id". Gcp SDK calls it "app"
dnj (Google)
2016/05/18 16:50:31
I'm using the luci-config concept here, not the GA
nodir
2016/05/18 17:02:19
Then why it says cloud project and why this flag i
|
| + "will attempt to be resolved by probing the local environment. This probably will match the "+ |
| + "App ID of the Coordinator.") |
| fs.StringVar(&s.coordinatorHost, "coordinator", "", |
| "The Coordinator service's [host][:port].") |
| fs.BoolVar(&s.coordinatorInsecure, "coordinator-insecure", false, |
| @@ -233,6 +258,28 @@ func (s *Service) addFlags(c context.Context, fs *flag.FlagSet) { |
| "If supplied, enable CPU profiling and write the profile here.") |
| } |
| +// probeGCEEnvironment fills in any parameters that can be probed from Google |
| +// Compute Engine metadata. |
| +// |
| +// If we're not running on GCE, this will return nil. An error will only be |
| +// returned if an operation that is expected to work fails. |
| +func (s *Service) probeGCEEnvironment(c context.Context) error { |
| + s.onGCE = metadata.OnGCE() |
| + if !s.onGCE { |
| + return nil |
| + } |
| + |
| + // Determine our project ID. |
| + if s.projectID == "" { |
| + var err error |
| + if s.projectID, err = metadata.ProjectID(); err != nil { |
| + log.WithError(err).Errorf(c, "Failed to probe GCE project ID.") |
| + return err |
| + } |
| + } |
| + return nil |
| +} |
| + |
| func (s *Service) initCoordinatorClient(c context.Context) (logdog.ServicesClient, error) { |
| if s.coordinatorHost == "" { |
| log.Errorf(c, "Missing Coordinator URL (-coordinator).") |
| @@ -275,6 +322,8 @@ func (s *Service) initConfig(c context.Context) (*config.Manager, error) { |
| log.WithError(err).Errorf(c, "Failed to load configuration parameters.") |
| return nil, err |
| } |
| + o.ProjectID = s.projectID |
| + o.ProjectConfigCacheDuration = projectConfigCacheDuration |
| o.KillFunc = s.shutdown |
| return config.NewManager(c, *o) |
| @@ -303,11 +352,25 @@ func (s *Service) Config() *svcconfig.Config { |
| return s.config.Config() |
| } |
| +// ProjectConfig returns the cached project configuration. |
| +// |
| +// If the project configuration is not available, nil will be returned. |
| +func (s *Service) ProjectConfig(c context.Context, proj luciConfig.ProjectName) (*svcconfig.ProjectConfig, error) { |
| + return s.config.ProjectConfig(c, proj) |
| +} |
| + |
| // Coordinator returns the cached Coordinator client. |
| func (s *Service) Coordinator() logdog.ServicesClient { |
| return s.coord |
| } |
| +// ProjectID returns the project ID. |
| +// |
| +// This is synonymous with the AppEngine "app ID". |
| +func (s *Service) ProjectID() string { |
| + return s.projectID |
| +} |
| + |
| // IntermediateStorage instantiates the configured intermediate Storage |
| // instance. |
| func (s *Service) IntermediateStorage(c context.Context) (storage.Storage, error) { |