featfeat: add ability to specify a custom app.json path
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
> New as of 0.5.0
|
||||
|
||||
## Usage
|
||||
|
||||
### Overview
|
||||
|
||||
Sometimes you need to run a command on deployment time, but before an app is completely deployed. Common use cases include:
|
||||
|
||||
- Checking a database is initialized
|
||||
@@ -49,7 +53,83 @@ Please keep the above in mind when utilizing deployment tasks.
|
||||
|
||||
> To execute commands on the host during a release phase, see the [plugin creation documentation](/docs/development/plugin-creation.md) docs for more information on building your own custom plugin.
|
||||
|
||||
## `app.json` deployment tasks
|
||||
### Changing the `app.json` location
|
||||
|
||||
When deploying a monorepo, it may be desirable to specify the specific path of the `app.json` file to use for a given app. This can be done via the `app-json:set` command.
|
||||
|
||||
```shell
|
||||
dokku app-json:set node-js-app appjson-path second-app.json
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option:
|
||||
|
||||
```shell
|
||||
dokku app-json:set node-js-app appjson-path
|
||||
```
|
||||
|
||||
The `appjson-path` property can also be set globally. The global default is `app.json`, and the global value is used when no app-specific value is set.
|
||||
|
||||
```shell
|
||||
dokku app-json:set --global appjson-path global-app.json
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option.
|
||||
|
||||
```shell
|
||||
dokku app-json:set --global appjson-path
|
||||
```
|
||||
|
||||
### Displaying app-json reports for an app
|
||||
|
||||
> New as of 0.25.0
|
||||
|
||||
You can get a report about the app's storage status using the `app-json:report` command:
|
||||
|
||||
```shell
|
||||
dokku app-json:report
|
||||
```
|
||||
|
||||
```
|
||||
=====> node-js-app app-json information
|
||||
App-json computed appjson path: app2.json
|
||||
App-json global appjson path: app.json
|
||||
App-json appjson path: app2.json
|
||||
=====> python-sample app-json information
|
||||
App-json computed appjson path: app.json
|
||||
App-json global appjson path: app.json
|
||||
App-json appjson path:
|
||||
=====> ruby-sample app-json information
|
||||
App-json computed appjson path: app.json
|
||||
App-json global appjson path: app.json
|
||||
App-json appjson path:
|
||||
```
|
||||
|
||||
You can run the command for a specific app also.
|
||||
|
||||
```shell
|
||||
dokku app-json:report node-js-app
|
||||
```
|
||||
|
||||
```
|
||||
=====> node-js-app app-json information
|
||||
App-json computed appjson path: app2.json
|
||||
App-json global appjson path: app.json
|
||||
App-json appjson path: app2.json
|
||||
```
|
||||
|
||||
You can pass flags which will output only the value of the specific information you want. For example:
|
||||
|
||||
```shell
|
||||
dokku app-json:report node-js-app --app-json-appjson-path
|
||||
```
|
||||
|
||||
```
|
||||
app2.json
|
||||
```
|
||||
|
||||
### Deployment tasks
|
||||
|
||||
#### `app.json` deployment tasks
|
||||
|
||||
Dokku provides limited support for the `app.json` manifest from Heroku (documentation available [here](https://devcenter.heroku.com/articles/app-json-schema)). The keys available for use with Deployment Tasks are:
|
||||
|
||||
@@ -75,7 +155,7 @@ The following is an example `app.json` file. Please note that only the `scripts.
|
||||
}
|
||||
```
|
||||
|
||||
## Procfile Release command
|
||||
#### Procfile Release command
|
||||
|
||||
> New as of 0.14.0
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
SUBCOMMANDS = subcommands/report subcommands/set
|
||||
TRIGGERS = triggers/install triggers/post-delete triggers/post-deploy triggers/pre-deploy
|
||||
BUILD = triggers
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = app-json
|
||||
|
||||
include ../../common.mk
|
||||
|
||||
@@ -6,6 +6,18 @@ import (
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultProperties is a map of all valid network properties with corresponding default property values
|
||||
DefaultProperties = map[string]string{
|
||||
"appjson-path": "",
|
||||
}
|
||||
|
||||
// GlobalProperties is a map of all valid global network properties
|
||||
GlobalProperties = map[string]bool{
|
||||
"appjson-path": true,
|
||||
}
|
||||
)
|
||||
|
||||
// AppJSON is a struct that represents an app.json file as understood by Dokku
|
||||
type AppJSON struct {
|
||||
Cron []CronCommand `json:"cron"`
|
||||
|
||||
@@ -448,6 +448,6 @@ func refreshAppJSON(appName string, image string) error {
|
||||
}
|
||||
}
|
||||
|
||||
common.CopyFromImage(appName, image, "app.json", appjsonPath)
|
||||
common.CopyFromImage(appName, image, reportComputedAppjsonpath(appName), appjsonPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
45
plugins/app-json/report.go
Normal file
45
plugins/app-json/report.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package appjson
|
||||
|
||||
import (
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
// ReportSingleApp is an internal function that displays the builder report for one or more apps
|
||||
func ReportSingleApp(appName string, format string, infoFlag string) error {
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flags := map[string]common.ReportFunc{
|
||||
"--app-json-computed-selected": reportComputedAppjsonpath,
|
||||
"--app-json-global-selected": reportGlobalAppjsonpath,
|
||||
"--app-json-selected": reportAppjsonpath,
|
||||
}
|
||||
|
||||
flagKeys := []string{}
|
||||
for flagKey := range flags {
|
||||
flagKeys = append(flagKeys, flagKey)
|
||||
}
|
||||
|
||||
trimPrefix := false
|
||||
uppercaseFirstCharacter := true
|
||||
infoFlags := common.CollectReport(appName, infoFlag, flags)
|
||||
return common.ReportSingleApp("app-json", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter)
|
||||
}
|
||||
|
||||
func reportComputedAppjsonpath(appName string) string {
|
||||
value := reportAppjsonpath(appName)
|
||||
if value == "" {
|
||||
value = reportGlobalAppjsonpath(appName)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalAppjsonpath(appName string) string {
|
||||
return common.PropertyGetDefault("app-json", "--global", "appjson-path", "app.json")
|
||||
}
|
||||
|
||||
func reportAppjsonpath(appName string) string {
|
||||
return common.PropertyGet("app-json", appName, "appjson-path")
|
||||
}
|
||||
56
plugins/app-json/src/commands/commands.go
Normal file
56
plugins/app-json/src/commands/commands.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
const (
|
||||
helpHeader = `Usage: dokku app-json[:COMMAND]
|
||||
|
||||
Manage app-json settings for an app
|
||||
|
||||
Additional commands:`
|
||||
|
||||
helpContent = `
|
||||
app-json:report [<app>] [<flag>], Displays a app-json report for one or more apps
|
||||
app-json:set <app> <property> (<value>), Set or clear a app-json property for an app
|
||||
`
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
cmd := flag.Arg(0)
|
||||
switch cmd {
|
||||
case "app-json", "app-json:help":
|
||||
usage()
|
||||
case "help":
|
||||
command := common.NewShellCmd(fmt.Sprintf("ps -o command= %d", os.Getppid()))
|
||||
command.ShowOutput = false
|
||||
output, err := command.Output()
|
||||
|
||||
if err == nil && strings.Contains(string(output), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
} else {
|
||||
fmt.Print("\n app-json, Manage app-json settings for an app\n")
|
||||
}
|
||||
default:
|
||||
dokkuNotImplementExitCode, err := strconv.Atoi(os.Getenv("DOKKU_NOT_IMPLEMENTED_EXIT"))
|
||||
if err != nil {
|
||||
fmt.Println("failed to retrieve DOKKU_NOT_IMPLEMENTED_EXIT environment variable")
|
||||
dokkuNotImplementExitCode = 10
|
||||
}
|
||||
os.Exit(dokkuNotImplementExitCode)
|
||||
}
|
||||
}
|
||||
|
||||
func usage() {
|
||||
common.CommandUsage(helpHeader, helpContent)
|
||||
}
|
||||
50
plugins/app-json/src/subcommands/subcommands.go
Normal file
50
plugins/app-json/src/subcommands/subcommands.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
appjson "github.com/dokku/dokku/plugins/app-json"
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// main entrypoint to all subcommands
|
||||
func main() {
|
||||
parts := strings.Split(os.Args[0], "/")
|
||||
subcommand := parts[len(parts)-1]
|
||||
|
||||
var err error
|
||||
switch subcommand {
|
||||
case "report":
|
||||
args := flag.NewFlagSet("app-json:report", flag.ExitOnError)
|
||||
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
||||
osArgs, infoFlag, flagErr := common.ParseReportArgs("appjson", os.Args[2:])
|
||||
if flagErr == nil {
|
||||
args.Parse(osArgs)
|
||||
appName := args.Arg(0)
|
||||
err = appjson.CommandReport(appName, *format, infoFlag)
|
||||
}
|
||||
case "set":
|
||||
args := flag.NewFlagSet("app-json:set", flag.ExitOnError)
|
||||
global := args.Bool("global", false, "--global: set a global property")
|
||||
args.Parse(os.Args[2:])
|
||||
appName := args.Arg(0)
|
||||
property := args.Arg(1)
|
||||
value := args.Arg(2)
|
||||
if *global {
|
||||
appName = "--global"
|
||||
property = args.Arg(0)
|
||||
value = args.Arg(1)
|
||||
}
|
||||
err = appjson.CommandSet(appName, property, value)
|
||||
default:
|
||||
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
common.LogFailWithError(err)
|
||||
}
|
||||
}
|
||||
29
plugins/app-json/subcommands.go
Normal file
29
plugins/app-json/subcommands.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package appjson
|
||||
|
||||
import (
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
// CommandReport displays a network report for one or more apps
|
||||
func CommandReport(appName string, format string, infoFlag string) error {
|
||||
if len(appName) == 0 {
|
||||
apps, err := common.DokkuApps()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, appName := range apps {
|
||||
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return ReportSingleApp(appName, format, infoFlag)
|
||||
}
|
||||
|
||||
// CommandSet set or clear a builder property for an app
|
||||
func CommandSet(appName string, property string, value string) error {
|
||||
common.CommandPropertySet("builder", appName, property, value, DefaultProperties, GlobalProperties)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user