diff --git a/plugins/app-json/Makefile b/plugins/app-json/Makefile index bf3adaa55..ebbcfa09c 100644 --- a/plugins/app-json/Makefile +++ b/plugins/app-json/Makefile @@ -1,5 +1,5 @@ SUBCOMMANDS = subcommands/report subcommands/set -TRIGGERS = triggers/app-json-process-deploy-parallelism triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/post-deploy triggers/pre-deploy triggers/report +TRIGGERS = triggers/app-json-process-deploy-parallelism triggers/install triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/post-deploy triggers/pre-deploy triggers/report BUILD = commands subcommands triggers PLUGIN_NAME = app-json diff --git a/plugins/app-json/appjson.go b/plugins/app-json/appjson.go index 471aa5caf..72568b95c 100644 --- a/plugins/app-json/appjson.go +++ b/plugins/app-json/appjson.go @@ -45,7 +45,7 @@ type Formation struct { // GetAppjsonDirectory returns the directory containing a given app's extracted app.json file func GetAppjsonDirectory(appName string) string { - return filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "app-json", appName) + return common.GetAppDataDirectory("app-json", appName) } // GetAppjsonPath returns the path to a given app's extracted app.json file diff --git a/plugins/app-json/functions.go b/plugins/app-json/functions.go index fe8c47c9b..109ed9b73 100644 --- a/plugins/app-json/functions.go +++ b/plugins/app-json/functions.go @@ -455,12 +455,12 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma } func refreshAppJSON(appName string, image string) error { - baseDirectory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "app-json") + baseDirectory := common.GetDataDirectory("app-json") if !common.DirectoryExists(baseDirectory) { return errors.New("Run 'dokku plugin:install' to ensure the correct directories exist") } - directory := GetAppjsonDirectory(appName) + directory := common.GetAppDataDirectory("app-json", appName) if !common.DirectoryExists(directory) { if err := os.MkdirAll(directory, 0755); err != nil { return err @@ -514,7 +514,7 @@ func injectDokkuScale(appName string, image string) error { return err } - baseDirectory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "app-json") + baseDirectory := common.GetDataDirectory("app-json") if !common.DirectoryExists(baseDirectory) { return errors.New("Run 'dokku plugin:install' to ensure the correct directories exist") } diff --git a/plugins/app-json/src/triggers/triggers.go b/plugins/app-json/src/triggers/triggers.go index e3a63e81e..4c610d024 100644 --- a/plugins/app-json/src/triggers/triggers.go +++ b/plugins/app-json/src/triggers/triggers.go @@ -28,6 +28,10 @@ func main() { oldAppName := flag.Arg(0) newAppName := flag.Arg(1) err = appjson.TriggerPostAppCloneSetup(oldAppName, newAppName) + case "post-app-rename": + oldAppName := flag.Arg(0) + newAppName := flag.Arg(1) + err = appjson.TriggerPostAppRename(oldAppName, newAppName) case "post-app-rename-setup": oldAppName := flag.Arg(0) newAppName := flag.Arg(1) diff --git a/plugins/app-json/triggers.go b/plugins/app-json/triggers.go index d0b24039a..37a7fab34 100644 --- a/plugins/app-json/triggers.go +++ b/plugins/app-json/triggers.go @@ -3,7 +3,6 @@ package appjson import ( "fmt" "os" - "path/filepath" "github.com/dokku/dokku/plugins/common" ) @@ -34,18 +33,17 @@ func TriggerAppJSONProcessDeployParallelism(appName string, processType string) return nil } -// TriggerInstall initializes app restart policies +// TriggerInstall initializes app-json directory structures func TriggerInstall() error { if err := common.PropertySetup("app-json"); err != nil { return fmt.Errorf("Unable to install the app-json plugin: %s", err.Error()) } - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "app-json") - if err := os.MkdirAll(directory, 0755); err != nil { + if err := common.SetupAppData("app-json"); err != nil { return err } - return common.SetPermissions(directory, 0755) + return nil } // TriggerPostAppCloneSetup creates new app-json files @@ -55,7 +53,12 @@ func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error { return err } - return nil + return common.CloneAppData("app-json", oldAppName, newAppName) +} + +// TriggerPostAppRename removes the old app data +func TriggerPostAppRename(oldAppName string, newAppName string) error { + return common.RemoveAppDataDirectory("app-json", oldAppName) } // TriggerPostAppRenameSetup renames app-json files @@ -68,13 +71,17 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error { return err } - return nil + return common.CloneAppData("app-json", oldAppName, newAppName) +} + +// TriggerPostCreate ensures apps the correct data directory structure +func TriggerPostCreate(appName string) error { + return common.CreateAppDataDirectory("app-json", appName) } // TriggerPostDelete destroys the app-json data for a given app container func TriggerPostDelete(appName string) error { - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "app-json", appName) - dataErr := os.RemoveAll(directory) + dataErr := os.RemoveAll(common.GetAppDataDirectory("app-json", appName)) propertyErr := common.PropertyDestroy("app-json", appName) if dataErr != nil { diff --git a/plugins/common/data.go b/plugins/common/data.go new file mode 100644 index 000000000..ad8c1dea8 --- /dev/null +++ b/plugins/common/data.go @@ -0,0 +1,82 @@ +package common + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/otiai10/copy" +) + +// CreateAppDataDirectory creates a data directory for the given plugin/app combination with the correct permissions +func CreateAppDataDirectory(pluginName, appName string) error { + directory := GetAppDataDirectory(pluginName, appName) + if err := os.MkdirAll(directory, 0755); err != nil { + return err + } + + if err := SetPermissions(directory, 0755); err != nil { + return err + } + + return nil +} + +// CreateDataDirectory creates a data directory for the given plugin/app combination with the correct permissions +func CreateDataDirectory(pluginName string) error { + directory := GetDataDirectory(pluginName) + if err := os.MkdirAll(directory, 0755); err != nil { + return err + } + + if err := SetPermissions(directory, 0755); err != nil { + return err + } + + return nil +} + +// GetAppDataDirectory returns the path to the data directory for the given plugin/app combination +func GetAppDataDirectory(pluginName string, appName string) string { + return filepath.Join(GetDataDirectory(pluginName), appName) +} + +// GetDataDirectory returns the path to the data directory for the specified plugin +func GetDataDirectory(pluginName string) string { + return filepath.Join(MustGetEnv("DOKKU_LIB_ROOT"), "data", pluginName) +} + +// RemoveAppDataDirectory removes the path to the data directory for the given plugin/app combination +func RemoveAppDataDirectory(pluginName, appName string) error { + return os.RemoveAll(GetAppDataDirectory(pluginName, appName)) +} + +func CloneAppData(pluginName string, oldAppName string, newAppName string) error { + oldDataDir := GetAppDataDirectory(pluginName, oldAppName) + newDataDir := GetAppDataDirectory(pluginName, newAppName) + if err := copy.Copy(oldDataDir, newDataDir); err != nil { + return fmt.Errorf("Unable to clone app data to new location: %v", err.Error()) + } + + return nil +} + +// SetupAppData creates +func SetupAppData(pluginName string) error { + if err := CreateDataDirectory(pluginName); err != nil { + return err + } + + apps, err := UnfilteredDokkuApps() + if err != nil { + return nil + } + + for _, appName := range apps { + if err := CreateAppDataDirectory(pluginName, appName); err != nil { + return err + } + } + + return nil +} diff --git a/plugins/logs/Makefile b/plugins/logs/Makefile index a8eb7dde4..a27ed3931 100644 --- a/plugins/logs/Makefile +++ b/plugins/logs/Makefile @@ -1,5 +1,5 @@ SUBCOMMANDS = subcommands/failed subcommands/report subcommands/set subcommands/vector-logs subcommands/vector-start subcommands/vector-stop -TRIGGERS = triggers/docker-args-process-deploy triggers/install triggers/logs-get-property triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report +TRIGGERS = triggers/docker-args-process-deploy triggers/install triggers/logs-get-property triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/report BUILD = commands subcommands triggers PLUGIN_NAME = logs diff --git a/plugins/logs/functions.go b/plugins/logs/functions.go index 01b2153f1..14cb3d5c9 100644 --- a/plugins/logs/functions.go +++ b/plugins/logs/functions.go @@ -223,7 +223,7 @@ func writeVectorConfig() error { b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1) b = bytes.Replace(b, []byte("\\u002B"), []byte("+"), -1) - vectorConfig := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "logs", "vector.json") + vectorConfig := filepath.Join(common.GetDataDirectory("logs"), "vector.json") if err := common.WriteSliceToFile(vectorConfig, []string{string(b)}); err != nil { return err } diff --git a/plugins/logs/src/triggers/triggers.go b/plugins/logs/src/triggers/triggers.go index b9b17be0d..4545ef516 100644 --- a/plugins/logs/src/triggers/triggers.go +++ b/plugins/logs/src/triggers/triggers.go @@ -31,6 +31,10 @@ func main() { oldAppName := flag.Arg(0) newAppName := flag.Arg(1) err = logs.TriggerPostAppCloneSetup(oldAppName, newAppName) + case "post-app-rename": + oldAppName := flag.Arg(0) + newAppName := flag.Arg(1) + err = logs.TriggerPostAppRename(oldAppName, newAppName) case "post-app-rename-setup": oldAppName := flag.Arg(0) newAppName := flag.Arg(1) diff --git a/plugins/logs/subcommands.go b/plugins/logs/subcommands.go index 365a67892..6808c8352 100644 --- a/plugins/logs/subcommands.go +++ b/plugins/logs/subcommands.go @@ -75,7 +75,7 @@ func CommandSet(appName string, property string, value string) error { common.CommandPropertySet("logs", appName, property, value, DefaultProperties, GlobalProperties) if property == "vector-sink" { - common.LogVerboseQuiet(fmt.Sprintf("Writing updated vector config to %s", filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "logs", "vector.json"))) + common.LogVerboseQuiet(fmt.Sprintf("Writing updated vector config to %s", filepath.Join(common.GetDataDirectory("logs"), "vector.json"))) return writeVectorConfig() } return nil diff --git a/plugins/logs/triggers.go b/plugins/logs/triggers.go index b62a65411..870ce29c6 100644 --- a/plugins/logs/triggers.go +++ b/plugins/logs/triggers.go @@ -69,18 +69,13 @@ func TriggerDockerArgsProcessDeploy(appName string) error { return nil } -// TriggerInstall initializes app restart policies +// TriggerInstall initializes log configuration func TriggerInstall() error { if err := common.PropertySetup("logs"); err != nil { return fmt.Errorf("Unable to install the logs plugin: %s", err.Error()) } - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "logs") - if err := os.MkdirAll(directory, 0755); err != nil { - return err - } - - if err := common.SetPermissions(directory, 0755); err != nil { + if err := common.SetupAppData("logs"); err != nil { return err } @@ -118,7 +113,12 @@ func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error { return err } - return nil + return common.CloneAppData("logs", oldAppName, newAppName) +} + +// TriggerPostAppRename removes the old app data +func TriggerPostAppRename(oldAppName string, newAppName string) error { + return common.RemoveAppDataDirectory("logs", oldAppName) } // TriggerPostAppRenameSetup renames logs files @@ -131,10 +131,22 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error { return err } - return nil + return common.CloneAppData("logs", oldAppName, newAppName) +} + +// TriggerPostCreate ensures apps the correct data directory structure +func TriggerPostCreate(appName string) error { + return common.CreateAppDataDirectory("logs", appName) } // TriggerPostDelete destroys the logs property for a given app container func TriggerPostDelete(appName string) error { - return common.PropertyDestroy("logs", appName) + dataErr := os.RemoveAll(common.GetAppDataDirectory("logs", appName)) + propertyErr := common.PropertyDestroy("logs", appName) + + if dataErr != nil { + return dataErr + } + + return propertyErr } diff --git a/plugins/ps/functions.go b/plugins/ps/functions.go index c6b31daad..f7e5a7a1d 100644 --- a/plugins/ps/functions.go +++ b/plugins/ps/functions.go @@ -66,7 +66,7 @@ func getProcfileCommand(procfilePath string, processType string, port int) (stri } func getProcfilePath(appName string) string { - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "ps", appName) + directory := common.GetAppDataDirectory("ps", appName) return filepath.Join(directory, "Procfile") } diff --git a/plugins/ps/subcommands.go b/plugins/ps/subcommands.go index 02aeb2058..f818d8140 100644 --- a/plugins/ps/subcommands.go +++ b/plugins/ps/subcommands.go @@ -104,7 +104,7 @@ func CommandRestore(appName string, allApps bool, parallelCount int) error { // CommandRetire ensures old containers are retired func CommandRetire(appName string) error { - lockFile := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "ps", "retire") + lockFile := filepath.Join(common.GetDataDirectory("ps"), "retire") scheduler := "" if appName == "" { scheduler = common.GetGlobalScheduler() diff --git a/plugins/ps/triggers.go b/plugins/ps/triggers.go index c6ef96a8e..2c8baec8c 100644 --- a/plugins/ps/triggers.go +++ b/plugins/ps/triggers.go @@ -116,12 +116,7 @@ func TriggerInstall() error { return fmt.Errorf("Unable to install the ps plugin: %s", err.Error()) } - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "ps") - if err := os.MkdirAll(directory, 0755); err != nil { - return err - } - - if err := common.SetPermissions(directory, 0755); err != nil { + if err := common.SetupAppData("ps"); err != nil { return err } @@ -130,6 +125,12 @@ func TriggerInstall() error { return nil } + for _, appName := range apps { + if err := common.CreateAppDataDirectory("ps", appName); err != nil { + return err + } + } + for _, appName := range apps { policies, err := getRestartPolicy(appName) if err != nil { @@ -188,12 +189,15 @@ func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error { return err } - // TODO: Copy data dir - return nil + return common.CloneAppData("ps", oldAppName, newAppName) } // TriggerPostAppRename rebuilds the renamed app func TriggerPostAppRename(oldAppName string, newAppName string) error { + if err := common.RemoveAppDataDirectory("ps", oldAppName); err != nil { + return err + } + if os.Getenv("SKIP_REBUILD") == "true" { return nil } @@ -211,8 +215,7 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error { return err } - // TODO: Move data dir - return nil + return common.CloneAppData("ps", oldAppName, newAppName) } // TriggerPostCreate ensures apps have a default restart policy @@ -222,12 +225,7 @@ func TriggerPostCreate(appName string) error { return err } - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "ps", appName) - if err := os.MkdirAll(directory, 0755); err != nil { - return err - } - - if err := common.SetPermissions(directory, 0755); err != nil { + if err := common.CreateAppDataDirectory("ps", appName); err != nil { return err } @@ -242,8 +240,7 @@ func TriggerPostCreate(appName string) error { // TriggerPostDelete destroys the ps properties for a given app container func TriggerPostDelete(appName string) error { - directory := filepath.Join(common.MustGetEnv("DOKKU_LIB_ROOT"), "data", "ps", appName) - dataErr := os.RemoveAll(directory) + dataErr := common.RemoveAppDataDirectory("ps", appName) propertyErr := common.PropertyDestroy("ps", appName) if dataErr != nil {