github.com/zorawar87/trillian@v1.2.1/server/trillian_log_signer/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_signer binary runs the log signing code. 16 package main 17 18 import ( 19 "context" 20 "flag" 21 "fmt" 22 "os" 23 "time" 24 25 "github.com/golang/glog" 26 "github.com/google/trillian/cmd" 27 "github.com/google/trillian/extension" 28 "github.com/google/trillian/log" 29 "github.com/google/trillian/monitoring/prometheus" 30 "github.com/google/trillian/server" 31 "github.com/google/trillian/util" 32 "github.com/google/trillian/util/election" 33 "github.com/google/trillian/util/etcd" 34 "github.com/grpc-ecosystem/grpc-gateway/runtime" 35 "google.golang.org/grpc" 36 37 tpb "github.com/google/trillian" 38 // Register pprof HTTP handlers 39 _ "net/http/pprof" 40 // Register key ProtoHandlers 41 _ "github.com/google/trillian/crypto/keys/der/proto" 42 _ "github.com/google/trillian/crypto/keys/pem/proto" 43 _ "github.com/google/trillian/crypto/keys/pkcs11/proto" 44 // Load hashers 45 _ "github.com/google/trillian/merkle/objhasher" 46 _ "github.com/google/trillian/merkle/rfc6962" 47 ) 48 49 var ( 50 rpcEndpoint = flag.String("rpc_endpoint", "localhost:8090", "Endpoint for RPC requests (host:port)") 51 httpEndpoint = flag.String("http_endpoint", "localhost:8091", "Endpoint for HTTP (host:port, empty means disabled)") 52 tlsCertFile = flag.String("tls_cert_file", "", "Path to the TLS server certificate. If unset, the server will use unsecured connections.") 53 tlsKeyFile = flag.String("tls_key_file", "", "Path to the TLS server key. If unset, the server will use unsecured connections.") 54 sequencerIntervalFlag = flag.Duration("sequencer_interval", time.Second*10, "Time between each sequencing pass through all logs") 55 batchSizeFlag = flag.Int("batch_size", 50, "Max number of leaves to process per batch") 56 numSeqFlag = flag.Int("num_sequencers", 10, "Number of sequencer workers to run in parallel") 57 sequencerGuardWindowFlag = flag.Duration("sequencer_guard_window", 0, "If set, the time elapsed before submitted leaves are eligible for sequencing") 58 forceMaster = flag.Bool("force_master", false, "If true, assume master for all logs") 59 etcdHTTPService = flag.String("etcd_http_service", "trillian-logsigner-http", "Service name to announce our HTTP endpoint under") 60 lockDir = flag.String("lock_file_path", "/test/multimaster", "etcd lock file directory path") 61 healthzTimeout = flag.Duration("healthz_timeout", time.Second*5, "Timeout used during healthz checks") 62 63 quotaIncreaseFactor = flag.Float64("quota_increase_factor", log.QuotaIncreaseFactor, 64 "Increase factor for tokens replenished by sequencing-based quotas (1 means a 1:1 relationship between sequenced leaves and replenished tokens)."+ 65 "Only effective for --quota_system=etcd.") 66 67 preElectionPause = flag.Duration("pre_election_pause", 1*time.Second, "Maximum time to wait before starting elections") 68 masterCheckInterval = flag.Duration("master_check_interval", 5*time.Second, "Interval between checking mastership still held") 69 masterHoldInterval = flag.Duration("master_hold_interval", 60*time.Second, "Minimum interval to hold mastership for") 70 resignOdds = flag.Int("resign_odds", 10, "Chance of resigning mastership after each check, the N in 1-in-N") 71 72 configFile = flag.String("config", "", "Config file containing flags, file contents can be overridden by command line flags") 73 ) 74 75 func main() { 76 flag.Parse() 77 defer glog.Flush() 78 79 if *configFile != "" { 80 if err := cmd.ParseFlagFile(*configFile); err != nil { 81 glog.Exitf("Failed to load flags from config file %q: %s", *configFile, err) 82 } 83 } 84 85 glog.CopyStandardLogTo("WARNING") 86 glog.Info("**** Log Signer Starting ****") 87 88 mf := prometheus.MetricFactory{} 89 90 sp, err := server.NewStorageProviderFromFlags(mf) 91 if err != nil { 92 glog.Exitf("Failed to get storage provider: %v", err) 93 } 94 defer sp.Close() 95 96 client, err := etcd.NewClient(*server.EtcdServers) 97 if err != nil { 98 glog.Exitf("Failed to connect to etcd at %v: %v", server.EtcdServers, err) 99 } 100 if client != nil { 101 defer client.Close() 102 } 103 104 ctx, cancel := context.WithCancel(context.Background()) 105 defer cancel() 106 go util.AwaitSignal(ctx, cancel) 107 108 hostname, _ := os.Hostname() 109 instanceID := fmt.Sprintf("%s.%d", hostname, os.Getpid()) 110 var electionFactory election.Factory 111 switch { 112 case *forceMaster: 113 glog.Warning("**** Acting as master for all logs ****") 114 electionFactory = election.NoopFactory{InstanceID: instanceID} 115 case client != nil: 116 electionFactory = etcd.NewElectionFactory(instanceID, client, *lockDir) 117 default: 118 glog.Exit("Either --force_master or --etcd_servers must be supplied") 119 } 120 121 qm, err := server.NewQuotaManagerFromFlags() 122 if err != nil { 123 glog.Exitf("Error creating quota manager: %v", err) 124 } 125 126 registry := extension.Registry{ 127 AdminStorage: sp.AdminStorage(), 128 LogStorage: sp.LogStorage(), 129 ElectionFactory: electionFactory, 130 QuotaManager: qm, 131 MetricFactory: mf, 132 } 133 134 // Start HTTP server (optional) 135 if *httpEndpoint != "" { 136 // Announce our endpoint to etcd if so configured. 137 unannounceHTTP := server.AnnounceSelf(ctx, client, *etcdHTTPService, *httpEndpoint) 138 defer unannounceHTTP() 139 } 140 141 // Start the sequencing loop, which will run until we terminate the process. This controls 142 // both sequencing and signing. 143 // TODO(Martin2112): Should respect read only mode and the flags in tree control etc 144 log.QuotaIncreaseFactor = *quotaIncreaseFactor 145 sequencerManager := server.NewSequencerManager(registry, *sequencerGuardWindowFlag) 146 info := server.LogOperationInfo{ 147 Registry: registry, 148 BatchSize: *batchSizeFlag, 149 NumWorkers: *numSeqFlag, 150 RunInterval: *sequencerIntervalFlag, 151 TimeSource: util.SystemTimeSource{}, 152 ElectionConfig: election.RunnerConfig{ 153 PreElectionPause: *preElectionPause, 154 MasterCheckInterval: *masterCheckInterval, 155 MasterHoldInterval: *masterHoldInterval, 156 ResignOdds: *resignOdds, 157 TimeSource: util.SystemTimeSource{}, 158 }, 159 } 160 sequencerTask := server.NewLogOperationManager(info, sequencerManager) 161 go sequencerTask.OperationLoop(ctx) 162 163 m := server.Main{ 164 RPCEndpoint: *rpcEndpoint, 165 HTTPEndpoint: *httpEndpoint, 166 TLSCertFile: *tlsCertFile, 167 TLSKeyFile: *tlsKeyFile, 168 StatsPrefix: "logsigner", 169 DBClose: sp.Close, 170 Registry: registry, 171 RegisterHandlerFn: func(_ context.Context, _ *runtime.ServeMux, _ string, _ []grpc.DialOption) error { 172 // No HTTP APIs are being exported. 173 return nil 174 }, 175 RegisterServerFn: func(s *grpc.Server, _ extension.Registry) error { 176 tpb.RegisterTrillianLogSequencerServer(s, &struct{}{}) 177 return nil 178 }, 179 IsHealthy: sp.AdminStorage().CheckDatabaseAccessible, 180 HealthyDeadline: *healthzTimeout, 181 } 182 183 if err := m.Run(ctx); err != nil { 184 glog.Exitf("Server exited with error: %v", err) 185 } 186 187 // Give things a few seconds to tidy up 188 glog.Infof("Stopping server, about to exit") 189 time.Sleep(time.Second * 5) 190 }