Skip to content

Commit

Permalink
Move server/trillian_log_signer to allow both file based config or fl…
Browse files Browse the repository at this point in the history
…ag based
  • Loading branch information
Roland Shoemaker committed May 17, 2017
1 parent 6fc62e7 commit 1019686
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 50 deletions.
11 changes: 3 additions & 8 deletions examples/ct/ct_server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ type config struct {
Host string
Port int
LogRPCServer string
RPCDeadline string
rpcDeadline time.Duration // work around required since you can't unmarshal into time.Duration
RPCDeadline util.ConfigDuration
LogConfig string
MaxGetEntriesAllowed int64
EtcdServers string
Expand All @@ -54,7 +53,7 @@ func main() {
flag.StringVar(&c.Host, "host", "localhost", "Address to serve CT log requests on")
flag.IntVar(&c.Port, "port", 6962, "Port to serve CT log requests on")
flag.StringVar(&c.LogRPCServer, "log_rpc_server", "localhost:8090", "Backend specification; comma-separated list or etcd service name (if --etcd_servers specified)")
flag.DurationVar(&c.rpcDeadline, "rpc_deadline", time.Second*10, "Deadline for backend RPC requests")
flag.DurationVar(&c.RPCDeadline.Duration, "rpc_deadline", time.Second*10, "Deadline for backend RPC requests")
flag.StringVar(&c.LogConfig, "log_config", "", "File holding log config in JSON")
flag.Int64Var(&c.MaxGetEntriesAllowed, "maxGetEntriesAllowed", 0, "Max number of entries we allow in a get-entries request (default 50)")
flag.StringVar(&c.EtcdServers, "etcd_servers", "", "A comma-separated list of etcd servers")
Expand All @@ -72,10 +71,6 @@ func main() {
if err := json.Unmarshal(f, &c); err != nil {
glog.Exitf("Failed to parse config file: %v", err)
}
c.rpcDeadline, err = time.ParseDuration(c.RPCDeadline)
if err != nil {
glog.Exitf("Cannot parse RPCDeadline: %v", err)
}
}

if c.MaxGetEntriesAllowed > 0 {
Expand Down Expand Up @@ -116,7 +111,7 @@ func main() {
client := trillian.NewTrillianLogClient(conn)

for _, cfg := range ctCfg {
handlers, err := cfg.SetUpInstance(client, c.rpcDeadline)
handlers, err := cfg.SetUpInstance(client, c.RPCDeadline.Duration)
if err != nil {
glog.Exitf("Failed to set up log instance for %+v: %v", cfg, err)
}
Expand Down
11 changes: 3 additions & 8 deletions server/trillian_log_server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ type config struct {
MySQLURI string
RPCEndpoint string
HTTPEndpoint string
DumpMetricsInterval string
dumpMetricsInterval time.Duration // work around required since you can't unmarshal into time.Duration
DumpMetricsInterval util.ConfigDuration
EtcdServers string
EtcdService string
}
Expand All @@ -59,7 +58,7 @@ func main() {
flag.StringVar(&c.MySQLURI, "mysql_uri", "test:zaphod@tcp(127.0.0.1:3306)/test", "Connection URI for MySQL database")
flag.StringVar(&c.RPCEndpoint, "rpc_endpoint", "localhost:8090", "Endpoint for RPC requests (host:port)")
flag.StringVar(&c.HTTPEndpoint, "http_endpoint", "localhost:8091", "Endpoint for HTTP metrics and REST requests on (host:port, empty means disabled)")
flag.DurationVar(&c.dumpMetricsInterval, "dump_metrics_interval", 0, "If greater than 0, how often to dump metrics to the logs.")
flag.DurationVar(&c.DumpMetricsInterval.Duration, "dump_metrics_interval", 0, "If greater than 0, how often to dump metrics to the logs.")
flag.StringVar(&c.EtcdServers, "etcd_servers", "", "A comma-separated list of etcd servers; no etcd registration if empty")
flag.StringVar(&c.EtcdService, "etcd_service", "trillian-log", "Service name to announce ourselves under")
flag.Parse()
Expand All @@ -76,10 +75,6 @@ func main() {
if err := json.Unmarshal(f, &c); err != nil {
glog.Exitf("Failed to parse config file: %v", err)
}
c.dumpMetricsInterval, err = time.ParseDuration(c.DumpMetricsInterval)
if err != nil {
glog.Exitf("Cannot parse DumpMetricsInterval: %v", err)
}
}

ctx := context.Background()
Expand Down Expand Up @@ -142,7 +137,7 @@ func main() {
trillian.RegisterTrillianLogServer(s, logServer)
return err
},
DumpMetricsInterval: c.dumpMetricsInterval,
DumpMetricsInterval: c.DumpMetricsInterval.Duration,
}

if err := m.Run(ctx); err != nil {
Expand Down
102 changes: 68 additions & 34 deletions server/trillian_log_signer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"time"

Expand All @@ -34,37 +36,69 @@ import (
"golang.org/x/net/context"
)

var (
mySQLURI = flag.String("mysql_uri", "test:zaphod@tcp(127.0.0.1:3306)/test", "Connection URI for MySQL database")
httpEndpoint = flag.String("http_endpoint", "localhost:8091", "Endpoint for HTTP (host:port, empty means disabled)")
sequencerIntervalFlag = flag.Duration("sequencer_interval", time.Second*10, "Time between each sequencing pass through all logs")
batchSizeFlag = flag.Int("batch_size", 50, "Max number of leaves to process per batch")
numSeqFlag = flag.Int("num_sequencers", 10, "Number of sequencer workers to run in parallel")
sequencerGuardWindowFlag = flag.Duration("sequencer_guard_window", 0, "If set, the time elapsed before submitted leaves are eligible for sequencing")
dumpMetricsInterval = flag.Duration("dump_metrics_interval", 0, "If greater than 0, how often to dump metrics to the logs.")
forceMaster = flag.Bool("force_master", false, "If true, assume master for all logs")
etcdServers = flag.String("etcd_servers", "localhost:2379", "A comma-separated list of etcd servers")
lockDir = flag.String("lock_file_path", "/test/multimaster", "etcd lock file directory path")

preElectionPause = flag.Duration("pre_election_pause", 1*time.Second, "Maximum time to wait before starting elections")
masterCheckInterval = flag.Duration("master_check_interval", 5*time.Second, "Interval between checking mastership still held")
masterHoldInterval = flag.Duration("master_hold_interval", 60*time.Second, "Minimum interval to hold mastership for")
resignOdds = flag.Int("resign_odds", 10, "Chance of resigning mastership after each check, the N in 1-in-N")
)
type config struct {
MySQLURI string
HTTPEndpoint string
SequencerInterval util.ConfigDuration
BatchSize int
NumSequencers int
SequencerGuardWindow util.ConfigDuration
DumpMetricsInterval util.ConfigDuration
ForceMaster bool
EtcdServers string
LockFilePath string
PreElectionPause util.ConfigDuration
MasterCheckInterval util.ConfigDuration
MasterHoldInterval util.ConfigDuration
ResignOdds int
}

var configFlag = flag.String("config", "", "Path to JSON config file to load instead of providing config via flags, if provided should be the only flag")

func main() {
c := config{}
flag.StringVar(&c.MySQLURI, "mysql_uri", "test:zaphod@tcp(127.0.0.1:3306)/test", "Connection URI for MySQL database")
flag.StringVar(&c.HTTPEndpoint, "http_endpoint", "localhost:8091", "Endpoint for HTTP (host:port, empty means disabled)")
flag.DurationVar(&c.SequencerInterval.Duration, "sequencer_interval", time.Second*10, "Time between each sequencing pass through all logs")
flag.IntVar(&c.BatchSize, "batch_size", 50, "Max number of leaves to process per batch")
flag.IntVar(&c.NumSequencers, "num_sequencers", 10, "Number of sequencer workers to run in parallel")
flag.DurationVar(&c.SequencerGuardWindow.Duration, "sequencer_guard_window", 0, "If set, the time elapsed before submitted leaves are eligible for sequencing")
flag.DurationVar(&c.DumpMetricsInterval.Duration, "dump_metrics_interval", 0, "If greater than 0, how often to dump metrics to the logs.")
flag.BoolVar(&c.ForceMaster, "force_master", false, "If true, assume master for all logs")
flag.StringVar(&c.EtcdServers, "etcd_servers", "localhost:2379", "A comma-separated list of etcd servers")
flag.StringVar(&c.LockFilePath, "lock_file_path", "/test/multimaster", "etcd lock file directory path")

flag.DurationVar(&c.PreElectionPause.Duration, "pre_election_pause", 1*time.Second, "Maximum time to wait before starting elections")
flag.DurationVar(&c.MasterCheckInterval.Duration, "master_check_interval", 5*time.Second, "Interval between checking mastership still held")
flag.DurationVar(&c.MasterHoldInterval.Duration, "master_hold_interval", 60*time.Second, "Minimum interval to hold mastership for")
flag.IntVar(&c.ResignOdds, "resign_odds", 10, "Chance of resigning mastership after each check, the N in 1-in-N")
flag.Parse()

if *configFlag != "" {
// Only allow either --configFlag OR any other flags
if flag.CommandLine.NFlag() > 2 {
glog.Exit("Cannot use --configFlag with any other flags")
}
f, err := ioutil.ReadFile(*configFlag)
if err != nil {
glog.Exitf("Failed to read config file: %v", err)
}
if err := json.Unmarshal(f, &c); err != nil {
glog.Exitf("Failed to parse config file: %v", err)
}
}

glog.CopyStandardLogTo("WARNING")
glog.Info("**** Log Signer Starting ****")

// Enable dumping of metrics to the log at regular interval,
// if requested.
if *dumpMetricsInterval > 0 {
go metric.DumpToLog(context.Background(), *dumpMetricsInterval)
if c.DumpMetricsInterval.Duration > 0 {
go metric.DumpToLog(context.Background(), c.DumpMetricsInterval.Duration)
}

// First make sure we can access the database, quit if not
db, err := mysql.OpenDB(*mySQLURI)
db, err := mysql.OpenDB(c.MySQLURI)
if err != nil {
glog.Exitf("Failed to open MySQL database: %v", err)
}
Expand All @@ -76,11 +110,11 @@ func main() {
hostname, _ := os.Hostname()
instanceID := fmt.Sprintf("%s.%d", hostname, os.Getpid())
var electionFactory util.ElectionFactory
if *forceMaster {
if c.ForceMaster {
glog.Warning("**** Acting as master for all logs ****")
electionFactory = util.NoopElectionFactory{InstanceID: instanceID}
} else {
electionFactory = etcd.NewElectionFactory(instanceID, *etcdServers, *lockDir)
electionFactory = etcd.NewElectionFactory(instanceID, c.EtcdServers, c.LockFilePath)
}

registry := extension.Registry{
Expand All @@ -92,27 +126,27 @@ func main() {
}

// Start HTTP server (optional)
if *httpEndpoint != "" {
glog.Infof("Creating HTTP server starting on %v", *httpEndpoint)
if err := util.StartHTTPServer(*httpEndpoint); err != nil {
glog.Exitf("Failed to start HTTP server on %v: %v", *httpEndpoint, err)
if c.HTTPEndpoint != "" {
glog.Infof("Creating HTTP server starting on %v", c.HTTPEndpoint)
if err := util.StartHTTPServer(c.HTTPEndpoint); err != nil {
glog.Exitf("Failed to start HTTP server on %v: %v", c.HTTPEndpoint, err)
}
}

// Start the sequencing loop, which will run until we terminate the process. This controls
// both sequencing and signing.
// TODO(Martin2112): Should respect read only mode and the flags in tree control etc
sequencerManager := server.NewSequencerManager(registry, *sequencerGuardWindowFlag)
sequencerManager := server.NewSequencerManager(registry, c.SequencerGuardWindow.Duration)
info := server.LogOperationInfo{
Registry: registry,
BatchSize: *batchSizeFlag,
NumWorkers: *numSeqFlag,
RunInterval: *sequencerIntervalFlag,
BatchSize: c.BatchSize,
NumWorkers: c.NumSequencers,
RunInterval: c.SequencerInterval.Duration,
TimeSource: util.SystemTimeSource{},
PreElectionPause: *preElectionPause,
MasterCheckInterval: *masterCheckInterval,
MasterHoldInterval: *masterHoldInterval,
ResignOdds: *resignOdds,
PreElectionPause: c.PreElectionPause.Duration,
MasterCheckInterval: c.MasterCheckInterval.Duration,
MasterHoldInterval: c.MasterHoldInterval.Duration,
ResignOdds: c.ResignOdds,
}
sequencerTask := server.NewLogOperationManager(info, sequencerManager)
sequencerTask.OperationLoop(ctx)
Expand Down

0 comments on commit 1019686

Please sign in to comment.