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 }