From eefd4b7914890bcd63ae933c1621349011d15d91 Mon Sep 17 00:00:00 2001 From: Michael Sauter Date: Sun, 13 Nov 2016 19:29:50 +0100 Subject: [PATCH 1/2] Implement config override --- .gitmodules | 3 +++ crane/cli.go | 12 ++++++---- crane/config.go | 40 +++++++++++++++++++++++++++++++-- vendor/github.com/imdario/mergo | 1 + 4 files changed, 50 insertions(+), 6 deletions(-) create mode 160000 vendor/github.com/imdario/mergo diff --git a/.gitmodules b/.gitmodules index afd3b57..50f32b2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "vendor/github.com/stretchr/testify"] path = vendor/github.com/stretchr/testify url = https://github.com/stretchr/testify +[submodule "vendor/github.com/imdario/mergo"] + path = vendor/github.com/imdario/mergo + url = https://github.com/imdario/mergo.git diff --git a/crane/cli.go b/crane/cli.go index 910831e..5567910 100644 --- a/crane/cli.go +++ b/crane/cli.go @@ -20,6 +20,10 @@ var ( "config", "Location of config file.", ).Short('c').PlaceHolder("~/crane.yaml").String() + overrideFlag = app.Flag( + "override", + "Location of override file.", + ).String() prefixFlag = app.Flag( "prefix", "Container prefix.", @@ -238,7 +242,7 @@ func isDryRun() bool { func commandAction(targetFlag string, wrapped func(unitOfWork *UnitOfWork), mightStartRelated bool) { - cfg = NewConfig(*configFlag, *prefixFlag, *tagFlag) + cfg = NewConfig(*configFlag, *overrideFlag, *prefixFlag, *tagFlag) allowed = allowedContainers(*excludeFlag, *onlyFlag) dependencyMap := cfg.DependencyMap() target, err := NewTarget(dependencyMap, targetFlag) @@ -388,7 +392,7 @@ func runCli() { }, false) case syncStartCommand.FullCommand(): - cfg = NewConfig(*configFlag, *prefixFlag, *tagFlag) + cfg = NewConfig(*configFlag, *overrideFlag, *prefixFlag, *tagFlag) sync := cfg.MacSync(*syncStartVolumeArg) if sync == nil { printErrorf("ERROR: No such sync configured: %s.", *syncStartVolumeArg) @@ -397,7 +401,7 @@ func runCli() { sync.Start(*syncStartDebugFlag) case syncStopCommand.FullCommand(): - cfg = NewConfig(*configFlag, *prefixFlag, *tagFlag) + cfg = NewConfig(*configFlag, *overrideFlag, *prefixFlag, *tagFlag) sync := cfg.MacSync(*syncStopVolumeArg) if sync == nil { printErrorf("ERROR: No such sync configured: %s.", *syncStartVolumeArg) @@ -406,7 +410,7 @@ func runCli() { sync.Stop() case syncStatusCommand.FullCommand(): - cfg = NewConfig(*configFlag, *prefixFlag, *tagFlag) + cfg = NewConfig(*configFlag, *overrideFlag, *prefixFlag, *tagFlag) w := new(tabwriter.Writer) w.Init(os.Stdout, 0, 8, 1, '\t', 0) fmt.Fprintln(w, "VOLUME\tCONTAINER\tSTATUS") diff --git a/crane/config.go b/crane/config.go index a67f4ba..a86945c 100644 --- a/crane/config.go +++ b/crane/config.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" "time" + "github.com/imdario/mergo" ) type Config interface { @@ -117,6 +118,31 @@ func readConfig(filename string) *config { return unmarshal(data, ext) } +func findOverride(filename, override string) string { + if len(override) > 0 { + if !path.IsAbs(override) { + override = path.Join(path.Dir(filename), override) + } + if _, err := os.Stat(override); err == nil { + return override + } else { + panic(StatusError{fmt.Errorf("Override %v not found", override), 78}) + } + } + + overrideFile := "" + lastIndex := strings.LastIndex(filename, ".") + if lastIndex > 0 { + overrideFile = filename[:lastIndex] + ".override" + filename[lastIndex:] + } else { + overrideFile = filename + ".override" + } + if _, err := os.Stat(overrideFile); err == nil { + return overrideFile + } + return "" +} + // displaySyntaxError will display more information // such as line and error type given an error and // the data that was unmarshalled. @@ -164,13 +190,23 @@ func unmarshal(data []byte, ext string) *config { // location. // Containers will be ordered so that they can be // brought up and down with Docker. -func NewConfig(location string, prefix string, tag string) Config { +func NewConfig(location string, override string, prefix string, tag string) Config { var config *config configFile := findConfig(location) if isVerbose() { printInfof("Using configuration file `%s`\n", configFile) } - config = readConfig(configFile) + configBase := readConfig(configFile) + overrideFile := findOverride(configFile, override) + if len(overrideFile) > 0 { + if isVerbose() { + printInfof("Using override file `%s`\n", overrideFile) + } + config = readConfig(overrideFile) + mergo.Merge(config, configBase) + } else { + config = configBase + } config.path = path.Dir(configFile) config.initialize() config.validate() diff --git a/vendor/github.com/imdario/mergo b/vendor/github.com/imdario/mergo new file mode 160000 index 0000000..50d4dbd --- /dev/null +++ b/vendor/github.com/imdario/mergo @@ -0,0 +1 @@ +Subproject commit 50d4dbd4eb0e84778abe37cefef140271d96fade From b7133a39812f45da67d43fba531cb011a5c4e93e Mon Sep 17 00:00:00 2001 From: Michael Sauter Date: Mon, 14 Nov 2016 19:25:39 +0100 Subject: [PATCH 2/2] Document override option --- CHANGELOG.md | 6 ++++++ README.md | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1e07d..9fb1e50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Allow to override configuration by another configuration file. By default, + Crane is looking for e.g. `crane.override.yml` if the config file in use is + `crane.yml`. This can be customized via `--override`/`CRANE_OVERRIDE`. + + _@michaelsauter_ + ## 2.10.3 (2016-10-27) * Add `--debug` flag to `crane mac-sync start` which turns on verbose logging diff --git a/README.md b/README.md index 11e9339..a91635d 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ continuous integration. * [Hooks](#hooks) * [Parallelism](#parallelism) * [Container Prefixes](#container-prefixes) + * [Override configuration](#override-configuration) * [Override image tag](#override-image-tag) * [Generate command](#generate-command) * [YAML advanced usage](#yaml-advanced-usage) @@ -489,6 +490,12 @@ in parallel, e.g. for CI builds. Container prefixes can also be supplied by the `CRANE_PREFIX` environment variable. +### Override configuration +The configuration can be overriden by another configuration file. By default, +Crane is looking for e.g. `crane.override.yml` if the config file in use is +`crane.yml`. This can be customized via `--override`/`CRANE_OVERRIDE`. + + ### Override image tag By using a the `--tag` flag, it is possible to globally overrides image tags. If you specify `--tag 2.0-rc2`, an image name `repo/app:1.0` is treated as