Commit 7f1098a1 authored by Nick Thomas's avatar Nick Thomas

Specify a richer scheme to run the migration with

parent c37020bb
...@@ -50,5 +50,9 @@ log_level: INFO ...@@ -50,5 +50,9 @@ log_level: INFO
# incurs an extra API call on every gitlab-shell command. # incurs an extra API call on every gitlab-shell command.
audit_usernames: false audit_usernames: false
# Feature flag: go or ruby # Migration to Go: anything listed here has two implementations. Use these flags
experimental: false # to try the new implementations out, or to revert to the old behaviour if there
# problems arise.
migration:
enabled: false
features: []
...@@ -9,28 +9,41 @@ import ( ...@@ -9,28 +9,41 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/go/internal/config" "gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
) )
func experiment() { func migrate(_cfg *config.Config, _args []string) (int, bool) {
fmt.Println("Experiment! nothing works!") // TODO: decide whether to handle the request in Go or not
os.Exit(1) 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]) 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() config, err := config.New()
if err != nil { if err != nil {
fmt.Println(err) fmt.Fprintln(os.Stderr, "Failed to read config, falling back to gitlab-shell-ruby")
os.Exit(1) execRuby()
} }
if config.Experimental { // Try to handle the command with the Go implementation
experiment() if exitCode, done := migrate(config, os.Args[1:]); done {
} else { os.Exit(exitCode)
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)
}
} }
// Since a migration has not handled the command, fall back to Ruby to do so
execRuby()
} }
...@@ -13,11 +13,16 @@ const ( ...@@ -13,11 +13,16 @@ const (
logFile = "gitlab-shell.log" logFile = "gitlab-shell.log"
) )
type MigrationConfig struct {
Enabled bool `yaml:"enabled"`
Features []string `yaml:"features"`
}
type Config struct { type Config struct {
RootDir string RootDir string
LogFile string `yaml:"log_file"` LogFile string `yaml:"log_file"`
LogFormat string `yaml:"log_format"` LogFormat string `yaml:"log_format"`
Experimental bool `yaml:"experimental"` Migration MigrationConfig `yaml:"migration"`
} }
func New() (*Config, error) { func New() (*Config, error) {
......
...@@ -2,22 +2,28 @@ package config ...@@ -2,22 +2,28 @@ package config
import ( import (
"fmt" "fmt"
"strings"
"testing" "testing"
) )
func TestConfigLogFile(t *testing.T) { func TestConfigLogFile(t *testing.T) {
testRoot := "/foo/bar" testRoot := "/foo/bar"
testCases := []struct { testCases := []struct {
yaml string yaml string
path string path string
format string format string
experimental bool migration MigrationConfig
}{ }{
{path: "/foo/bar/gitlab-shell.log", format: "text"}, {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: 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_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: "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 { for _, tc := range testCases {
...@@ -27,8 +33,12 @@ func TestConfigLogFile(t *testing.T) { ...@@ -27,8 +33,12 @@ func TestConfigLogFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if cfg.Experimental != tc.experimental { if cfg.Migration.Enabled != tc.migration.Enabled {
t.Fatalf("expected %v, got %v", tc.experimental, cfg.Experimental) 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 { if cfg.LogFile != tc.path {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment