Skip to content

Commit

Permalink
Adding a configuration file for gitserver
Browse files Browse the repository at this point in the history
Now that gitserver is a bit more mature, let's stop passing in so many
flags and instead use the same config format that the rest of the
omegaUp services use.
  • Loading branch information
lhchavez committed Jul 14, 2019
1 parent 41a92b5 commit 0e6dc28
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 44 deletions.
90 changes: 90 additions & 0 deletions cmd/omegaup-gitserver/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"encoding/json"
"io"
)

// DbConfig represents the configuration for the database.
type DbConfig struct {
Driver string
DataSourceName string
}

// LoggingConfig represents the configuration for logging.
type LoggingConfig struct {
File string
Level string
}

// GitserverConfig represents the configuration for the Grader.
type GitserverConfig struct {
// RootPath is the root path of all repositories.
RootPath string

// PublicKeyBase64 is the base64-encoded public key of the omegaUp frontend.
// Used for verifying Paseto tokens.
PublicKeyBase64 string

// SecretToken is a shared secret with the frontend that can be used to
// authenticate instead of using PKI for speeding up tests.
SecretToken string

// Port is the TCP port in which the server will listen.
Port uint16

// PprofPort is the TCP port in which the pprof server will listen.
PprofPort uint16

// LibinteractivePath is the path of libinteractive.jar.
LibinteractivePath string

// AllowDirectPushToMaster determines whether gitserver allows pushing
// directly to master.
AllowDirectPushToMaster bool
}

// Config represents the configuration for the whole program.
type Config struct {
Db DbConfig
Logging LoggingConfig
Gitserver GitserverConfig
}

var defaultConfig = Config{
Db: DbConfig{
Driver: "sqlite3",
DataSourceName: "./omegaup.db",
},
Logging: LoggingConfig{
File: "/var/log/omegaup/gitserver.log",
Level: "info",
},
Gitserver: GitserverConfig{
RootPath: "/var/lib/omegaup/problems.git",
PublicKeyBase64: "gKEg5JlIOA1BsIxETZYhjd+ZGchY/rZeQM0GheAWvXw=",
SecretToken: "",
Port: 33861,
PprofPort: 33862,
LibinteractivePath: "/usr/share/java/libinteractive.jar",
AllowDirectPushToMaster: false,
},
}

// DefaultConfig returns a default Config.
func DefaultConfig() Config {
return defaultConfig
}

// NewConfig creates a new Config from the specified reader.
func NewConfig(reader io.Reader) (*Config, error) {
config := defaultConfig

// Read basic config
decoder := json.NewDecoder(reader)
if err := decoder.Decode(&config); err != nil {
return nil, err
}

return &config, nil
}
66 changes: 34 additions & 32 deletions cmd/omegaup-gitserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,13 @@ import (
)

