luci-go: Index | Files | Directories

package server

import ""

Package server implements an environment for running LUCI servers.

It interprets command line flags and initializes the serving environment with the following base services available via context.Context:

* Logging.
* Tracing.
* Process cache.
* Making authenticated calls.

Other functionality is optional and provided by modules (objects implementing module.Module interface). They should be passed to the server when it starts.

Usage example:

func main() {
  // When copying, please pick only modules you need.
  modules := []module.Module{
  server.Main(nil, modules, func(srv *server.Server) error {
    // Initialize global state, change root context (if necessary).
    if err := initializeGlobalStuff(srv.Context); err != nil {
      return err
    srv.Context = injectGlobalStuff(srv.Context)

    // Install regular HTTP routes.
    srv.Routes.GET("/", router.MiddlewareChain{}, func(c *router.Context) {
      // ...

    // Install pRPC services.
    servicepb.RegisterSomeServer(srv.PRPC, &SomeServer{})
    return nil


Package Files

port.go server.go

func Main Uses

func Main(opts *Options, mods []module.Module, init func(srv *Server) error)

Main initializes the server and runs its serving loop until SIGTERM.

Registers all options in the default flag set and uses `flag.Parse` to parse them. If 'opts' is nil, the default options will be used.

Additionally recognizes GAE_APPLICATION env var as an indicator that the server is running on GAE. This slightly tweaks its behavior to match what GAE expects from servers.

On errors, logs them and aborts the process with non-zero exit code.

type Options Uses

type Options struct {
    Prod     bool   // set when running in production (not on a dev workstation)
    GAE      bool   // set when running on GAE, implies Prod
    Hostname string // used for logging and metric fields, default is os.Hostname

    HTTPAddr  string // address to bind the main listening socket to
    AdminAddr string // address to bind the admin socket to, ignored on GAE

    ShutdownDelay time.Duration // how long to wait after SIGTERM before shutting down

    ClientAuth      clientauth.Options // base settings for client auth options
    TokenCacheDir   string             // where to cache auth tokens (optional)
    AuthDBPath      string             // if set, load AuthDB from a file
    AuthServiceHost string             // hostname of an Auth Service to use
    AuthDBDump      string             // Google Storage path to fetch AuthDB dumps from
    AuthDBSigner    string             // service account that signs AuthDB dumps

    CloudProject string // name of the hosting Google Cloud Project
    CloudRegion  string // name of the hosting Google Cloud region

    TraceSampling string // what portion of traces to upload to Stackdriver (ignored on GAE)

    TsMonAccount     string // service account to flush metrics as
    TsMonServiceName string // service name of tsmon target
    TsMonJobName     string // job name of tsmon target

    ProfilingDisable   bool   // set to true to explicitly disable Stackdriver Profiler
    ProfilingServiceID string // service name to associated with profiles in Stackdriver Profiler

    ContainerImageID string // ID of the container image with this binary, for logs (optional)
    // contains filtered or unexported fields

Options are used to configure the server.

Most of them are exposed as command line flags (see Register implementation). Some (mostly GAE-specific) are only settable through code or are derived from the environment.

func (*Options) FromGAEEnv Uses

func (o *Options) FromGAEEnv()

FromGAEEnv uses the GAE_APPLICATION env var (and other GAE-specific env vars) to configure the server for the GAE environment.

Does nothing if GAE_APPLICATION is not set.

Equivalent to passing the following flags:

-admin-addr -
-shutdown-delay 0s
-cloud-project ${GOOGLE_CLOUD_PROJECT}
-cloud-region <derived from the region code in GAE_APPLICATION>
-service-account-json :gce
-ts-mon-service-name ${GOOGLE_CLOUD_PROJECT}
-ts-mon-job-name ${GAE_SERVICE}

Additionally the hostname and -container-image-id (used in metric and trace fields) are derived from available GAE_* env vars to be semantically similar to what they represent in the GKE environment.

Note that a mapping between a region code in GAE_APPLICATION and the corresponding cloud region is not documented anywhere, so if you see warnings when your app starts up either update the code to recognize your region code or pass '-cloud-region' argument explicitly in app.yaml.


func (*Options) Register Uses

func (o *Options) Register(f *flag.FlagSet)

Register registers the command line flags.

type Port Uses

type Port struct {
    // Routes is a router for requests hitting this port.
    // This router is used for all requests whose Host header does not match any
    // specially registered per-host routers (see VirtualHost). Normally, there
    // are no such per-host routers, so usually Routes is used for all requests.
    // Should be populated before Server's ListenAndServe call.
    Routes *router.Router
    // contains filtered or unexported fields

Port is returned by Server's AddPort and used to setup the request routing.

func (*Port) VirtualHost Uses

func (p *Port) VirtualHost(host string) *router.Router

VirtualHost returns a router (registering it if necessary) used for requests that have the given Host header.

Note that requests that match some registered virtual host router won't reach the default router (port.Routes), even if the virtual host router doesn't have a route for them. Such requests finish with HTTP 404.

Should be called before Server's ListenAndServe (panics otherwise).

type PortOptions Uses

type PortOptions struct {
    Name           string // optional logical name of the port for logs
    ListenAddr     string // local address to bind to or "-" for a dummy port
    DisableMetrics bool   // do not collect HTTP metrics for requests on this port

PortOptions is a configuration of a single serving HTTP port.

See Server's AddPort.

type Server Uses

type Server struct {
    // Context is the root context used by all requests and background activities.
    // Can be replaced (by a derived context) before ListenAndServe call, for
    // example to inject values accessible to all request handlers.
    Context context.Context

    // Routes is a router for requests hitting HTTPAddr port.
    // This router is used for all requests whose Host header does not match any
    // specially registered per-host routers (see VirtualHost). Normally, there
    // are no such per-host routers, so usually Routes is used for all requests.
    // This router is also accessible to the server modules and they can install
    // routes into it.
    // Should be populated before ListenAndServe call.
    Routes *router.Router

    // PRPC is pRPC server with APIs exposed on HTTPAddr port via Routes router.
    // Should be populated before ListenAndServe call.
    PRPC *prpc.Server

    // Options is a copy of options passed to New.
    Options Options
    // contains filtered or unexported fields

Server is responsible for initializing and launching the serving environment.

Generally assumed to be a singleton: do not launch multiple Server instances within the same process, use AddPort instead if you want to expose multiple ports.

Doesn't do TLS. Should be sitting behind a load balancer that terminates TLS.

func New Uses

func New(ctx context.Context, opts Options, mods []module.Module) (srv *Server, err error)

New constructs a new server instance.

It hosts one or more HTTP servers and starts and stops them in unison. It is also responsible for preparing contexts for incoming requests.

The given context will become the root context of the server and will be inherited by all handlers.

On errors returns partially initialized server (always non-nil). At least its logging will be configured and can be used to report the error. Trying to use such partially initialized server for anything else is undefined behavior.

func (*Server) AddPort Uses

func (s *Server) AddPort(opts PortOptions) *Port

AddPort prepares an additional serving HTTP port.

Can be used to open more listening HTTP ports (in addition to opts.HTTPAddr and opts.AdminAddr). The returned Port object can be used to populate the router that serves requests hitting the added port.

If opts.ListenAddr is '-', a dummy port will be added: it is a valid *Port object, but it is not actually exposed as a listening TCP socket. This is useful to disable listening ports without changing any code.

Should be called before ListenAndServe (panics otherwise).

func (*Server) Fatal Uses

func (s *Server) Fatal(err error)

Fatal logs the error and immediately shuts down the process with exit code 3.

No cleanup is performed. Deferred statements are not run. Not recoverable.

func (*Server) ListenAndServe Uses

func (s *Server) ListenAndServe() error

ListenAndServe launches the serving loop.

Blocks forever or until the server is stopped via Shutdown (from another goroutine or from a SIGTERM handler). Returns nil if the server was shutdown correctly or an error if it failed to start or unexpectedly died. The error is logged inside.

Should be called only once. Panics otherwise.

func (*Server) RegisterCleanup Uses

func (s *Server) RegisterCleanup(cb func(context.Context))

RegisterCleanup registers a callback that is run in ListenAndServe after the server has exited the serving loop.

Registering a new cleanup callback from within a cleanup causes a deadlock, don't do that.

func (*Server) RegisterUnaryServerInterceptor Uses

func (s *Server) RegisterUnaryServerInterceptor(intr grpc.UnaryServerInterceptor)

RegisterUnaryServerInterceptor registers an grpc.UnaryServerInterceptor applied to all unary RPCs that hit the server.

Interceptors are chained in order they are registered, i.e. the first registered interceptor becomes the outermost. The initial chain already contains some base interceptors (e.g. for monitoring) and all interceptors registered by server modules. RegisterUnaryServerInterceptor extends this chain.

An interceptor set in server.PRPC.UnaryServerInterceptor (if any) is automatically registered as the last (innermost) one right before the server starts listening for requests in ListenAndServe.

Should be called before ListenAndServe (panics otherwise).

func (*Server) RunInBackground Uses

func (s *Server) RunInBackground(activity string, f func(context.Context))

RunInBackground launches the given callback in a separate goroutine right before starting the serving loop.

If the server is already running, launches it right away. If the server fails to start, the goroutines will never be launched.

Should be used for background asynchronous activities like reloading configs.

All logs lines emitted by the callback are annotated with "activity" field which can be arbitrary, but by convention has format "<namespace>.<name>", where "luci" namespace is reserved for internal activities.

The context passed to the callback is canceled when the server is shutting down. It is expected the goroutine will exit soon after the context is canceled.

func (*Server) Shutdown Uses

func (s *Server) Shutdown()

Shutdown gracefully stops the server if it was running.

Blocks until the server is stopped. Can be called multiple times.

func (*Server) VirtualHost Uses

func (s *Server) VirtualHost(host string) *router.Router

VirtualHost returns a router (registering it if necessary) used for requests that hit the main port (opts.HTTPAddr) and have the given Host header.

Should be used in rare cases when the server is exposed through multiple domain names and requests should be routed differently based on what domain was used. If your server is serving only one domain name, or you don't care what domain name is used to access it, do not use VirtualHost.

Note that requests that match some registered virtual host router won't reach the default router (server.Routes), even if the virtual host router doesn't have a route for them. Such requests finish with HTTP 404.

Also the router created by VirtualHost is initially completely empty: the server and its modules don't install anything into it (there's intentionally no mechanism to do this). For that reason VirtualHost should never by used to register a router for the "main" domain name: it will make the default server.Routes (and all handlers installed there by server modules) useless, probably breaking the server. Put routes for the main server functionality directly into server.Routes instead, using VirtualHost only for routes that critically depend on Host header.

Should be called before ListenAndServe (panics otherwise).


analyticsPackage analytics provides a standard way to store the Google Analytics tracking ID.
authPackage auth implements authentication and authorization framework for HTTP servers.
auth/authdbPackage authdb contains definition of Authentication Database (aka AuthDB).
auth/authdb/dumpPackage dump implements loading AuthDB from dumps in Google Storage.
auth/authtestPackage authtest implements some interfaces used by auth package to simplify unit testing.
auth/delegationPackage delegation contains low-level API for working with delegation tokens.
auth/openidPackage openid implements OpenID Connect Login protocol (client side).
auth/realmsPackage realms contains functionality related to LUCI Realms.
auth/servicePackage service implements a wrapper around API exposed by auth_service:
auth/signingPackage signing provides interfaces to sign arbitrary small blobs with RSA-SHA256 signature (PKCS1v15) and verify such signatures.
auth/signing/signingtestPackage signingtest implements signing.Signer interface using small random keys.
auth/xsrfPackage xsrf provides Cross Site Request Forgery prevention middleware.
cachingPackage caching implements common server object caches.
caching/cachingtestPackage cachingtest contains helpers for testing code that uses caching package.
caching/layeredPackage layered provides a two-layer cache for serializable objects.
gaeemulationPackage gaeemulation provides a server module that adds implementation of some APIs to the global server context.
internalPackage internal is supporting code used by server.go.
limiterPackage limiter implements load shedding for servers.
middlewarePackage middleware defines base type for context-aware HTTP request handler.
modulePackage module defines a framework for extending server.Server with optional reusable bundles of functionality (called "modules", naturally).
portalPackage portal implements HTTP routes for portal pages.
pprofPackage pprof is similar to net/http/pprof, except it supports auth.
redisconnPackage redisconn implements integration with a Redis connection pool.
routerPackage router provides an HTTP router with support for middleware and subrouters.
secretsPackage secrets provides an interface for a simple secret store: you ask it for a secret (a byte blob, identifies by some key), and it returns it to you (current version, as well as a bunch of previous versions).
secrets/testsecretsPackage testsecrets provides a dumb in-memory secret store to use in unit tests.
settingsPackage settings implements storage for infrequently changing global settings.
spanPackage span implements a server module for communicating with Cloud Spanner.
templatesPackage templates implements wrapper around html/template to provide lazy loading of templates and better integration with HTTP middleware framework.
tokensPackage tokens provides means to generate and validate base64 encoded tokens compatible with luci-py's components.auth implementation.
tqPackage tq provides a task queue implementation on top of Cloud Tasks.
tq/internal/dbPackage db defines common database interface.
tq/internal/lessorPackage lessor defines common lessor interface.
tq/internal/partitionPackage partition encapsulates partitioning and querying large keyspace which can't be expressed even as uint64.
tq/internal/reminderPackage reminder holds Reminder to avoid circular dependencies.
tq/internal/testutilPackage testutil provides fakes for testing TQ guts.
tq/tqtestingPackage tqtesting contains helpers for running server/tq in tests and on localhost.
tsmonPackage tsmon adapts common/tsmon library to a server-side environment.
warmupPackage warmup allows to register hooks executed during the server warmup.

Package server imports 57 packages (graph). Updated 2020-08-07. Refresh now. Tools for package owners.