fix: migrate env files before reading deprecated vars

Install steps run in alphabetical order of the enabled plugin directory, so `apps`, `builder`, and `checks` read an app's environment before the `config` plugin had moved the `ENV` file to its new location. The read came back empty, so their deprecated `DOKKU_*` variables were never migrated to the matching plugin property and were never unset, with nothing reported either way: `dokku config:show` kept listing the variable while the plugin behaved as though it were unset. The relocation now runs before any deprecated variable is read, whatever the install order, and each old file is removed as soon as it has been drained rather than on a later install, which also covers the global file that was never removed at all. A file that reappears at the old path can only have been written by hand, so it is merged in with a warning naming its keys instead of being discarded.
This commit is contained in:
Jose Diaz-Gonzalez
2026-08-07 16:43:56 -04:00
parent eedcb90e29
commit 70dc921967
11 changed files with 455 additions and 100 deletions

View File

@@ -77,44 +77,11 @@ func setupAppConfigDir(appName string) error {
})
}
func migrateGlobalEnv() error {
if err := common.PropertySetup("--global"); err != nil {
return fmt.Errorf("Unable to setup global environment: %s", err.Error())
}
oldGlobalEnvFile := filepath.Join(common.MustGetEnv("DOKKU_ROOT"), "ENV")
isGlobalMigrated := common.PropertyGetDefault("config", "--global", "env-migrated", "")
if isGlobalMigrated == "true" {
return nil
}
oldGlobalEnv, err := loadFromFile("--global", oldGlobalEnvFile)
if err != nil {
return fmt.Errorf("Unable to load old global environment: %s", err.Error())
}
globalEnv, err := LoadGlobalEnv()
if err != nil {
return fmt.Errorf("Unable to load global environment: %s", err.Error())
}
globalEnv.Merge(oldGlobalEnv)
if err := globalEnv.Write(); err != nil {
return fmt.Errorf("Unable to write global environment: %s", err.Error())
}
if err := common.SetPermissions(common.SetPermissionInput{
Filename: globalEnv.Filename(),
Mode: os.FileMode(0600),
}); err != nil {
return fmt.Errorf("Unable to set permissions on global environment: %s", err.Error())
}
if err := common.PropertyWrite("config", "--global", "env-migrated", "true"); err != nil {
return fmt.Errorf("Unable to set env-migrated property: %s", err.Error())
}
return nil
// TriggerConfigMigrateEnv drains the pre-0.38 ENV files into the config
// property path. Exposed as a trigger so plugins that install before config can
// force the migration before reading a deprecated config var.
func TriggerConfigMigrateEnv() error {
return MigrateEnvFiles()
}
// TriggerInstall runs the install step for the config plugin
@@ -123,65 +90,7 @@ func TriggerInstall() error {
return fmt.Errorf("Unable to install the config plugin: %s", err.Error())
}
if err := migrateGlobalEnv(); err != nil {
return fmt.Errorf("Unable to migrate global environment: %s", err.Error())
}
apps, err := common.UnfilteredDokkuApps()
if err != nil {
return nil
}
// migrate all app ENV files to config path
for _, appName := range apps {
if err := common.PropertySetupApp("config", appName); err != nil {
return fmt.Errorf("Unable to setup app environment: %s", err.Error())
}
if err := setupAppConfigDir(appName); err != nil {
return fmt.Errorf("Unable to setup app config directory: %s", err.Error())
}
oldEnvFile := filepath.Join(common.AppRoot(appName), "ENV")
isMigrated := common.PropertyGetDefault("config", appName, "env-migrated", "")
// delete the old file on the next install
if isMigrated == "true" {
if err := os.RemoveAll(oldEnvFile); err != nil {
return fmt.Errorf("Unable to remove old ENV file: %s", err.Error())
}
continue
}
// skip if the file doesn't exist
if _, err := os.Stat(oldEnvFile); err != nil {
if err := common.PropertyWrite("config", appName, "env-migrated", "true"); err != nil {
return fmt.Errorf("Unable to set env-migrated property: %s", err.Error())
}
continue
}
// merge in the old env into the new env
oldEnv, err := loadFromFile(appName, oldEnvFile)
if err != nil {
return fmt.Errorf("Unable to load old environment: %s", err.Error())
}
env, err := LoadAppEnv(appName)
if err != nil {
return fmt.Errorf("Unable to load app environment: %s", err.Error())
}
env.Merge(oldEnv)
if err := env.Write(); err != nil {
return fmt.Errorf("Unable to write app environment: %s", err.Error())
}
if err := common.PropertyWrite("config", appName, "env-migrated", "true"); err != nil {
return fmt.Errorf("Unable to set env-migrated property: %s", err.Error())
}
}
return nil
return MigrateEnvFiles()
}
// TriggerPostAppCloneSetup creates new buildpacks files