diff options
author | Nick Thomas <nick@gitlab.com> | 2018-09-28 14:50:26 +0100 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2018-09-28 14:50:26 +0100 |
commit | 7f1098a1d9fd79b394b53b0c43fcc4741349d43a (patch) | |
tree | c31273b3b1a49c73c6c19ab2c008230e2d488b5a | |
parent | c37020bb5ae66bfb7596e2b1b4f7b5c79203ecf3 (diff) | |
download | gitlab-shell-7f1098a1d9fd79b394b53b0c43fcc4741349d43a.tar.gz |
Specify a richer scheme to run the migration with
-rw-r--r-- | config.yml.example | 8 | ||||
-rw-r--r-- | go/cmd/gitlab-shell/main.go | 43 | ||||
-rw-r--r-- | go/internal/config/config.go | 13 | ||||
-rw-r--r-- | go/internal/config/config_test.go | 24 |
4 files changed, 60 insertions, 28 deletions
diff --git a/config.yml.example b/config.yml.example index 49f5d78..3d3e580 100644 --- a/config.yml.example +++ b/config.yml.example @@ -50,5 +50,9 @@ log_level: INFO # incurs an extra API call on every gitlab-shell command. audit_usernames: false -# Feature flag: go or ruby -experimental: false +# Migration to Go: anything listed here has two implementations. Use these flags +# to try the new implementations out, or to revert to the old behaviour if there +# problems arise. +migration: + enabled: false + features: [] diff --git a/go/cmd/gitlab-shell/main.go b/go/cmd/gitlab-shell/main.go index 53632a1..44384ab 100644 --- a/go/cmd/gitlab-shell/main.go +++ b/go/cmd/gitlab-shell/main.go @@ -9,28 +9,41 @@ import ( "gitlab.com/gitlab-org/gitlab-shell/go/internal/config" ) -func experiment() { - fmt.Println("Experiment! nothing works!") - os.Exit(1) +func migrate(_cfg *config.Config, _args []string) (int, bool) { + // TODO: decide whether to handle the request in Go or not + return 0, false } -func main() { +// rubyExec will never return. It either replaces the current process with a +// Ruby interpreter, or outputs an error and kills the process. +func execRuby() { root := filepath.Dir(os.Args[0]) - ruby := filepath.Join(root, "gitlab-shell-ruby") + rubyCmd := filepath.Join(root, "gitlab-shell-ruby") + rubyArgs := os.Args[1:] + rubyEnv := os.Environ() + + execErr := syscall.Exec(rubyCmd, rubyArgs, rubyEnv) + if execErr != nil { + fmt.Fprintf(os.Stderr, "Failed to exec(%q): %v\n", rubyCmd, execErr) + os.Exit(1) + } +} + +func main() { + // Fall back to Ruby in case of problems reading the config, but issue a + // warning as this isn't something we can sustain indefinitely config, err := config.New() if err != nil { - fmt.Println(err) - os.Exit(1) + fmt.Fprintln(os.Stderr, "Failed to read config, falling back to gitlab-shell-ruby") + execRuby() } - if config.Experimental { - experiment() - } else { - execErr := syscall.Exec(ruby, os.Args, os.Environ()) - if execErr != nil { - fmt.Fprintf(os.Stderr, "Failed to exec(%q): %v\n", ruby, execErr) - os.Exit(1) - } + // Try to handle the command with the Go implementation + if exitCode, done := migrate(config, os.Args[1:]); done { + os.Exit(exitCode) } + + // Since a migration has not handled the command, fall back to Ruby to do so + execRuby() } diff --git a/go/internal/config/config.go b/go/internal/config/config.go index 64822c7..4069851 100644 --- a/go/internal/config/config.go +++ b/go/internal/config/config.go @@ -13,11 +13,16 @@ const ( logFile = "gitlab-shell.log" ) +type MigrationConfig struct { + Enabled bool `yaml:"enabled"` + Features []string `yaml:"features"` +} + type Config struct { - RootDir string - LogFile string `yaml:"log_file"` - LogFormat string `yaml:"log_format"` - Experimental bool `yaml:"experimental"` + RootDir string + LogFile string `yaml:"log_file"` + LogFormat string `yaml:"log_format"` + Migration MigrationConfig `yaml:"migration"` } func New() (*Config, error) { diff --git a/go/internal/config/config_test.go b/go/internal/config/config_test.go index 552a600..368ab29 100644 --- a/go/internal/config/config_test.go +++ b/go/internal/config/config_test.go @@ -2,22 +2,28 @@ package config import ( "fmt" + "strings" "testing" ) func TestConfigLogFile(t *testing.T) { testRoot := "/foo/bar" testCases := []struct { - yaml string - path string - format string - experimental bool + yaml string + path string + format string + migration MigrationConfig }{ {path: "/foo/bar/gitlab-shell.log", format: "text"}, {yaml: "log_file: my-log.log", path: "/foo/bar/my-log.log", format: "text"}, {yaml: "log_file: /qux/my-log.log", path: "/qux/my-log.log", format: "text"}, {yaml: "log_format: json", path: "/foo/bar/gitlab-shell.log", format: "json"}, - {yaml: "experimental: true", path: "/foo/bar/gitlab-shell.log", format: "text", experimental: true}, + { + yaml: "migration:\n enabled: true\n features:\n - foo\n - bar", + path: "/foo/bar/gitlab-shell.log", + format: "text", + migration: MigrationConfig{Enabled: true, Features: []string{"foo", "bar"}}, + }, } for _, tc := range testCases { @@ -27,8 +33,12 @@ func TestConfigLogFile(t *testing.T) { t.Fatal(err) } - if cfg.Experimental != tc.experimental { - t.Fatalf("expected %v, got %v", tc.experimental, cfg.Experimental) + if cfg.Migration.Enabled != tc.migration.Enabled { + t.Fatalf("migration.enabled: expected %v, got %v", tc.migration.Enabled, cfg.Migration.Enabled) + } + + if strings.Join(cfg.Migration.Features, ":") != strings.Join(tc.migration.Features, ":") { + t.Fatalf("migration.features: expected %#v, got %#v", tc.migration.Features, cfg.Migration.Features) } if cfg.LogFile != tc.path { |