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
|
> 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:
|
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
|
- 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.
|
> 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:
|
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
|
> 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
|
TRIGGERS = triggers/install triggers/post-delete triggers/post-deploy triggers/pre-deploy
|
||||||
BUILD = triggers
|
BUILD = commands subcommands triggers
|
||||||
PLUGIN_NAME = app-json
|
PLUGIN_NAME = app-json
|
||||||
|
|
||||||
include ../../common.mk
|
include ../../common.mk
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ import (
|
|||||||
"github.com/dokku/dokku/plugins/common"
|
"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
|
// AppJSON is a struct that represents an app.json file as understood by Dokku
|
||||||
type AppJSON struct {
|
type AppJSON struct {
|
||||||
Cron []CronCommand `json:"cron"`
|
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
|
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