diff --git a/docs/processes/process-management.md b/docs/processes/process-management.md index 20f372c89..80e219291 100644 --- a/docs/processes/process-management.md +++ b/docs/processes/process-management.md @@ -4,15 +4,15 @@ > New as of 0.3.14, Enhanced in 0.7.0 ``` -ps:inspect # Displays a sanitized version of docker inspect for an app -ps:rebuild [--parallel count] [--all|] # Rebuilds an app from source -ps:report [] [] # Displays a process report for one or more apps -ps:restart [--parallel count] [--all|] [] # Restart an app -ps:restore [] # Start previously running apps e.g. after reboot -ps:scale [--skip-deploy] = [=...] # Get/Set how many instances of a given process to run -ps:set # Set or clear a ps property for an app -ps:start [--parallel count] [--all|] # Start an app -ps:stop [--parallel count] [--all|] # Stop an app +ps:inspect # Displays a sanitized version of docker inspect for an app +ps:rebuild [--parallel count] [--all|] # Rebuilds an app from source +ps:report [] [] # Displays a process report for one or more apps +ps:restart [--parallel count] [--all|] [] # Restart an app +ps:restore [] # Start previously running apps e.g. after reboot +ps:scale [--skip-deploy] [--format stdout|json] [=...] # Get/Set how many instances of a given process to run +ps:set # Set or clear a ps property for an app +ps:start [--parallel count] [--all|] # Start an app +ps:stop [--parallel count] [--all|] # Stop an app ``` ## Usage @@ -107,6 +107,18 @@ proctype: qty web: 1 ``` +The formation can also be retrieved as JSON by using the `--format json` flag, which is useful for programmatic consumption. Each entry maps a process type to its desired quantity: + +```shell +dokku ps:scale node-js-app --format json +``` + +```json +[{"process_type":"web","quantity":1},{"process_type":"worker","quantity":4}] +``` + +When no scale has been set for the app, the JSON output is an empty array (`[]`). + ### Changing process management settings The `ps` plugin provides a number of settings that can be used to managed deployments on a per-app basis. The following table outlines ones not covered elsewhere: diff --git a/plugins/ps/functions.go b/plugins/ps/functions.go index 068f8ab9e..a32e0b38d 100644 --- a/plugins/ps/functions.go +++ b/plugins/ps/functions.go @@ -1,6 +1,7 @@ package ps import ( + "encoding/json" "errors" "fmt" "os" @@ -243,12 +244,22 @@ func restorePrep() error { return nil } -func scaleReport(appName string) error { +func scaleReport(appName string, format string) error { formations, err := getFormations(appName) if err != nil { return err } + if format == "json" { + out, err := json.Marshal(formations) + if err != nil { + return err + } + + common.Log(string(out)) + return nil + } + common.LogInfo1Quiet(fmt.Sprintf("Scaling for %s", appName)) content := []string{} diff --git a/plugins/ps/src/commands/commands.go b/plugins/ps/src/commands/commands.go index 98a0c830d..6063bfcf5 100644 --- a/plugins/ps/src/commands/commands.go +++ b/plugins/ps/src/commands/commands.go @@ -23,7 +23,7 @@ Additional commands:` ps:report [] [], Displays a process report for one or more apps ps:restart [--parallel count] [--all|] [], Restart an app ps:restore [], Start previously running apps e.g. after reboot - ps:scale [--skip-deploy] = [=...], Get/Set how many instances of a given process to run + ps:scale [--skip-deploy] [--format stdout|json] [=...], Get/Set how many instances of a given process to run ps:set , Set or clear a ps property for an app ps:start [--parallel count] [--all|], Start an app ps:stop [--parallel count] [--all|], Stop an app diff --git a/plugins/ps/src/subcommands/subcommands.go b/plugins/ps/src/subcommands/subcommands.go index 440640214..91e41c5cb 100644 --- a/plugins/ps/src/subcommands/subcommands.go +++ b/plugins/ps/src/subcommands/subcommands.go @@ -65,10 +65,11 @@ func main() { case "scale": args := flag.NewFlagSet("ps:scale", flag.ExitOnError) skipDeploy := args.Bool("skip-deploy", false, "--skip-deploy: skip deploy of the app") + format := args.String("format", "stdout", "format: [ stdout | json ]") args.Parse(os.Args[2:]) appName := args.Arg(0) _, processTuples := common.ShiftString(args.Args()) - err = ps.CommandScale(appName, *skipDeploy, processTuples) + err = ps.CommandScale(appName, *skipDeploy, *format, processTuples) case "set": args := flag.NewFlagSet("ps:set", flag.ExitOnError) global := args.Bool("global", false, "--global: set a global property") diff --git a/plugins/ps/subcommands.go b/plugins/ps/subcommands.go index e19af314d..14f8ef9e4 100644 --- a/plugins/ps/subcommands.go +++ b/plugins/ps/subcommands.go @@ -158,13 +158,13 @@ func CommandRetire(appName string) error { } // CommandScale gets or sets how many instances of a given process to run -func CommandScale(appName string, skipDeploy bool, processTuples []string) error { +func CommandScale(appName string, skipDeploy bool, format string, processTuples []string) error { if err := common.VerifyAppName(appName); err != nil { return err } if len(processTuples) == 0 { - return scaleReport(appName) + return scaleReport(appName, format) } if !canScaleApp(appName) { diff --git a/tests/unit/ps-general-1.bats b/tests/unit/ps-general-1.bats index 175e108ae..20a00858d 100644 --- a/tests/unit/ps-general-1.bats +++ b/tests/unit/ps-general-1.bats @@ -269,6 +269,42 @@ web assert_output $'beat: 0\nweb: 4\nworker: 1' } +@test "(ps:scale) --format json" { + run /bin/bash -c "dokku ps:scale $TEST_APP --format json" + echo "output: $output" + echo "status: $status" + assert_success + assert_output '[{"process_type":"web","quantity":1}]' + + echo "web=4 +worker=1" >/var/lib/dokku/config/ps/$TEST_APP/scale + + run /bin/bash -c "dokku ps:scale $TEST_APP --format json | jq '. | length'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "2" + + run /bin/bash -c "dokku ps:scale $TEST_APP --format json | jq -r '.[] | select(.process_type==\"web\") | .quantity'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "4" + + run /bin/bash -c "dokku ps:scale $TEST_APP --format json | jq -r '.[] | select(.process_type==\"worker\") | .quantity'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1" + + rm -f /var/lib/dokku/config/ps/$TEST_APP/scale + run /bin/bash -c "dokku ps:scale $TEST_APP --format json" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "[]" +} + @test "(ps) handle windows newlines in procfile" { run deploy_app python dokku@$DOKKU_DOMAIN:$TEST_APP procfile_line_endings_to_windows echo "output: $output"