[config] support for env bundles
This commit is contained in:
@@ -6,36 +6,23 @@ source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
build_env_pre_build_buildpack() {
|
||||
declare desc="build-env pre-build-buildpack plugin trigger"
|
||||
local trigger="build_env_pre_build_buildpack"
|
||||
local APP="$1"; local IMAGE=$(get_app_image_name "$APP"); local BUILD_ENV=""
|
||||
local APP="$1"; local IMAGE=$(get_app_image_name "$APP");
|
||||
verify_app_name "$APP"
|
||||
|
||||
[[ -z $(config_get --global CURL_CONNECT_TIMEOUT) ]] && config_set --global CURL_CONNECT_TIMEOUT=90
|
||||
[[ -z $(config_get --global CURL_TIMEOUT) ]] && config_set --global CURL_TIMEOUT=60
|
||||
|
||||
if [[ -n $(config_export global) ]]; then
|
||||
local BUILD_ENV+=$'\n'
|
||||
local BUILD_ENV+=$(config_export global)
|
||||
local BUILD_ENV+=$'\n'
|
||||
fi
|
||||
if [[ -n $(config_export app "$APP") ]]; then
|
||||
local BUILD_ENV+=$'\n'
|
||||
local BUILD_ENV+=$(config_export app "$APP")
|
||||
local BUILD_ENV+=$'\n'
|
||||
fi
|
||||
dokku_log_info1 "Adding BUILD_ENV to build environment..."
|
||||
# create build env files for use in buildpacks like this:
|
||||
# https://github.com/niteoweb/heroku-buildpack-buildout/blob/5879fa3418f7d8e079f1aa5816ba1adde73f4948/bin/compile#L34
|
||||
local id=$(config_export app "$APP" --merged --bundle | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /tmp/env; cat | tar -x -C /tmp/env")
|
||||
test "$(docker wait "$id")" -eq 0
|
||||
docker commit "$id" "$IMAGE" > /dev/null
|
||||
|
||||
if [[ ! -z "$BUILD_ENV" ]]; then
|
||||
dokku_log_info1 "Adding BUILD_ENV to build environment..."
|
||||
# create build env files for use in buildpacks like this:
|
||||
# https://github.com/niteoweb/heroku-buildpack-buildout/blob/5879fa3418f7d8e079f1aa5816ba1adde73f4948/bin/compile#L34
|
||||
local id=$(echo $BUILD_ENV | sed -e 's@export @@g' -e 's@\\n@ @g' | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /tmp/env; for ENV_VAR in $(cat); do echo \$ENV_VAR | cut -d'=' -f2- > /tmp/env/\$(echo \$ENV_VAR | cut -d'=' -f1); done " )
|
||||
test "$(docker wait "$id")" -eq 0
|
||||
docker commit "$id" "$IMAGE" > /dev/null
|
||||
|
||||
# create build env for 'old style' buildpacks and dokku plugins
|
||||
local id=$(echo -e "$BUILD_ENV" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "cat >> /app/.env")
|
||||
test "$(docker wait "$id")" -eq 0
|
||||
docker commit "$id" "$IMAGE" > /dev/null
|
||||
fi
|
||||
# create build env for 'old style' buildpacks and dokku plugins
|
||||
local id=$(config_export app "$APP" --envfile --merged --escape-newlines | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "cat >> /app/.env")
|
||||
test "$(docker wait "$id")" -eq 0
|
||||
docker commit "$id" "$IMAGE" > /dev/null
|
||||
}
|
||||
|
||||
build_env_pre_build_buildpack "$@"
|
||||
|
||||
@@ -3,19 +3,23 @@ package configenv
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"archive/tar"
|
||||
|
||||
common "github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
//Env is a representation for global or app environment
|
||||
type Env struct {
|
||||
name string
|
||||
env map[string]string
|
||||
filename string
|
||||
name string
|
||||
env map[string]string
|
||||
filename string
|
||||
EscapeNewlines bool
|
||||
}
|
||||
|
||||
func (e *Env) String() string {
|
||||
@@ -38,7 +42,11 @@ func (e *Env) StringWithPrefixAndSeparator(prefix string, separator string) stri
|
||||
keys := e.Keys()
|
||||
entries := make([]string, len(keys))
|
||||
for i, k := range keys {
|
||||
entries[i] = fmt.Sprintf("%s%s='%s'", prefix, k, SingleQuoteEscape(e.env[k]))
|
||||
v := SingleQuoteEscape(e.env[k])
|
||||
if e.EscapeNewlines {
|
||||
v = strings.Replace(v, "\n", "'$'\\n''", -1)
|
||||
}
|
||||
entries[i] = fmt.Sprintf("%s%s='%s'", prefix, k, v)
|
||||
}
|
||||
return strings.Join(entries, separator)
|
||||
}
|
||||
@@ -48,7 +56,29 @@ func SingleQuoteEscape(value string) string { // so that 'esc'apped' -> 'esc'\''
|
||||
return strings.Replace(value, "'", "'\\''", -1)
|
||||
}
|
||||
|
||||
//NewFromTarget creates an env from the given target. Tareget is either "--global" or an app name
|
||||
//ExportBundle writes a tarfile of the environmnet to the given io.Writer.
|
||||
// for every environment variable there is a file with the variable's key
|
||||
// with its content set to the variable's value
|
||||
func (e *Env) ExportBundle(dest io.Writer) error {
|
||||
tarfile := tar.NewWriter(dest)
|
||||
defer tarfile.Close()
|
||||
|
||||
for _, k := range e.Keys() {
|
||||
val, _ := e.Get(k)
|
||||
valbin := []byte(val)
|
||||
|
||||
header := &tar.Header{
|
||||
Name: k,
|
||||
Mode: 0600,
|
||||
Size: int64(len(valbin)),
|
||||
}
|
||||
tarfile.WriteHeader(header)
|
||||
tarfile.Write(valbin)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//NewFromTarget creates an env from the given target. Target is either "--global" or an app name
|
||||
func NewFromTarget(target string) (*Env, error) {
|
||||
if target == "--global" {
|
||||
return LoadGlobal()
|
||||
|
||||
@@ -36,7 +36,7 @@ func parseEnvFromReader(name string, filename string, reader io.Reader) (*Env, e
|
||||
StateKey = iota
|
||||
StateValue = iota
|
||||
)
|
||||
env := &Env{name, map[string]string{}, filename}
|
||||
env := &Env{name, map[string]string{}, filename, false}
|
||||
var buffer bytes.Buffer
|
||||
var state = StateKey
|
||||
var quoted = false
|
||||
|
||||
@@ -12,13 +12,16 @@ import (
|
||||
// print the environment to stdout
|
||||
func main() {
|
||||
const defaultPrefix = "export "
|
||||
const defaultSeparator = "\n"
|
||||
args := flag.NewFlagSet("config:export", flag.ExitOnError)
|
||||
global := args.Bool("global", false, "--global: use the global environment")
|
||||
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
|
||||
keys := args.Bool("keys", false, "--keys: export keys only")
|
||||
bundle := args.Bool("bundle", false, "--bundle: export as tar bundle")
|
||||
envfile := args.Bool("envfile", false, "--envfile: export as envfile rather than bash exports (--prefix='')")
|
||||
prefix := args.String("prefix", "export ", "--prefix: prefix")
|
||||
separator := args.String("separator", "\n", "--separator: separator")
|
||||
prefix := args.String("prefix", defaultPrefix, "--prefix: prefix")
|
||||
separator := args.String("separator", defaultSeparator, "--separator: separator")
|
||||
escapeNewlines := args.Bool("escape-newlines", false, "--escape-newlines: replace literal newlines with $'\n'")
|
||||
args.Parse(os.Args[2:])
|
||||
|
||||
appName := args.Arg(0)
|
||||
@@ -57,6 +60,16 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
if *escapeNewlines {
|
||||
env.EscapeNewlines = true
|
||||
}
|
||||
|
||||
if *bundle {
|
||||
if *prefix != defaultPrefix || *separator != defaultSeparator || *envfile {
|
||||
common.LogFail("--bundle cannot be given with --envfile, --prefix, or --separator")
|
||||
}
|
||||
env.ExportBundle(os.Stdout)
|
||||
}
|
||||
if *envfile {
|
||||
if *prefix != defaultPrefix {
|
||||
common.LogFail("--prefix and --envfile cannot both be given")
|
||||
|
||||
Reference in New Issue
Block a user