var (
rootPath = flag.String("root", "", "Root path of all repositories")
publicKeyBase64 = flag.String("public-key", "gKEg5JlIOA1BsIxETZYhjd+ZGchY/rZeQM0GheAWvXw=", "Public key of the omegaUp frontend")
secretToken = flag.String("secret-token", "", "A secret token to use instead of resorting to PKI for speeding up tests")
port = flag.Int("port", 33861, "Port in which the server will listen")
pprofPort = flag.Int("pprof-port", 33862, "Port in which the pprof server will listen")
libinteractivePath = flag.String("libinteractive-path", "/usr/share/java/libinteractive.jar", "Path of libinteractive.jar")
allowDirectPushToMaster = flag.Bool("allow-direct-push-to-master", false, "Allow direct push to master")
logFile = flag.String("log-file", "", "Redirect logs to file")
verbose = flag.Bool("verbose", false, "Verbose logging")
version = flag.Bool("version", false, "Print the version and exit")
log log15.Logger
configPath = flag.String(
"config",
"/etc/omegaup/gitserver/config.json",
"gitserver configuration file",
)
version = flag.Bool("version", false, "Print the version and exit")
log log15.Logger

// ProgramVersion is the version of the code from which the binary was built from.
ProgramVersion string
Expand Down Expand Up @@ -240,35 +236,46 @@ func main() {
return
}

if *logFile != "" {
logLevel := "info"
if *verbose {
logLevel = "debug"
}
f, err := os.Open(*configPath)
if err != nil {
panic(err)
}
config, err := NewConfig(f)
if err != nil {
panic(err)
}
f.Close()

if config.Logging.File != "" {
var err error
if log, err = base.RotatingLog(*logFile, logLevel); err != nil {
if log, err = base.RotatingLog(config.Logging.File, config.Logging.Level); err != nil {
panic(err)
}
} else if *verbose {
} else if config.Logging.Level == "debug" {
log = base.StderrLog()
} else {
log = log15.New()
log.SetHandler(base.ErrorCallerStackHandler(log15.LvlInfo, log15.StderrHandler))
}

if config.Gitserver.RootPath == "" {
log.Error("root path cannot be empty. Please specify one with -root")
os.Exit(1)
}

stopChan := make(chan os.Signal)
signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)

var authCallback githttp.AuthorizationCallback
if *publicKeyBase64 == "" && *secretToken != "" {
if config.Gitserver.PublicKeyBase64 == "" && config.Gitserver.SecretToken != "" {
log.Warn("using insecure secret token authorization")
auth := secretTokenAuthorization{
log: log,
secretToken: *secretToken,
secretToken: config.Gitserver.SecretToken,
}
authCallback = auth.authorize
} else {
keyBytes, err := base64.StdEncoding.DecodeString(*publicKeyBase64)
keyBytes, err := base64.StdEncoding.DecodeString(config.Gitserver.PublicKeyBase64)
if err != nil {
log.Error("failed to parse the base64-encoded public key", "err", err)
os.Exit(1)
Expand All @@ -284,25 +291,20 @@ func main() {
protocol := gitserver.NewGitProtocol(
authCallback,
referenceDiscovery,
*allowDirectPushToMaster,
config.Gitserver.AllowDirectPushToMaster,
gitserver.OverallWallTimeHardLimit,
&gitserver.LibinteractiveCompiler{
LibinteractiveJarPath: *libinteractivePath,
LibinteractiveJarPath: config.Gitserver.LibinteractivePath,
Log: log,
},
log,
)

if *rootPath == "" {
log.Error("root path cannot be empty. Please specify one with -root")
os.Exit(1)
}

var servers []*http.Server
var wg sync.WaitGroup
gitServer := &http.Server{
Addr: fmt.Sprintf(":%d", *port),
Handler: muxHandler(*rootPath, protocol, log),
Addr: fmt.Sprintf(":%d", config.Gitserver.Port),
Handler: muxHandler(config.Gitserver.RootPath, protocol, log),
}
servers = append(servers, gitServer)
wg.Add(1)
Expand All @@ -318,15 +320,15 @@ func main() {
"address", gitServer.Addr,
)

if *pprofPort > 0 {
if config.Gitserver.PprofPort > 0 {
pprofServeMux := http.NewServeMux()
pprofServeMux.HandleFunc("/debug/pprof/", pprof.Index)
pprofServeMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
pprofServeMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
pprofServeMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
pprofServeMux.HandleFunc("/debug/pprof/trace", pprof.Trace)
pprofServer := &http.Server{
Addr: fmt.Sprintf("localhost:%d", *pprofPort),
Addr: fmt.Sprintf("localhost:%d", config.Gitserver.PprofPort),
Handler: pprofServeMux,
}
servers = append(servers, pprofServer)
Expand Down
2 changes: 1 addition & 1 deletion cmd/omegaup-gitserver/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const (

func TestParseBearerAuth(t *testing.T) {
log := base.StderrLog()
keyBytes, err := base64.StdEncoding.DecodeString(*publicKeyBase64)
keyBytes, err := base64.StdEncoding.DecodeString(DefaultConfig().Gitserver.PublicKeyBase64)
if err != nil {
t.Fatalf("failed to parse shared key: %v", err)
}
Expand Down
17 changes: 17 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
module github.com/omegaup/gitserver

go 1.12

require (
github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a
github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec
github.com/lhchavez/git2go v0.0.0-20190221190548-e9c961d8b627
github.com/o1egl/paseto v1.0.0
github.com/omegaup/githttp v0.0.0-20190424035114-ded1cff40e18
github.com/omegaup/go-base v0.0.0-20190624033755-26f895597739
github.com/omegaup/quark v1.1.19
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.0.0
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc
golang.org/x/text v0.3.2
)
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5 h1:mzjBh+S5frKOsOBobWIMAbXavqjmgO17k/2puhcFR94=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
Expand Down
22 changes: 11 additions & 11 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ type PublishingConfig struct {
Branch string `json:"branch,omitempty"`
}

// Config represents the contents of config.json in refs/meta/config.
type Config struct {
// MetaConfig represents the contents of config.json in refs/meta/config.
type MetaConfig struct {
Publishing PublishingConfig `json:"publishing"`
}

Expand Down Expand Up @@ -1026,8 +1026,8 @@ func (p *gitProtocol) validateUpdateConfig(repository *git.Repository, oldCommit
contents := configBlob.Contents()
configBlob.Free()

var config Config
if err := json.Unmarshal([]byte(contents), &config); err != nil {
var metaConfig MetaConfig
if err := json.Unmarshal([]byte(contents), &metaConfig); err != nil {
return base.ErrorWithCategory(
ErrJSONParseError,
errors.Wrap(
Expand All @@ -1036,16 +1036,16 @@ func (p *gitProtocol) validateUpdateConfig(repository *git.Repository, oldCommit
),
)
}
if config.Publishing.Mode == "mirror" {
if metaConfig.Publishing.Mode == "mirror" {
// No additional checks needed.
} else if config.Publishing.Mode == "subdirectory" {
if config.Publishing.Target == "" {
} else if metaConfig.Publishing.Mode == "subdirectory" {
if metaConfig.Publishing.Target == "" {
return ErrConfigSubdirectoryMissingTarget
}
} else {
return ErrConfigInvalidPublishingMode
}
if parsed, err := url.Parse(config.Publishing.Repository); err != nil || !parsed.IsAbs() {
if parsed, err := url.Parse(metaConfig.Publishing.Repository); err != nil || !parsed.IsAbs() {
return ErrConfigRepositoryNotAbsoluteURL
}
return nil
Expand Down Expand Up @@ -1689,7 +1689,7 @@ func InitRepository(
}

// Disable delta.
config, err := repo.Config()
repoConfig, err := repo.Config()
if err != nil {
return nil, base.ErrorWithCategory(
ErrInternalGit,
Expand All @@ -1700,9 +1700,9 @@ func InitRepository(
),
)
}
defer config.Free()
defer repoConfig.Free()

if err := config.SetInt32("pack.deltaCacheSize", 0); err != nil {
if err := repoConfig.SetInt32("pack.deltaCacheSize", 0); err != nil {
return nil, base.ErrorWithCategory(
ErrInternalGit,
errors.Wrapf(
Expand Down

0 comments on commit 0e6dc28

Please sign in to comment.