feat: implement app-json-is-valid plugin trigger
This commit is contained in:
@@ -200,21 +200,9 @@ func GetAppJSON(appName string) (AppJSON, error) {
|
||||
return AppJSON{}, nil
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(getProcessSpecificAppJSONPath(appName))
|
||||
if err != nil {
|
||||
return AppJSON{}, fmt.Errorf("Cannot read app.json file: %v", err)
|
||||
}
|
||||
appJSONPath := getProcessSpecificAppJSONPath(appName)
|
||||
|
||||
if strings.TrimSpace(string(b)) == "" {
|
||||
return AppJSON{}, nil
|
||||
}
|
||||
|
||||
var appJSON AppJSON
|
||||
if err = json.Unmarshal(b, &appJSON); err != nil {
|
||||
return AppJSON{}, fmt.Errorf("Cannot parse app.json: %v", err)
|
||||
}
|
||||
|
||||
return appJSON, nil
|
||||
return ReadAppJSON(appJSONPath)
|
||||
}
|
||||
|
||||
func GetAutoscalingConfig(appName string, processType string, replicas int) (FormationAutoscaling, bool, error) {
|
||||
@@ -256,3 +244,22 @@ func GetAutoscalingConfig(appName string, processType string, replicas int) (For
|
||||
|
||||
return autoscaling, true, nil
|
||||
}
|
||||
|
||||
// ReadAppJSON reads an app.json file from a given path
|
||||
func ReadAppJSON(path string) (AppJSON, error) {
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return AppJSON{}, fmt.Errorf("Cannot read app.json file: %v", err)
|
||||
}
|
||||
|
||||
if strings.TrimSpace(string(b)) == "" {
|
||||
return AppJSON{}, nil
|
||||
}
|
||||
|
||||
var appJSON AppJSON
|
||||
if err = json.Unmarshal(b, &appJSON); err != nil {
|
||||
return AppJSON{}, fmt.Errorf("Cannot parse app.json: %v", err)
|
||||
}
|
||||
|
||||
return appJSON, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package appjson
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@@ -142,31 +142,16 @@ func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
|
||||
}
|
||||
|
||||
if hasAppJSON(appName) {
|
||||
b, err := os.ReadFile(processSpecificAppJSON)
|
||||
result, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
|
||||
Trigger: "app-json-is-valid",
|
||||
Args: []string{appName, processSpecificAppJSON},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
content := strings.TrimSpace(string(b))
|
||||
if content == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var appJSON AppJSON
|
||||
if err := json.Unmarshal([]byte(content), &appJSON); err != nil {
|
||||
return fmt.Errorf("Unable to unmarshal app.json: %v", err.Error())
|
||||
}
|
||||
|
||||
if appJSON.Cron != nil {
|
||||
for i, c := range appJSON.Cron {
|
||||
if c.Command == "" {
|
||||
return fmt.Errorf("Missing cron command for app %s (index %d)", appName, i)
|
||||
}
|
||||
|
||||
if c.Schedule == "" {
|
||||
return fmt.Errorf("Missing cron schedule for app %s (index %d)", appName, i)
|
||||
}
|
||||
if result.StderrContents() != "" {
|
||||
return errors.New(result.StderrContents())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,21 +62,32 @@ func (t TemplateCommand) CronCommand() string {
|
||||
return fmt.Sprintf("dokku run --cron-id %s %s %s", t.ID, t.App, t.Command)
|
||||
}
|
||||
|
||||
// FetchCronEntriesInput is the input for the FetchCronEntries function
|
||||
type FetchCronEntriesInput struct {
|
||||
AppName string
|
||||
AppJSON *appjson.AppJSON
|
||||
}
|
||||
|
||||
// FetchCronEntries returns a list of cron commands for a given app
|
||||
func FetchCronEntries(appName string) ([]TemplateCommand, error) {
|
||||
func FetchCronEntries(input FetchCronEntriesInput) ([]TemplateCommand, error) {
|
||||
appName := input.AppName
|
||||
commands := []TemplateCommand{}
|
||||
isMaintenance := reportComputedMaintenance(appName) == "true"
|
||||
|
||||
appJSON, err := appjson.GetAppJSON(appName)
|
||||
if err != nil {
|
||||
return commands, fmt.Errorf("Unable to fetch app.json for app %s: %s", appName, err.Error())
|
||||
if input.AppJSON == nil {
|
||||
appJSON, err := appjson.GetAppJSON(appName)
|
||||
if err != nil {
|
||||
return commands, fmt.Errorf("Unable to fetch app.json for app %s: %s", appName, err.Error())
|
||||
}
|
||||
|
||||
input.AppJSON = &appJSON
|
||||
}
|
||||
|
||||
if appJSON.Cron == nil {
|
||||
if input.AppJSON.Cron == nil {
|
||||
return commands, nil
|
||||
}
|
||||
|
||||
for i, c := range appJSON.Cron {
|
||||
for i, c := range input.AppJSON.Cron {
|
||||
if c.Command == "" {
|
||||
common.LogWarn(fmt.Sprintf("Missing cron command for app %s (index %d)", appName, i))
|
||||
continue
|
||||
|
||||
@@ -41,7 +41,7 @@ func reportMailto(_ string) string {
|
||||
}
|
||||
|
||||
func reportTasks(appName string) string {
|
||||
c, _ := FetchCronEntries(appName)
|
||||
c, _ := FetchCronEntries(FetchCronEntriesInput{AppName: appName})
|
||||
return strconv.Itoa(len(c))
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ func CommandList(appName string, format string) error {
|
||||
return fmt.Errorf("Invalid format specified, supported formats: json, stdout")
|
||||
}
|
||||
|
||||
entries, err := FetchCronEntries(appName)
|
||||
entries, err := FetchCronEntries(FetchCronEntriesInput{AppName: appName})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -79,7 +79,7 @@ func CommandRun(appName string, cronID string, detached bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
entries, err := FetchCronEntries(appName)
|
||||
entries, err := FetchCronEntries(FetchCronEntriesInput{AppName: appName})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
appjson "github.com/dokku/dokku/plugins/app-json"
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
@@ -23,6 +24,25 @@ func TriggerCronGetProperty(appName string, key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TriggerAppJSONIsValid validates the cron entries for a given app
|
||||
func TriggerAppJSONIsValid(appName string, appJSONPath string) error {
|
||||
if !common.FileExists(appJSONPath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
appJSON, err := appjson.ReadAppJSON(appJSONPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = FetchCronEntries(FetchCronEntriesInput{AppName: appName, AppJSON: &appJSON})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TriggerInstall runs the install step for the cron plugin
|
||||
func TriggerInstall() error {
|
||||
if err := common.PropertySetup("cron"); err != nil {
|
||||
|
||||
@@ -52,7 +52,7 @@ func generateCronEntries() ([]cron.TemplateCommand, error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := cron.FetchCronEntries(appName)
|
||||
c, err := cron.FetchCronEntries(cron.FetchCronEntriesInput{AppName: appName})
|
||||
if err != nil {
|
||||
results <- []cron.TemplateCommand{}
|
||||
common.LogWarn(err.Error())
|
||||
|
||||
@@ -266,7 +266,7 @@ func TriggerSchedulerDeploy(scheduler string, appName string, imageTag string) e
|
||||
|
||||
workingDir := common.GetWorkingDir(appName, image)
|
||||
|
||||
allCronEntries, err := cron.FetchCronEntries(appName)
|
||||
allCronEntries, err := cron.FetchCronEntries(cron.FetchCronEntriesInput{AppName: appName})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error fetching cron entries: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user