feat: add support for formation key in app.json file

Still needs triggers for ps-can-scale and ps-scale-set.

Refs #4500
This commit is contained in:
Jose Diaz-Gonzalez
2021-03-22 00:24:56 -04:00
parent 9d0bc930a6
commit 6d9520e599
3 changed files with 52 additions and 8 deletions

View File

@@ -20,8 +20,9 @@ var (
// AppJSON is a struct that represents an app.json file as understood by Dokku
type AppJSON struct {
Cron []CronCommand `json:"cron"`
Scripts struct {
Cron []CronCommand `json:"cron"`
Formation map[string]Formation `json:"formation"`
Scripts struct {
Dokku struct {
Predeploy string `json:"predeploy"`
Postdeploy string `json:"postdeploy"`
@@ -36,6 +37,10 @@ type CronCommand struct {
Schedule string `json:"schedule"`
}
type Formation struct {
Quantity int `json:"quantity"`
}
// 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)

View File

@@ -79,24 +79,33 @@ func constructScript(command string, shell string, isHerokuishImage bool, isCnbI
return []string{shell, "-c", strings.Join(script, " ")}
}
// getPhaseScript extracts app.json from app image and returns the appropriate json key/value
func getPhaseScript(appName string, phase string) (string, error) {
func getAppJson(appName string) (AppJSON, error) {
if !common.FileExists(GetAppjsonPath(appName)) {
return "", nil
return AppJSON{}, nil
}
b, err := ioutil.ReadFile(GetAppjsonPath(appName))
if err != nil {
return "", fmt.Errorf("Cannot read app.json file: %v", err)
return AppJSON{}, fmt.Errorf("Cannot read app.json file: %v", err)
}
if strings.TrimSpace(string(b)) == "" {
return "", nil
return AppJSON{}, nil
}
var appJSON AppJSON
if err = json.Unmarshal(b, &appJSON); err != nil {
return "", fmt.Errorf("Cannot parse app.json: %v", err)
return AppJSON{}, fmt.Errorf("Cannot parse app.json: %v", err)
}
return AppJSON{}, nil
}
// getPhaseScript extracts app.json from app image and returns the appropriate json key/value
func getPhaseScript(appName string, phase string) (string, error) {
appJSON, err := getAppJson(appName)
if err != nil {
return "", err
}
if phase == "heroku.postdeploy" {
@@ -475,3 +484,29 @@ func refreshAppJSON(appName string, image string) error {
common.CopyFromImage(appName, image, reportComputedAppjsonpath(appName), appjsonPath)
return nil
}
func setScale(appName string, image string) error {
appJSON, err := getAppJson(appName)
if err != nil {
return err
}
args := []string{appName}
for processType, formation := range appJSON.Formation {
args = append(args, fmt.Sprintf("%s=%d", processType, formation.Quantity))
}
if len(args) == 1 {
return common.PlugnTrigger("ps-can-scale", []string{appName, "true"}...)
}
if err := common.PlugnTrigger("ps-can-scale", []string{appName, "false"}...); err != nil {
return err
}
if err := common.PlugnTrigger("ps-scale-set", args...); err != nil {
return err
}
return nil
}

View File

@@ -64,6 +64,10 @@ func TriggerPreDeploy(appName string, imageTag string) error {
return err
}
if err := setScale(appName, image); err != nil {
return err
}
if common.PropertyGet("common", appName, "deployed") == "true" {
return nil
}