github.com/mre-fog/trillianxx@v1.1.2-0.20180615153820-ae375a99d36a/server/trillian_log_server/main.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // The trillian_log_server binary runs the Trillian log server, and also
    16  // provides an admin server.
    17  package main
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"time"
    23  
    24  	"github.com/golang/glog"
    25  	"github.com/golang/protobuf/proto"
    26  	"github.com/google/trillian"
    27  	"github.com/google/trillian/cmd"
    28  	"github.com/google/trillian/crypto/keys/der"
    29  	"github.com/google/trillian/crypto/keyspb"
    30  	"github.com/google/trillian/extension"
    31  	"github.com/google/trillian/monitoring/opencensus"
    32  	"github.com/google/trillian/monitoring/prometheus"
    33  	"github.com/google/trillian/quota/etcd/quotaapi"
    34  	"github.com/google/trillian/quota/etcd/quotapb"
    35  	"github.com/google/trillian/server"
    36  	"github.com/google/trillian/util"
    37  	"github.com/google/trillian/util/etcd"
    38  	"github.com/grpc-ecosystem/grpc-gateway/runtime"
    39  	"google.golang.org/grpc"
    40  
    41  	// Register pprof HTTP handlers
    42  	_ "net/http/pprof"
    43  	// Register key ProtoHandlers
    44  	_ "github.com/google/trillian/crypto/keys/der/proto"
    45  	_ "github.com/google/trillian/crypto/keys/pem/proto"
    46  	_ "github.com/google/trillian/crypto/keys/pkcs11/proto"
    47  	// Load hashers
    48  	_ "github.com/google/trillian/merkle/objhasher"
    49  	_ "github.com/google/trillian/merkle/rfc6962"
    50  )
    51  
    52  var (
    53  	rpcEndpoint     = flag.String("rpc_endpoint", "localhost:8090", "Endpoint for RPC requests (host:port)")
    54  	httpEndpoint    = flag.String("http_endpoint", "localhost:8091", "Endpoint for HTTP metrics and REST requests on (host:port, empty means disabled)")
    55  	healthzTimeout  = flag.Duration("healthz_timeout", time.Second*5, "Timeout used during healthz checks")
    56  	tlsCertFile     = flag.String("tls_cert_file", "", "Path to the TLS server certificate. If unset, the server will use unsecured connections.")
    57  	tlsKeyFile      = flag.String("tls_key_file", "", "Path to the TLS server key. If unset, the server will use unsecured connections.")
    58  	etcdService     = flag.String("etcd_service", "trillian-logserver", "Service name to announce ourselves under")
    59  	etcdHTTPService = flag.String("etcd_http_service", "trillian-logserver-http", "Service name to announce our HTTP endpoint under")
    60  
    61  	quotaDryRun = flag.Bool("quota_dry_run", false, "If true no requests are blocked due to lack of tokens")
    62  
    63  	treeGCEnabled            = flag.Bool("tree_gc", true, "If true, tree garbage collection (hard-deletion) is periodically performed")
    64  	treeDeleteThreshold      = flag.Duration("tree_delete_threshold", server.DefaultTreeDeleteThreshold, "Minimum period a tree has to remain deleted before being hard-deleted")
    65  	treeDeleteMinRunInterval = flag.Duration("tree_delete_min_run_interval", server.DefaultTreeDeleteMinInterval, "Minimum interval between tree garbage collection sweeps. Actual runs happen randomly between [minInterval,2*minInterval).")
    66  
    67  	tracing          = flag.Bool("tracing", false, "If true opencensus Stackdriver tracing will be enabled. See https://opencensus.io/.")
    68  	tracingProjectID = flag.String("tracing_project_id", "", "project ID to pass to stackdriver. Can be empty for GCP, consult docs for other platforms.")
    69  	tracingPercent   = flag.Int("tracing_percent", 0, "Percent of requests to be traced. Zero is a special case to use the DefaultSampler")
    70  
    71  	configFile = flag.String("config", "", "Config file containing flags, file contents can be overridden by command line flags")
    72  )
    73  
    74  func main() {
    75  	flag.Parse()
    76  	defer glog.Flush()
    77  
    78  	if *configFile != "" {
    79  		if err := cmd.ParseFlagFile(*configFile); err != nil {
    80  			glog.Exitf("Failed to load flags from config file %q: %s", *configFile, err)
    81  		}
    82  	}
    83  
    84  	ctx := context.Background()
    85  
    86  	var options []grpc.ServerOption
    87  	mf := prometheus.MetricFactory{}
    88  
    89  	if *tracing {
    90  		opts, err := opencensus.EnableRPCServerTracing(*tracingProjectID, *tracingPercent)
    91  		if err != nil {
    92  			glog.Exitf("Failed to initialize stackdriver / opencensus tracing: %v", err)
    93  		}
    94  		// Enable the server request counter tracing etc.
    95  		options = append(options, opts...)
    96  	}
    97  
    98  	sp, err := server.NewStorageProviderFromFlags(mf)
    99  	if err != nil {
   100  		glog.Exitf("Failed to get storage provider: %v", err)
   101  	}
   102  
   103  	client, err := etcd.NewClient(*server.EtcdServers)
   104  	if err != nil {
   105  		glog.Exitf("Failed to connect to etcd at %v: %v", server.EtcdServers, err)
   106  	}
   107  
   108  	// Announce our endpoints to etcd if so configured.
   109  	unannounce := server.AnnounceSelf(ctx, client, *etcdService, *rpcEndpoint)
   110  	defer unannounce()
   111  	if *httpEndpoint != "" {
   112  		unannounceHTTP := server.AnnounceSelf(ctx, client, *etcdHTTPService, *httpEndpoint)
   113  		defer unannounceHTTP()
   114  	}
   115  
   116  	qm, err := server.NewQuotaManagerFromFlags()
   117  	if err != nil {
   118  		glog.Exitf("Error creating quota manager: %v", err)
   119  	}
   120  
   121  	registry := extension.Registry{
   122  		AdminStorage:  sp.AdminStorage(),
   123  		LogStorage:    sp.LogStorage(),
   124  		QuotaManager:  qm,
   125  		MetricFactory: mf,
   126  		NewKeyProto: func(ctx context.Context, spec *keyspb.Specification) (proto.Message, error) {
   127  			return der.NewProtoFromSpec(spec)
   128  		},
   129  	}
   130  
   131  	m := server.Main{
   132  		RPCEndpoint:  *rpcEndpoint,
   133  		HTTPEndpoint: *httpEndpoint,
   134  		TLSCertFile:  *tlsCertFile,
   135  		TLSKeyFile:   *tlsKeyFile,
   136  		StatsPrefix:  "log",
   137  		ExtraOptions: options,
   138  		QuotaDryRun:  *quotaDryRun,
   139  		DBClose:      sp.Close,
   140  		Registry:     registry,
   141  		RegisterHandlerFn: func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error {
   142  			if err := trillian.RegisterTrillianLogHandlerFromEndpoint(ctx, mux, endpoint, opts); err != nil {
   143  				return err
   144  			}
   145  			if *server.QuotaSystem == server.QuotaEtcd {
   146  				return quotapb.RegisterQuotaHandlerFromEndpoint(ctx, mux, endpoint, opts)
   147  			}
   148  			return nil
   149  		},
   150  		RegisterServerFn: func(s *grpc.Server, registry extension.Registry) error {
   151  			ts := util.SystemTimeSource{}
   152  			logServer := server.NewTrillianLogRPCServer(registry, ts)
   153  			if err := logServer.IsHealthy(); err != nil {
   154  				return err
   155  			}
   156  			trillian.RegisterTrillianLogServer(s, logServer)
   157  			if *server.QuotaSystem == server.QuotaEtcd {
   158  				quotapb.RegisterQuotaServer(s, quotaapi.NewServer(client))
   159  			}
   160  			return nil
   161  		},
   162  		IsHealthy: func(ctx context.Context) error {
   163  			as := sp.AdminStorage()
   164  			return as.CheckDatabaseAccessible(ctx)
   165  		},
   166  		HealthyDeadline:       *healthzTimeout,
   167  		AllowedTreeTypes:      []trillian.TreeType{trillian.TreeType_LOG, trillian.TreeType_PREORDERED_LOG},
   168  		TreeGCEnabled:         *treeGCEnabled,
   169  		TreeDeleteThreshold:   *treeDeleteThreshold,
   170  		TreeDeleteMinInterval: *treeDeleteMinRunInterval,
   171  	}
   172  
   173  	if err := m.Run(ctx); err != nil {
   174  		glog.Exitf("Server exited with error: %v", err)
   175  	}
   176  }