Merge pull request #8498 from dokku/migrate-env-vars-to-properties
Migrate environment variables to plugin properties
This commit is contained in:
@@ -606,37 +606,12 @@ func GetRunningImageTag(appName string, imageTag string) (string, error) {
|
||||
|
||||
// GetDokkuAppShell returns the shell for a given app
|
||||
func GetDokkuAppShell(appName string) string {
|
||||
shell := "/bin/bash"
|
||||
globalShell := ""
|
||||
appShell := ""
|
||||
|
||||
ctx := context.Background()
|
||||
errs, ctx := errgroup.WithContext(ctx)
|
||||
errs.Go(func() error {
|
||||
results, _ := CallPlugnTriggerWithContext(ctx, PlugnTriggerInput{
|
||||
Trigger: "config-get-global",
|
||||
Args: []string{"DOKKU_APP_SHELL"},
|
||||
})
|
||||
globalShell = results.StdoutContents()
|
||||
return nil
|
||||
})
|
||||
errs.Go(func() error {
|
||||
results, _ := CallPlugnTriggerWithContext(ctx, PlugnTriggerInput{
|
||||
Trigger: "config-get",
|
||||
Args: []string{appName, "DOKKU_APP_SHELL"},
|
||||
})
|
||||
appShell = results.StdoutContents()
|
||||
return nil
|
||||
})
|
||||
|
||||
errs.Wait()
|
||||
appShell := PropertyGet("scheduler", appName, "shell")
|
||||
if appShell != "" {
|
||||
shell = appShell
|
||||
} else if globalShell != "" {
|
||||
shell = globalShell
|
||||
return appShell
|
||||
}
|
||||
|
||||
return shell
|
||||
return PropertyGetDefault("scheduler", "--global", "shell", "/bin/bash")
|
||||
}
|
||||
|
||||
// DokkuApps returns a list of all local apps
|
||||
|
||||
@@ -390,23 +390,17 @@ func DockerBin() string {
|
||||
func DockerCleanup(appName string, forceCleanup bool) error {
|
||||
if !forceCleanup {
|
||||
skipCleanup := false
|
||||
if appName != "" {
|
||||
triggerName := "config-get"
|
||||
triggerArgs := []string{appName, "DOKKU_SKIP_CLEANUP"}
|
||||
if appName == "--global" {
|
||||
triggerName = "config-get-global"
|
||||
triggerArgs = []string{"DOKKU_SKIP_CLEANUP"}
|
||||
}
|
||||
|
||||
results, _ := CallPlugnTrigger(PlugnTriggerInput{
|
||||
Trigger: triggerName,
|
||||
Args: triggerArgs,
|
||||
})
|
||||
if results.StdoutContents() == "true" {
|
||||
if appName != "" && appName != "--global" {
|
||||
if PropertyGet("builder", appName, "skip-cleanup") == "true" {
|
||||
skipCleanup = true
|
||||
}
|
||||
}
|
||||
|
||||
if !skipCleanup && PropertyGet("builder", "--global", "skip-cleanup") == "true" {
|
||||
skipCleanup = true
|
||||
}
|
||||
|
||||
// Fallback for .dokkurc compatibility
|
||||
if skipCleanup || os.Getenv("DOKKU_SKIP_CLEANUP") == "true" {
|
||||
LogInfo1("DOKKU_SKIP_CLEANUP set. Skipping dokku cleanup")
|
||||
return nil
|
||||
|
||||
@@ -632,8 +632,8 @@ release_and_deploy() {
|
||||
|
||||
if verify_image "$IMAGE"; then
|
||||
IMAGE_SOURCE_TYPE="$(get_image_builder_type "$IMAGE" "$APP")"
|
||||
local DOKKU_APP_SKIP_DEPLOY="$(config_get "$APP" DOKKU_SKIP_DEPLOY || true)"
|
||||
local DOKKU_GLOBAL_SKIP_DEPLOY="$(config_get --global DOKKU_SKIP_DEPLOY || true)"
|
||||
local DOKKU_APP_SKIP_DEPLOY="$(fn-plugin-property-get-default "ps" "$APP" "skip-deploy" "")"
|
||||
local DOKKU_GLOBAL_SKIP_DEPLOY="$(fn-plugin-property-get-default "ps" "--global" "skip-deploy" "")"
|
||||
|
||||
local DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"}
|
||||
|
||||
@@ -917,7 +917,7 @@ suppress_output() {
|
||||
}
|
||||
|
||||
fn-migrate-config-to-property() {
|
||||
declare desc="migrates deprecated config variables to property counterpart"
|
||||
declare desc="[deprecated] migrates deprecated config variables to property counterpart. Use 'prop migrate-config-to-property' instead."
|
||||
declare PLUGIN="$1" KEY="$2" CONFIG_VAR="$3" GLOBAL_CONFIG_VAR="$4"
|
||||
|
||||
# todo: refactor to remove config_unset usage
|
||||
|
||||
@@ -548,6 +548,121 @@ func PropertySetupApp(pluginName string, appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MigrateConfigEntry describes a single config-to-property migration
|
||||
type MigrateConfigEntry struct {
|
||||
// ConfigVar is the per-app environment variable name (e.g. "DOKKU_APP_PROXY_TYPE")
|
||||
ConfigVar string
|
||||
|
||||
// GlobalConfigVar is the global environment variable name (e.g. "DOKKU_PROXY_TYPE"), empty if none
|
||||
GlobalConfigVar string
|
||||
|
||||
// Property is the target property name (e.g. "type")
|
||||
Property string
|
||||
|
||||
// Transform is an optional value transformation function applied before writing
|
||||
Transform func(value string) string
|
||||
|
||||
// ListProperty indicates the value should be written as a list property via PropertyListWrite
|
||||
ListProperty bool
|
||||
}
|
||||
|
||||
// MigrateConfigToProperties migrates config variables to properties for a given plugin
|
||||
// across all apps and optionally globally. It is idempotent: if the property already
|
||||
// exists, the migration is skipped for that app/entry.
|
||||
func MigrateConfigToProperties(pluginName string, entries []MigrateConfigEntry) error {
|
||||
apps, err := UnfilteredDokkuApps()
|
||||
if err != nil && !errors.Is(err, NoAppsExist) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.GlobalConfigVar != "" {
|
||||
if err := migrateConfigEntry(pluginName, "--global", entry.GlobalConfigVar, entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, appName := range apps {
|
||||
if entry.ConfigVar == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := migrateConfigEntry(pluginName, appName, entry.ConfigVar, entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateConfigEntry migrates a single config variable to a property for a given app
|
||||
func migrateConfigEntry(pluginName string, appName string, configVar string, entry MigrateConfigEntry) error {
|
||||
if entry.ListProperty {
|
||||
if exists, _ := PropertyListLength(pluginName, appName, entry.Property); exists > 0 {
|
||||
return nil
|
||||
}
|
||||
} else if PropertyExists(pluginName, appName, entry.Property) {
|
||||
return nil
|
||||
}
|
||||
|
||||
triggerName := "config-get"
|
||||
triggerArgs := []string{appName, configVar}
|
||||
if appName == "--global" {
|
||||
triggerName = "config-get-global"
|
||||
triggerArgs = []string{configVar}
|
||||
}
|
||||
|
||||
results, _ := CallPlugnTrigger(PlugnTriggerInput{
|
||||
Trigger: triggerName,
|
||||
Args: triggerArgs,
|
||||
})
|
||||
value := results.StdoutContents()
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if entry.Transform != nil {
|
||||
value = entry.Transform(value)
|
||||
}
|
||||
|
||||
if appName == "--global" {
|
||||
LogInfo1(fmt.Sprintf("Migrating deprecated global %s to %s %s property. Use 'dokku %s:set --global %s <value>' to manage this going forward.", configVar, pluginName, entry.Property, pluginName, entry.Property))
|
||||
} else {
|
||||
LogInfo1(fmt.Sprintf("Migrating deprecated %s to %s %s property for %s. Use 'dokku %s:set %s %s <value>' to manage this going forward.", configVar, pluginName, entry.Property, appName, pluginName, appName, entry.Property))
|
||||
}
|
||||
|
||||
if entry.ListProperty {
|
||||
values := strings.Split(value, " ")
|
||||
if err := PropertyListWrite(pluginName, appName, entry.Property, values); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := PropertyWrite(pluginName, appName, entry.Property, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
unsetTrigger := "config-unset"
|
||||
unsetArgs := []string{appName, configVar}
|
||||
if appName == "--global" {
|
||||
unsetArgs = []string{"--global", configVar}
|
||||
}
|
||||
|
||||
_, err := CallPlugnTrigger(PlugnTriggerInput{
|
||||
Trigger: unsetTrigger,
|
||||
Args: unsetArgs,
|
||||
Env: map[string]string{
|
||||
"DOKKU_QUIET_OUTPUT": "1",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
LogWarn(err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPropertyPath(pluginName string, appName string, property string) string {
|
||||
pluginAppConfigRoot := getPluginAppPropertyPath(pluginName, appName)
|
||||
return filepath.Join(pluginAppConfigRoot, property)
|
||||
|
||||
@@ -192,6 +192,76 @@ func main() {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
case "migrate-config-to-property":
|
||||
property := flag.Arg(2)
|
||||
configVar := flag.Arg(3)
|
||||
|
||||
globalConfigVar := ""
|
||||
transformName := ""
|
||||
listProperty := false
|
||||
for i := 4; i < flag.NArg(); i++ {
|
||||
arg := flag.Arg(i)
|
||||
switch {
|
||||
case arg == "--list":
|
||||
listProperty = true
|
||||
case arg == "--global-config-var" && i+1 < flag.NArg():
|
||||
i++
|
||||
globalConfigVar = flag.Arg(i)
|
||||
case arg == "--transform" && i+1 < flag.NArg():
|
||||
i++
|
||||
transformName = flag.Arg(i)
|
||||
}
|
||||
}
|
||||
|
||||
var transform func(string) string
|
||||
switch transformName {
|
||||
case "restore-bool":
|
||||
transform = func(value string) string {
|
||||
if value == "0" {
|
||||
return "false"
|
||||
}
|
||||
return "true"
|
||||
}
|
||||
case "non-empty-to-true":
|
||||
transform = func(value string) string {
|
||||
if value != "" {
|
||||
return "true"
|
||||
}
|
||||
return value
|
||||
}
|
||||
case "skip-all-checks-to-disabled":
|
||||
transform = func(value string) string {
|
||||
if value == "true" {
|
||||
return "_all_"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
case "checks-enabled-to-skipped":
|
||||
transform = func(value string) string {
|
||||
if value == "0" {
|
||||
return "_all_"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
case "":
|
||||
// no transform
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown transform: %s\n", transformName)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
entry := common.MigrateConfigEntry{
|
||||
ConfigVar: configVar,
|
||||
GlobalConfigVar: globalConfigVar,
|
||||
Property: property,
|
||||
Transform: transform,
|
||||
ListProperty: listProperty,
|
||||
}
|
||||
|
||||
if err := common.MigrateConfigToProperties(pluginName, []common.MigrateConfigEntry{entry}); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
case "set":
|
||||
appName := flag.Arg(2)
|
||||
property := flag.Arg(3)
|
||||
|
||||
Reference in New Issue
Block a user