Merge pull request #4502 from dokku/4501-monorepo-support
Add monorepo support
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. If a value is specified and that file does not exist within the repository, Dokku will continue the build process as if the repository has no `app.json` file.
|
||||
|
||||
```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
|
||||
|
||||
|
||||
@@ -3,3 +3,7 @@
|
||||
## Changes
|
||||
|
||||
- The network plugin can now set an `initial-network` for all containers on creation. This is a replacement for specifying the `--network` flag via the `docker-options` plugin. Please see the [network documentation](/docs/networking/network.md#attaching-an-app-to-a-network) for more information.
|
||||
|
||||
## Deprecations
|
||||
|
||||
- In previous versions of Dokku, the only way to specify a custom `Dockerfile` was to use the `docker-options` plugin to set the `--file` flag for a docker build. As of 0.25.0, the `builder-dockerfile:set` command should be used instead, as outlined in the [docs here](/docs/deployment/builders/dockerfiles.md#changingthe-dockerfile-location). Usage of the old method should be migrated to the new method.
|
||||
|
||||
@@ -47,6 +47,34 @@ The default value may be set by passing an empty value for the option.
|
||||
dokku builder:set --global selected
|
||||
```
|
||||
|
||||
#### Changing the build directory
|
||||
|
||||
> Warning: Please keep in mind that setting a custom build directory will result in loss of any changes to the top-level directory, such as the `git.keep-git-dir` property.
|
||||
|
||||
When deploying a monorepo, it may be desirable to specify the specific build directory to use for a given app. This can be done via the `builder:set` command. If a value is specified and that directory does not exist within the repository, the build will fail.
|
||||
|
||||
```shell
|
||||
dokku builder:set node-js-app build-dir app2
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option:
|
||||
|
||||
```shell
|
||||
dokku builder:set node-js-app build-dir
|
||||
```
|
||||
|
||||
The `build-dir` property can also be set globally. The global default is empty string, and the global value is used when no app-specific value is set.
|
||||
|
||||
```shell
|
||||
dokku builder:set --global build-dir app2
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option.
|
||||
|
||||
```shell
|
||||
dokku builder:set --global build-dir
|
||||
```
|
||||
|
||||
### Displaying builder reports for an app
|
||||
|
||||
You can get a report about the app's builder status using the `builder:report` command:
|
||||
@@ -57,15 +85,24 @@ dokku builder:report
|
||||
|
||||
```
|
||||
=====> node-js-app builder information
|
||||
Builder computed selected: herokuish
|
||||
Builder build dir: custom
|
||||
Builder computed build dir: custom
|
||||
Builder computed selected: herokuish
|
||||
Builder global build dir:
|
||||
Builder global selected: herokuish
|
||||
Builder selected: herokuish
|
||||
=====> python-sample builder information
|
||||
Builder build dir:
|
||||
Builder computed build dir:
|
||||
Builder computed selected: dockerfile
|
||||
Builder global build dir:
|
||||
Builder global selected: herokuish
|
||||
Builder selected: dockerfile
|
||||
=====> ruby-sample builder information
|
||||
Builder build dir:
|
||||
Builder computed build dir:
|
||||
Builder computed selected: herokuish
|
||||
Builder global build dir:
|
||||
Builder global selected: herokuish
|
||||
Builder selected:
|
||||
```
|
||||
|
||||
@@ -12,25 +12,6 @@ Cloud Native Buildpacks are an evolution over the Buildpacks technology provided
|
||||
|
||||
## Usage
|
||||
|
||||
### Detection
|
||||
|
||||
This builder will be auto-detected in either the following cases:
|
||||
|
||||
- The `DOKKU_CNB_EXPERIMENTAL` app environment variable is set to `1`.
|
||||
```shell
|
||||
dokku config:set --no-restart node-js-app DOKKU_CNB_EXPERIMENTAL=1
|
||||
```
|
||||
- A `project.toml` file exists in the root of the app repository.
|
||||
- This file is consumed by `pack-cli` and used to describe how the app is built.
|
||||
|
||||
The builder can also be specified via the `builder:set` command:
|
||||
|
||||
```shell
|
||||
dokku builder:set node-js-app selected pack
|
||||
```
|
||||
|
||||
> Dokku will only select the `dockerfile` builder if both the `herokuish` and `pack` builders are not detected and a Dockerfile exists. See the [dockerfile builder documentation](/docs/deployment/builders/dockerfiles.md) for more information on how that builder functions.
|
||||
|
||||
### Requirements
|
||||
|
||||
The `pack` cli tool is not included by default with Dokku or as a dependency. It must also be installed as shown on [this page](https://buildpacks.io/docs/tools/pack/).
|
||||
@@ -51,6 +32,99 @@ As this functionality is highly experimental, there are a number of caveats. Ple
|
||||
- `pack` is not currently included with Dokku, nor is it added as a package dependency.
|
||||
- A future version will include it as a package dependency.
|
||||
|
||||
### Detection
|
||||
|
||||
This builder will be auto-detected in either the following cases:
|
||||
|
||||
- The `DOKKU_CNB_EXPERIMENTAL` app environment variable is set to `1`.
|
||||
```shell
|
||||
dokku config:set --no-restart node-js-app DOKKU_CNB_EXPERIMENTAL=1
|
||||
```
|
||||
- A `project.toml` file exists in the root of the app repository.
|
||||
- This file is consumed by `pack-cli` and used to describe how the app is built.
|
||||
|
||||
The builder can also be specified via the `builder:set` command:
|
||||
|
||||
```shell
|
||||
dokku builder:set node-js-app selected pack
|
||||
```
|
||||
|
||||
> Dokku will only select the `dockerfile` builder if both the `herokuish` and `pack` builders are not detected and a Dockerfile exists. See the [dockerfile builder documentation](/docs/deployment/builders/dockerfiles.md) for more information on how that builder functions.
|
||||
|
||||
### Changing the `project.toml` location
|
||||
|
||||
When deploying a monorepo, it may be desirable to specify the specific path of the `project.toml` file to use for a given app. This can be done via the `builder-pack:set` command. If a value other than `project.toml` is specified and that file does not exist in the app's build directory, Dokku will continue the build process as if the repository has no `project.toml`.
|
||||
|
||||
```shell
|
||||
dokku builder-pack:set node-js-app projecttoml-path project2.toml
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option:
|
||||
|
||||
```shell
|
||||
dokku builder-pack:set node-js-app projecttoml-path
|
||||
```
|
||||
|
||||
The `projecttoml-path` property can also be set globally. The global default is `project.toml`, and the global value is used when no app-specific value is set.
|
||||
|
||||
```shell
|
||||
dokku builder-pack:set --global projecttoml-path project2.toml
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option.
|
||||
|
||||
```shell
|
||||
dokku builder-pack:set --global projecttoml-path
|
||||
```
|
||||
|
||||
### Displaying builder-pack reports for an app
|
||||
|
||||
> New as of 0.25.0
|
||||
|
||||
You can get a report about the app's storage status using the `builder-pack:report` command:
|
||||
|
||||
```shell
|
||||
dokku app-json:report
|
||||
```
|
||||
|
||||
```
|
||||
=====> node-js-app builder-pack information
|
||||
Builder-pack computed projecttoml path: project2.toml
|
||||
Builder-pack global projecttoml path: project.toml
|
||||
Builder-pack projecttoml path: project2.toml
|
||||
=====> python-sample builder-pack information
|
||||
Builder-pack computed projecttoml path: project.toml
|
||||
Builder-pack global projecttoml path: project.toml
|
||||
Builder-pack projecttoml path:
|
||||
=====> ruby-sample builder-pack information
|
||||
Builder-pack computed projecttoml path: project.toml
|
||||
Builder-pack global projecttoml path: project.json
|
||||
Builder-pack projecttoml path:
|
||||
```
|
||||
|
||||
You can run the command for a specific app also.
|
||||
|
||||
```shell
|
||||
dokku builder-pack:report node-js-app
|
||||
```
|
||||
|
||||
```
|
||||
=====> node-js-app builder-pack information
|
||||
Builder-pack computed projecttoml path: project2.toml
|
||||
Builder-pack global projecttoml path: project.toml
|
||||
Builder-pack projecttoml path: project2.toml
|
||||
```
|
||||
|
||||
You can pass flags which will output only the value of the specific information you want. For example:
|
||||
|
||||
```shell
|
||||
dokku builder-pack:report node-js-app --builder-pack-projecttoml-path
|
||||
```
|
||||
|
||||
```
|
||||
project2.toml
|
||||
```
|
||||
|
||||
### Customizing the Buildpack stack builder
|
||||
|
||||
> New as of 0.23.0
|
||||
|
||||
@@ -27,6 +27,82 @@ If an application was previously deployed via buildpacks, the following commands
|
||||
dokku config:unset --no-restart node-js-app DOKKU_PROXY_PORT_MAP
|
||||
```
|
||||
|
||||
### Changing the `Dockerfile` location
|
||||
|
||||
> The previous method to perform this - via `docker-options:add` - should be removed in favor of the `builder-dockerfile:set` command outlined here.
|
||||
|
||||
When deploying a monorepo, it may be desirable to specify the specific path of the `Dockerfile` file to use for a given app. This can be done via the `builder-dockerfile:set` command. If a value is specified and that file does not exist in the app's build directory, then the build will fail.
|
||||
|
||||
```shell
|
||||
dokku builder-dockerfile:set node-js-app dockerfile-path Dockerfile2
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option:
|
||||
|
||||
```shell
|
||||
dokku builder-dockerfile:set node-js-app dockerfile-path
|
||||
```
|
||||
|
||||
The `dockerfile-path` property can also be set globally. The global default is `Dockerfile`, and the global value is used when no app-specific value is set.
|
||||
|
||||
```shell
|
||||
dokku builder-dockerfile:set --global dockerfile-path Dockerfile2
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option.
|
||||
|
||||
```shell
|
||||
dokku builder-dockerfile:set --global dockerfile-path
|
||||
```
|
||||
|
||||
### Displaying builder-dockerfile reports for an app
|
||||
|
||||
> New as of 0.25.0
|
||||
|
||||
You can get a report about the app's storage status using the `builder-dockerfile:report` command:
|
||||
|
||||
```shell
|
||||
dokku app-json:report
|
||||
```
|
||||
|
||||
```
|
||||
=====> node-js-app builder-dockerfile information
|
||||
Builder-dockerfile computed dockerfile path: Dockerfile2
|
||||
Builder-dockerfile global dockerfile path: Dockerfile
|
||||
Builder-dockerfile dockerfile path: Dockerfile2
|
||||
=====> python-sample builder-dockerfile information
|
||||
Builder-dockerfile computed dockerfile path: Dockerfile
|
||||
Builder-dockerfile global dockerfile path: Dockerfile
|
||||
Builder-dockerfile dockerfile path:
|
||||
=====> ruby-sample builder-dockerfile information
|
||||
Builder-dockerfile computed dockerfile path: Dockerfile
|
||||
Builder-dockerfile global dockerfile path: Dockerfile
|
||||
Builder-dockerfile dockerfile path:
|
||||
```
|
||||
|
||||
You can run the command for a specific app also.
|
||||
|
||||
```shell
|
||||
dokku builder-dockerfile:report node-js-app
|
||||
```
|
||||
|
||||
```
|
||||
=====> node-js-app builder-dockerfile information
|
||||
Builder-dockerfile computed dockerfile path: Dockerfile2
|
||||
Builder-dockerfile global dockerfile path: Dockerfile
|
||||
Builder-dockerfile dockerfile path: Dockerfile2
|
||||
```
|
||||
|
||||
You can pass flags which will output only the value of the specific information you want. For example:
|
||||
|
||||
```shell
|
||||
dokku builder-dockerfile:report node-js-app --builder-dockerfile-dockerfile-path
|
||||
```
|
||||
|
||||
```
|
||||
Dockerfile2
|
||||
```
|
||||
|
||||
### Build-time configuration variables
|
||||
|
||||
For security reasons - and as per [Docker recommendations](https://github.com/docker/docker/issues/13490) - Dockerfile-based deploys have variables available only during runtime.
|
||||
@@ -37,12 +113,6 @@ For users that require customization in the `build` phase, you may use build arg
|
||||
dokku docker-options:add node-js-app build '--build-arg NODE_ENV=production'
|
||||
```
|
||||
|
||||
The location of the `Dockerfile` may also be specified. If the location is changed, the repository **must also** have a `Dockerfile` in the root directory in order to trigger a dockerfile-based deploy.
|
||||
|
||||
```shell
|
||||
dokku docker-options:add node-js-app build '--file Dockerfile.dokku'
|
||||
```
|
||||
|
||||
Once set, the Dockerfile usage would be as follows:
|
||||
|
||||
```Dockerfile
|
||||
|
||||
@@ -342,6 +342,31 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
curl "http://httpstat.us/200"
|
||||
```
|
||||
|
||||
### `core-post-extract`
|
||||
|
||||
> To avoid issues with community plugins, this plugin trigger should be used _only_ for core plugins. Please avoid using this trigger in your own plugins.
|
||||
|
||||
- Description: Allows you to modify the contents of an app _after_ it has been extracted from git/tarball but _before_ the image source type is detected.
|
||||
- Invoked by: `dokku tar:in`, `dokku tar:from` and the `receive-app` plugin trigger
|
||||
- Arguments: `$APP` `$TMP_WORK_DIR` `$REV`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
# Adds a clock process to an app's Procfile
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
APP="$1"
|
||||
TMP_WORK_DIR="$2"
|
||||
REV="$3" # optional, may not be sent for tar-based builds
|
||||
|
||||
pushd "$TMP_WORK_DIR" >/dev/null
|
||||
touch Procfile
|
||||
echo "clock: some-command" >> Procfile
|
||||
popd &>/dev/null
|
||||
```
|
||||
|
||||
### `cron-write`
|
||||
|
||||
- Description: Force triggers writing out cron entries
|
||||
|
||||
@@ -156,6 +156,32 @@ There are also a few other exceptions for the `web` process.
|
||||
- See the [nginx request proxying documentation](/docs/configuration/nginx.md#request-proxying) for more information on how nginx handles proxied requests.
|
||||
- Only the `web` process may be bound to an external port.
|
||||
|
||||
#### Changing the `Procfile` location
|
||||
|
||||
When deploying a monorepo, it may be desirable to specify the specific path of the `Procfile` file to use for a given app. This can be done via the `ps:set` command. If a value is specified and that file does not exist within the repository, Dokku will continue the build process as if the repository has no `Procfile`.
|
||||
|
||||
```shell
|
||||
dokku ps:set node-js-app procfile-path Procfile2
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option:
|
||||
|
||||
```shell
|
||||
dokku ps:set node-js-app procfile-path
|
||||
```
|
||||
|
||||
The `procfile-path` property can also be set globally. The global default is `Procfile`, and the global value is used when no app-specific value is set.
|
||||
|
||||
```shell
|
||||
dokku ps:set --global procfile-path global-Procfile
|
||||
```
|
||||
|
||||
The default value may be set by passing an empty value for the option.
|
||||
|
||||
```shell
|
||||
dokku ps:set --global procfile-path
|
||||
```
|
||||
|
||||
### Stopping apps
|
||||
|
||||
Deployed apps can be stopped using the `ps:stop` command. This turns off all running containers for an app, and will result in a **502 Bad Gateway** response for the default nginx proxy implementation.
|
||||
@@ -254,21 +280,30 @@ dokku ps:report
|
||||
Deployed: false
|
||||
Processes: 0
|
||||
Ps can scale: true
|
||||
Ps computed procfile path: Procfile2
|
||||
Ps global procfile path: Procfile
|
||||
Ps restart policy: on-failure:10
|
||||
Ps procfile path: Procfile2
|
||||
Restore: true
|
||||
Running: false
|
||||
=====> python-sample ps information
|
||||
Deployed: false
|
||||
Processes: 0
|
||||
Ps can scale: true
|
||||
Ps computed procfile path: Procfile
|
||||
Ps global procfile path: Procfile
|
||||
Ps restart policy: on-failure:10
|
||||
Ps procfile path:
|
||||
Restore: true
|
||||
Running: false
|
||||
=====> ruby-sample ps information
|
||||
Deployed: false
|
||||
Processes: 0
|
||||
Ps can scale: true
|
||||
Ps computed procfile path: Procfile
|
||||
Ps global procfile path: Procfile
|
||||
Ps restart policy: on-failure:10
|
||||
Ps procfile path:
|
||||
Restore: true
|
||||
Running: false
|
||||
```
|
||||
|
||||
1
plugins/20_events/core-post-extract
Symbolic link
1
plugins/20_events/core-post-extract
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
11
plugins/app-json/.gitignore
vendored
11
plugins/app-json/.gitignore
vendored
@@ -1,5 +1,8 @@
|
||||
/triggers/*
|
||||
/triggers
|
||||
/pre-*
|
||||
/post-*
|
||||
/commands
|
||||
/install
|
||||
/post-*
|
||||
/pre-*
|
||||
/report
|
||||
/subcommands/*
|
||||
/triggers
|
||||
/triggers/*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
TRIGGERS = triggers/install triggers/post-delete triggers/post-deploy triggers/pre-deploy
|
||||
BUILD = triggers
|
||||
SUBCOMMANDS = subcommands/report subcommands/set
|
||||
TRIGGERS = triggers/install triggers/post-delete triggers/post-deploy triggers/pre-deploy triggers/report
|
||||
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
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3 h1:utdYOikI1XjNtTFGCwSM6OmFJblU4ld4gACoJsbadJg=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,9 @@ func main() {
|
||||
appName := flag.Arg(0)
|
||||
imageTag := flag.Arg(1)
|
||||
err = appjson.TriggerPreDeploy(appName, imageTag)
|
||||
case "report":
|
||||
appName := flag.Arg(0)
|
||||
err = appjson.ReportSingleApp(appName, "", "")
|
||||
default:
|
||||
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
|
||||
}
|
||||
|
||||
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("app-json", appName, property, value, DefaultProperties, GlobalProperties)
|
||||
return nil
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
|
||||
trigger-builder-dockerfile-builder-build() {
|
||||
declare desc="builder-dockerfile builder-build plugin trigger"
|
||||
@@ -19,6 +21,17 @@ trigger-builder-dockerfile-builder-build() {
|
||||
|
||||
pushd "$SOURCECODE_WORK_DIR" &>/dev/null
|
||||
|
||||
local NEW_DOCKERFILE="$(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
|
||||
if [[ -n "$NEW_DOCKERFILE" ]]; then
|
||||
if [[ ! -f "$NEW_DOCKERFILE" ]]; then
|
||||
dokku_log_fail "Invalid dockerfile-path specified: $NEW_DOCKERFILE"
|
||||
fi
|
||||
|
||||
if [[ "$NEW_DOCKERFILE" != "Dockerfile" ]]; then
|
||||
mv "$NEW_DOCKERFILE" Dockerfile
|
||||
fi
|
||||
fi
|
||||
|
||||
# extract first port from Dockerfile
|
||||
dos2unix Dockerfile
|
||||
local DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile)
|
||||
|
||||
15
plugins/builder-dockerfile/commands
Executable file
15
plugins/builder-dockerfile/commands
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/help-functions"
|
||||
|
||||
case "$1" in
|
||||
help | builder-dockerfile:help)
|
||||
cmd-builder-dockerfile-help "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
|
||||
;;
|
||||
|
||||
esac
|
||||
33
plugins/builder-dockerfile/help-functions
Executable file
33
plugins/builder-dockerfile/help-functions
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-dockerfile-help() {
|
||||
declare desc="help command"
|
||||
declare CMD="$1"
|
||||
local plugin_name="builder-dockerfile"
|
||||
local plugin_description="Manage the dockerfile builder integration for an app"
|
||||
|
||||
if [[ "$CMD" == "${plugin_name}:help" ]]; then
|
||||
echo -e "Usage: dokku ${plugin_name}[:COMMAND]"
|
||||
echo ''
|
||||
echo "$plugin_description"
|
||||
echo ''
|
||||
echo 'Additional commands:'
|
||||
fn-help-content | sort | column -c2 -t -s,
|
||||
elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then
|
||||
fn-help-content
|
||||
else
|
||||
cat <<help_desc
|
||||
$plugin_name, $plugin_description
|
||||
help_desc
|
||||
fi
|
||||
}
|
||||
|
||||
fn-help-content() {
|
||||
declare desc="return help content"
|
||||
cat <<help_content
|
||||
builder-dockerfile:report [<app>] [<flag>], Displays a builder-dockerfile report for one or more apps
|
||||
builder-dockerfile:set <app> <property> (<value>), Set or clear a builder-dockerfile property for an app
|
||||
help_content
|
||||
}
|
||||
91
plugins/builder-dockerfile/internal-functions
Executable file
91
plugins/builder-dockerfile/internal-functions
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-dockerfile-report() {
|
||||
declare desc="displays a builder-dockerfile report for one or more apps"
|
||||
declare cmd="builder-dockerfile:report"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" INFO_FLAG="$2"
|
||||
local INSTALLED_APPS=$(dokku_apps)
|
||||
|
||||
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
||||
INFO_FLAG="$APP"
|
||||
APP=""
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
||||
INFO_FLAG="true"
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]]; then
|
||||
for app in $INSTALLED_APPS; do
|
||||
cmd-builder-dockerfile-report-single "$app" "$INFO_FLAG" | tee || true
|
||||
done
|
||||
else
|
||||
cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-builder-dockerfile-report-single() {
|
||||
declare APP="$1" INFO_FLAG="$2"
|
||||
if [[ "$INFO_FLAG" == "true" ]]; then
|
||||
INFO_FLAG=""
|
||||
fi
|
||||
verify_app_name "$APP"
|
||||
local flag_map=(
|
||||
"--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
|
||||
"--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")"
|
||||
"--builder-dockerfile-dockerfile-path: $(fn-builder-dockerfile-dockerfile-path "$APP")"
|
||||
)
|
||||
|
||||
if [[ -z "$INFO_FLAG" ]]; then
|
||||
dokku_log_info2_quiet "${APP} builder-dockerfile information"
|
||||
for flag in "${flag_map[@]}"; do
|
||||
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
||||
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
||||
done
|
||||
else
|
||||
local match=false
|
||||
local value_exists=false
|
||||
for flag in "${flag_map[@]}"; do
|
||||
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
||||
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
||||
value=${flag#*: }
|
||||
size="${#value}"
|
||||
if [[ "$size" -ne 0 ]]; then
|
||||
echo "$value" && match=true && value_exists=true
|
||||
else
|
||||
match=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
||||
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
|
||||
fi
|
||||
}
|
||||
|
||||
fn-builder-dockerfile-computed-dockerfile-path() {
|
||||
declare APP="$1"
|
||||
|
||||
file="$(fn-builder-dockerfile-dockerfile-path "$APP")"
|
||||
if [[ "$file" == "" ]]; then
|
||||
file="$(fn-builder-dockerfile-global-dockerfile-path "$APP")"
|
||||
fi
|
||||
|
||||
echo "$file"
|
||||
}
|
||||
|
||||
fn-builder-dockerfile-global-dockerfile-path() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-dockerfile" "--global" "dockerfile-path" "Dockerfile"
|
||||
}
|
||||
|
||||
fn-builder-dockerfile-dockerfile-path() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-dockerfile" "$APP" "dockerfile-path" ""
|
||||
}
|
||||
6
plugins/builder-dockerfile/report
Executable file
6
plugins/builder-dockerfile/report
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-dockerfile-report-single "$@"
|
||||
6
plugins/builder-dockerfile/subcommands/default
Executable file
6
plugins/builder-dockerfile/subcommands/default
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/help-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-dockerfile-help "builder-dockerfile:help"
|
||||
6
plugins/builder-dockerfile/subcommands/report
Executable file
6
plugins/builder-dockerfile/subcommands/report
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-dockerfile-report "$@"
|
||||
30
plugins/builder-dockerfile/subcommands/set
Executable file
30
plugins/builder-dockerfile/subcommands/set
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-dockerfile-set() {
|
||||
declare desc="set or clear a builder-dockerfile property for an app"
|
||||
declare cmd="builder-dockerfile:set"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" KEY="$2" VALUE="$3"
|
||||
local VALID_KEYS=("dockerfile-path")
|
||||
[[ "$APP" == "--global" ]] || verify_app_name "$APP"
|
||||
|
||||
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
|
||||
|
||||
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
|
||||
dokku_log_fail "Invalid key specified, valid keys include: dockerfile-path"
|
||||
fi
|
||||
|
||||
if [[ -n "$VALUE" ]]; then
|
||||
dokku_log_info2_quiet "Setting ${KEY} to ${VALUE}"
|
||||
fn-plugin-property-write "builder-dockerfile" "$APP" "$KEY" "$VALUE"
|
||||
else
|
||||
dokku_log_info2_quiet "Unsetting ${KEY}"
|
||||
fn-plugin-property-delete "builder-dockerfile" "$APP" "$KEY"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-builder-dockerfile-set "$@"
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-pack-builder-build() {
|
||||
declare desc="builder-pack builder-build plugin trigger"
|
||||
|
||||
15
plugins/builder-pack/commands
Executable file
15
plugins/builder-pack/commands
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-pack/help-functions"
|
||||
|
||||
case "$1" in
|
||||
help | builder-pack:help)
|
||||
cmd-builder-pack-help "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
|
||||
;;
|
||||
|
||||
esac
|
||||
30
plugins/builder-pack/core-post-extract
Executable file
30
plugins/builder-pack/core-post-extract
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-pack-core-post-extract() {
|
||||
declare desc="builder-pack post-extract plugin trigger"
|
||||
declare trigger="post-extract"
|
||||
declare APP="$1" SOURCECODE_WORK_DIR="$2"
|
||||
local NEW_PROJECT_TOML="$(fn-builder-pack-computed-projecttoml-path "$APP")"
|
||||
|
||||
pushd "$TMP_WORK_DIR" >/dev/null
|
||||
|
||||
if [[ -z "$NEW_PROJECT_TOML" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ! -f "$NEW_PROJECT_TOML" ]]; then
|
||||
rm -f project.toml
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$NEW_PROJECT_TOML" != "project.toml" ]]; then
|
||||
mv "$NEW_PROJECT_TOML" project.toml
|
||||
fi
|
||||
popd &>/dev/null
|
||||
}
|
||||
|
||||
trigger-builder-pack-core-post-extract "$@"
|
||||
33
plugins/builder-pack/help-functions
Executable file
33
plugins/builder-pack/help-functions
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-pack-help() {
|
||||
declare desc="help command"
|
||||
declare CMD="$1"
|
||||
local plugin_name="builder-pack"
|
||||
local plugin_description="Manage the pack builder integration for an app"
|
||||
|
||||
if [[ "$CMD" == "${plugin_name}:help" ]]; then
|
||||
echo -e "Usage: dokku ${plugin_name}[:COMMAND]"
|
||||
echo ''
|
||||
echo "$plugin_description"
|
||||
echo ''
|
||||
echo 'Additional commands:'
|
||||
fn-help-content | sort | column -c2 -t -s,
|
||||
elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then
|
||||
fn-help-content
|
||||
else
|
||||
cat <<help_desc
|
||||
$plugin_name, $plugin_description
|
||||
help_desc
|
||||
fi
|
||||
}
|
||||
|
||||
fn-help-content() {
|
||||
declare desc="return help content"
|
||||
cat <<help_content
|
||||
builder-pack:report [<app>] [<flag>], Displays a builder-pack report for one or more apps
|
||||
builder-pack:set <app> <property> (<value>), Set or clear a builder-pack property for an app
|
||||
help_content
|
||||
}
|
||||
91
plugins/builder-pack/internal-functions
Executable file
91
plugins/builder-pack/internal-functions
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-pack-report() {
|
||||
declare desc="displays a builder-pack report for one or more apps"
|
||||
declare cmd="builder-pack:report"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" INFO_FLAG="$2"
|
||||
local INSTALLED_APPS=$(dokku_apps)
|
||||
|
||||
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
||||
INFO_FLAG="$APP"
|
||||
APP=""
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
||||
INFO_FLAG="true"
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]]; then
|
||||
for app in $INSTALLED_APPS; do
|
||||
cmd-builder-pack-report-single "$app" "$INFO_FLAG" | tee || true
|
||||
done
|
||||
else
|
||||
cmd-builder-pack-report-single "$APP" "$INFO_FLAG"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-builder-pack-report-single() {
|
||||
declare APP="$1" INFO_FLAG="$2"
|
||||
if [[ "$INFO_FLAG" == "true" ]]; then
|
||||
INFO_FLAG=""
|
||||
fi
|
||||
verify_app_name "$APP"
|
||||
local flag_map=(
|
||||
"--builder-pack-computed-projecttoml-path: $(fn-builder-pack-computed-projecttoml-path "$APP")"
|
||||
"--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")"
|
||||
"--builder-pack-projecttoml-path: $(fn-builder-pack-projecttoml-path "$APP")"
|
||||
)
|
||||
|
||||
if [[ -z "$INFO_FLAG" ]]; then
|
||||
dokku_log_info2_quiet "${APP} builder-pack information"
|
||||
for flag in "${flag_map[@]}"; do
|
||||
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
||||
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
||||
done
|
||||
else
|
||||
local match=false
|
||||
local value_exists=false
|
||||
for flag in "${flag_map[@]}"; do
|
||||
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
||||
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
||||
value=${flag#*: }
|
||||
size="${#value}"
|
||||
if [[ "$size" -ne 0 ]]; then
|
||||
echo "$value" && match=true && value_exists=true
|
||||
else
|
||||
match=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
||||
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
|
||||
fi
|
||||
}
|
||||
|
||||
fn-builder-pack-computed-projecttoml-path() {
|
||||
declare APP="$1"
|
||||
|
||||
file="$(fn-builder-pack-projecttoml-path "$APP")"
|
||||
if [[ "$file" == "" ]]; then
|
||||
file="$(fn-builder-pack-global-projecttoml-path "$APP")"
|
||||
fi
|
||||
|
||||
echo "$file"
|
||||
}
|
||||
|
||||
fn-builder-pack-global-projecttoml-path() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-pack" "--global" "projecttoml-path" "project.toml"
|
||||
}
|
||||
|
||||
fn-builder-pack-projecttoml-path() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-pack" "$APP" "projecttoml-path" ""
|
||||
}
|
||||
6
plugins/builder-pack/report
Executable file
6
plugins/builder-pack/report
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-pack-report-single "$@"
|
||||
6
plugins/builder-pack/subcommands/default
Executable file
6
plugins/builder-pack/subcommands/default
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-pack/help-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-pack-help "builder-pack:help"
|
||||
6
plugins/builder-pack/subcommands/report
Executable file
6
plugins/builder-pack/subcommands/report
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-pack-report "$@"
|
||||
30
plugins/builder-pack/subcommands/set
Executable file
30
plugins/builder-pack/subcommands/set
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-pack-set() {
|
||||
declare desc="set or clear a builder-pack property for an app"
|
||||
declare cmd="builder-pack:set"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" KEY="$2" VALUE="$3"
|
||||
local VALID_KEYS=("projecttoml-path")
|
||||
[[ "$APP" == "--global" ]] || verify_app_name "$APP"
|
||||
|
||||
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
|
||||
|
||||
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
|
||||
dokku_log_fail "Invalid key specified, valid keys include: projecttoml-path"
|
||||
fi
|
||||
|
||||
if [[ -n "$VALUE" ]]; then
|
||||
dokku_log_info2_quiet "Setting ${KEY} to ${VALUE}"
|
||||
fn-plugin-property-write "builder-pack" "$APP" "$KEY" "$VALUE"
|
||||
else
|
||||
dokku_log_info2_quiet "Unsetting ${KEY}"
|
||||
fn-plugin-property-delete "builder-pack" "$APP" "$KEY"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-builder-pack-set "$@"
|
||||
2
plugins/builder/.gitignore
vendored
2
plugins/builder/.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
/commands
|
||||
/core-post-deploy
|
||||
/core-post-extract
|
||||
/subcommands/*
|
||||
/triggers/*
|
||||
/triggers
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SUBCOMMANDS = subcommands/report subcommands/set
|
||||
TRIGGERS = triggers/builder-detect triggers/install triggers/post-delete triggers/report
|
||||
TRIGGERS = triggers/builder-detect triggers/core-post-extract triggers/install triggers/post-delete triggers/report
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = builder
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ package builder
|
||||
var (
|
||||
// DefaultProperties is a map of all valid network properties with corresponding default property values
|
||||
DefaultProperties = map[string]string{
|
||||
"selected": "",
|
||||
"selected": "",
|
||||
"build-dir": "",
|
||||
}
|
||||
|
||||
// GlobalProperties is a map of all valid global network properties
|
||||
GlobalProperties = map[string]bool{
|
||||
"selected": true,
|
||||
"selected": true,
|
||||
"build-dir": true,
|
||||
}
|
||||
)
|
||||
|
||||
20
plugins/builder/functions.go
Normal file
20
plugins/builder/functions.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func removeAllContents(basePath string) error {
|
||||
dir, err := ioutil.ReadDir(basePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, d := range dir {
|
||||
os.RemoveAll(path.Join([]string{basePath, d.Name()}...))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,10 +3,11 @@ module github.com/dokku/dokku/plugins/builder
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/otiai10/copy v1.6.0
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -2,6 +2,12 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+Bu
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA=
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE=
|
||||
github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
|
||||
github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3 h1:utdYOikI1XjNtTFGCwSM6OmFJblU4ld4gACoJsbadJg=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
|
||||
@@ -11,9 +11,12 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
|
||||
}
|
||||
|
||||
flags := map[string]common.ReportFunc{
|
||||
"--builder-computed-selected": reportComputedSelected,
|
||||
"--builder-global-selected": reportGlobalSelected,
|
||||
"--builder-selected": reportSelected,
|
||||
"--builder-computed-selected": reportComputedSelected,
|
||||
"--builder-global-selected": reportGlobalSelected,
|
||||
"--builder-selected": reportSelected,
|
||||
"--builder-computed-build-dir": reportComputedBuildDir,
|
||||
"--builder-global-build-dir": reportGlobalBuildDir,
|
||||
"--builder-build-dir": reportBuildDir,
|
||||
}
|
||||
|
||||
flagKeys := []string{}
|
||||
@@ -42,3 +45,19 @@ func reportGlobalSelected(appName string) string {
|
||||
func reportSelected(appName string) string {
|
||||
return common.PropertyGet("builder", appName, "selected")
|
||||
}
|
||||
|
||||
func reportComputedBuildDir(appName string) string {
|
||||
value := reportBuildDir(appName)
|
||||
if value == "" {
|
||||
value = reportGlobalBuildDir(appName)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
func reportGlobalBuildDir(appName string) string {
|
||||
return common.PropertyGet("builder", "--global", "build-dir")
|
||||
}
|
||||
|
||||
func reportBuildDir(appName string) string {
|
||||
return common.PropertyGet("builder", appName, "build-dir")
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@ func main() {
|
||||
case "report":
|
||||
appName := flag.Arg(0)
|
||||
err = builder.ReportSingleApp(appName, "", "")
|
||||
case "core-post-extract":
|
||||
appName := flag.Arg(0)
|
||||
sourceWorkDir := flag.Arg(1)
|
||||
err = builder.TriggerCorePostExtract(appName, sourceWorkDir)
|
||||
default:
|
||||
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
|
||||
}
|
||||
|
||||
@@ -2,8 +2,13 @@ package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
"github.com/otiai10/copy"
|
||||
)
|
||||
|
||||
// TriggerBuilderDetect outputs a manually selected builder for the app
|
||||
@@ -21,6 +26,42 @@ func TriggerBuilderDetect(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TriggerCorePostExtract moves a configured build-dir to be in the app root dir
|
||||
func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
|
||||
buildDir := strings.Trim(reportComputedBuildDir(appName), "/")
|
||||
if buildDir == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
newSourceWorkDir := filepath.Join(sourceWorkDir, buildDir)
|
||||
if !common.DirectoryExists(newSourceWorkDir) {
|
||||
return fmt.Errorf("Specified build-dir not found in sourcecode working directory: %v", buildDir)
|
||||
}
|
||||
|
||||
tmpWorkDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("dokku-%s-%s", common.MustGetEnv("DOKKU_PID"), "CorePostExtract"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to create temporary working directory: %v", err.Error())
|
||||
}
|
||||
|
||||
if err := removeAllContents(tmpWorkDir); err != nil {
|
||||
return fmt.Errorf("Unable to clear out temporary working directory for rewrite: %v", err.Error())
|
||||
}
|
||||
|
||||
if err := copy.Copy(newSourceWorkDir, tmpWorkDir); err != nil {
|
||||
return fmt.Errorf("Unable to move build-dir to temporary working directory: %v", err.Error())
|
||||
}
|
||||
|
||||
if err := removeAllContents(sourceWorkDir); err != nil {
|
||||
return fmt.Errorf("Unable to clear out sourcecode working directory for rewrite: %v", err.Error())
|
||||
}
|
||||
|
||||
if err := copy.Copy(tmpWorkDir, sourceWorkDir); err != nil {
|
||||
return fmt.Errorf("Unable to move build-dir to sourcecode working directory: %v", err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TriggerInstall runs the install step for the builder plugin
|
||||
func TriggerInstall() error {
|
||||
if err := common.PropertySetup("builder"); err != nil {
|
||||
|
||||
@@ -51,6 +51,7 @@ git_trigger_build() {
|
||||
declare APP="$1" TMP_WORK_DIR="$2" REV="$3"
|
||||
local BUILDER
|
||||
|
||||
plugn trigger core-post-extract "$APP" "$TMP_WORK_DIR" "$REV"
|
||||
plugn trigger post-extract "$APP" "$TMP_WORK_DIR" "$REV"
|
||||
|
||||
BUILDER="$(plugn trigger builder-detect "$APP" "$TMP_WORK_DIR" | head -n1 || true)"
|
||||
|
||||
15
plugins/ps/.gitignore
vendored
15
plugins/ps/.gitignore
vendored
@@ -1,12 +1,13 @@
|
||||
/app-restart
|
||||
/commands
|
||||
/subcommands/*
|
||||
/triggers/*
|
||||
/triggers
|
||||
/proxy-*
|
||||
/core-post-deploy
|
||||
/core-post-extract
|
||||
/install
|
||||
/post-*
|
||||
/report
|
||||
/pre-*
|
||||
/procfile-*
|
||||
/app-restart
|
||||
/core-post-deploy
|
||||
/proxy-*
|
||||
/report
|
||||
/subcommands/*
|
||||
/triggers
|
||||
/triggers/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SUBCOMMANDS = subcommands/inspect subcommands/rebuild subcommands/report subcommands/restart subcommands/restore subcommands/retire subcommands/scale subcommands/set subcommands/start subcommands/stop
|
||||
TRIGGERS = triggers/app-restart triggers/core-post-deploy triggers/install triggers/post-app-clone triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/post-extract triggers/post-stop triggers/pre-deploy triggers/procfile-extract triggers/procfile-get-command triggers/procfile-remove triggers/report
|
||||
TRIGGERS = triggers/app-restart triggers/core-post-deploy triggers/core-post-extract triggers/install triggers/post-app-clone triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/post-extract triggers/post-stop triggers/pre-deploy triggers/procfile-extract triggers/procfile-get-command triggers/procfile-remove triggers/report
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = ps
|
||||
|
||||
|
||||
@@ -8,8 +8,9 @@ require (
|
||||
github.com/dokku/dokku/plugins/config v0.0.0-00010101000000-000000000000
|
||||
github.com/dokku/dokku/plugins/docker-options v0.0.0-00010101000000-000000000000
|
||||
github.com/gofrs/flock v0.8.0
|
||||
github.com/otiai10/copy v1.6.0
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -8,6 +8,12 @@ github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
|
||||
github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc=
|
||||
github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
|
||||
github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3 h1:utdYOikI1XjNtTFGCwSM6OmFJblU4ld4gACoJsbadJg=
|
||||
github.com/ryanuber/columnize v1.1.2-0.20190319233515-9e6335e58db3/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
|
||||
@@ -15,10 +15,13 @@ var (
|
||||
// DefaultProperties is a map of all valid ps properties with corresponding default property values
|
||||
DefaultProperties = map[string]string{
|
||||
"restart-policy": "on-failure:10",
|
||||
"procfile-path": "",
|
||||
}
|
||||
|
||||
// GlobalProperties is a map of all valid global ps properties
|
||||
GlobalProperties = map[string]bool{}
|
||||
GlobalProperties = map[string]bool{
|
||||
"procfile-path": true,
|
||||
}
|
||||
)
|
||||
|
||||
// Rebuild rebuilds app from base image
|
||||
|
||||
@@ -15,12 +15,15 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
|
||||
}
|
||||
|
||||
flags := map[string]common.ReportFunc{
|
||||
"--deployed": reportDeployed,
|
||||
"--processes": reportProcesses,
|
||||
"--ps-can-scale": reportCanScale,
|
||||
"--ps-restart-policy": reportRestartPolicy,
|
||||
"--restore": reportRestore,
|
||||
"--running": reportRunningState,
|
||||
"--deployed": reportDeployed,
|
||||
"--processes": reportProcesses,
|
||||
"--ps-can-scale": reportCanScale,
|
||||
"--ps-restart-policy": reportRestartPolicy,
|
||||
"--ps-computed-procfile-path": reportComputedProcfilePath,
|
||||
"--ps-global-procfile-path": reportGlobalProcfilePath,
|
||||
"--ps-procfile-path": reportProcfilePath,
|
||||
"--restore": reportRestore,
|
||||
"--running": reportRunningState,
|
||||
}
|
||||
|
||||
extraFlags := addStatusFlags(appName, infoFlag)
|
||||
@@ -81,6 +84,23 @@ func reportCanScale(appName string) string {
|
||||
return canScale
|
||||
}
|
||||
|
||||
func reportComputedProcfilePath(appName string) string {
|
||||
value := reportProcfilePath(appName)
|
||||
if value == "" {
|
||||
value = reportGlobalProcfilePath(appName)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalProcfilePath(appName string) string {
|
||||
return common.PropertyGetDefault("ps", "--global", "procfile-path", "Procfile")
|
||||
}
|
||||
|
||||
func reportProcfilePath(appName string) string {
|
||||
return common.PropertyGetDefault("ps", appName, "procfile-path", "")
|
||||
}
|
||||
|
||||
func reportDeployed(appName string) string {
|
||||
deployed := "false"
|
||||
if common.IsDeployed(appName) {
|
||||
|
||||
@@ -24,6 +24,10 @@ func main() {
|
||||
case "core-post-deploy":
|
||||
appName := flag.Arg(0)
|
||||
err = ps.TriggerCorePostDeploy(appName)
|
||||
case "core-post-extract":
|
||||
appName := flag.Arg(0)
|
||||
sourceWorkDir := flag.Arg(1)
|
||||
err = ps.TriggerCorePostExtract(appName, sourceWorkDir)
|
||||
case "install":
|
||||
err = ps.TriggerInstall()
|
||||
case "post-app-clone":
|
||||
|
||||
@@ -3,6 +3,7 @@ package ps
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
"github.com/dokku/dokku/plugins/config"
|
||||
dockeroptions "github.com/dokku/dokku/plugins/docker-options"
|
||||
"github.com/otiai10/copy"
|
||||
)
|
||||
|
||||
// TriggerAppRestart restarts an app
|
||||
@@ -29,6 +31,29 @@ func TriggerCorePostDeploy(appName string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// TriggerCorePostExtract ensures that the main Procfile is the one specified by procfile-path
|
||||
func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
|
||||
procfilePath := strings.Trim(reportComputedProcfilePath(appName), "/")
|
||||
if procfilePath == "" || procfilePath == "Procfile" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := os.Remove(path.Join(sourceWorkDir, "Procfile")); err != nil {
|
||||
return fmt.Errorf("Unable to remove existing Procfile: %v", err.Error())
|
||||
}
|
||||
|
||||
fullProcfilePath := path.Join(sourceWorkDir, procfilePath)
|
||||
if !common.FileExists(fullProcfilePath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := copy.Copy(fullProcfilePath, path.Join(sourceWorkDir, "Procfile")); err != nil {
|
||||
return fmt.Errorf("Unable to move specified Procfile into place: %v", err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TriggerInstall initializes app restart policies
|
||||
func TriggerInstall() error {
|
||||
if err := common.PropertySetup("ps"); err != nil {
|
||||
|
||||
@@ -43,6 +43,7 @@ tar_trigger_build() {
|
||||
declare APP="$1" TMP_WORK_DIR="$2" REV="$3"
|
||||
local BUILDER
|
||||
|
||||
plugn trigger core-post-extract "$APP" "$TMP_WORK_DIR" "$REV"
|
||||
plugn trigger post-extract "$APP" "$TMP_WORK_DIR" "$REV"
|
||||
|
||||
BUILDER="$(plugn trigger builder-detect "$APP" "$TMP_WORK_DIR" | head -n1 || true)"
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
cron: node worker.js
|
||||
web: node web.js
|
||||
worker: node worker.js
|
||||
release: node release.js
|
||||
|
||||
3
tests/apps/dockerfile-procfile/release.js
Normal file
3
tests/apps/dockerfile-procfile/release.js
Normal file
@@ -0,0 +1,3 @@
|
||||
var secret = process.env.SECRET_KEY || "";
|
||||
|
||||
console.log('SECRET_KEY: ' + secret);
|
||||
8
tests/apps/dockerfile-procfile/second.Procfile
Normal file
8
tests/apps/dockerfile-procfile/second.Procfile
Normal file
@@ -0,0 +1,8 @@
|
||||
###############################
|
||||
# DEVELOPMENT #
|
||||
###############################
|
||||
|
||||
# Procfile for development using the new threaded worker (scheduler, twitter stream and delayed job)
|
||||
cron: node worker.js
|
||||
web: node web.js
|
||||
worker: node worker.js
|
||||
15
tests/apps/dockerfile/second.Dockerfile
Normal file
15
tests/apps/dockerfile/second.Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM node:4-alpine
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
EXPOSE 3001/udp
|
||||
EXPOSE 3000/tcp
|
||||
EXPOSE 3003
|
||||
|
||||
COPY . /var/www/html
|
||||
WORKDIR /var/www/html
|
||||
RUN npm install
|
||||
|
||||
RUN echo hi
|
||||
|
||||
CMD npm start
|
||||
8
tests/apps/python/app2.json
Normal file
8
tests/apps/python/app2.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"scripts": {
|
||||
"dokku": {
|
||||
"predeploy": "touch /app/predeploy2.test",
|
||||
"postdeploy": "touch /app/postdeploy.test"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
tests/apps/python/cnb/1/bin/build
Executable file
17
tests/apps/python/cnb/1/bin/build
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
layers_dir=$1
|
||||
|
||||
echo "Building with buildpack 1"
|
||||
bp_layer=$layers_dir/1
|
||||
bp_env_dir=$bp_layer/env
|
||||
mkdir -p $bp_env_dir
|
||||
|
||||
echo "TESTENV_1" >$bp_env_dir/TESTENV
|
||||
|
||||
{
|
||||
echo "[types]"
|
||||
echo "launch = true"
|
||||
echo "build = true"
|
||||
echo "cache = true"
|
||||
} >"${bp_layer}.toml"
|
||||
3
tests/apps/python/cnb/1/bin/detect
Executable file
3
tests/apps/python/cnb/1/bin/detect
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "1" && exit 0
|
||||
9
tests/apps/python/cnb/1/buildpack.toml
Normal file
9
tests/apps/python/cnb/1/buildpack.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
api = "0.6"
|
||||
|
||||
[buildpack]
|
||||
id = "1"
|
||||
version = "0.1.0"
|
||||
name = "1 Packages Buildpack"
|
||||
|
||||
[[stacks]]
|
||||
id = "heroku-20"
|
||||
23
tests/apps/python/cnb/2/bin/build
Executable file
23
tests/apps/python/cnb/2/bin/build
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
layers_dir=$1
|
||||
|
||||
echo "Building with buildpack 2"
|
||||
bp_layer=$layers_dir/2
|
||||
bp_env_dir=$bp_layer/env
|
||||
mkdir -p $bp_env_dir
|
||||
|
||||
export TESTENV="$TESTENV:anotherenv"
|
||||
|
||||
echo "===> env start"
|
||||
env
|
||||
echo "===> env end"
|
||||
|
||||
echo "TESTENV_2" >$bp_env_dir/TESTENV
|
||||
|
||||
{
|
||||
echo "[types]"
|
||||
echo "launch = true"
|
||||
echo "build = true"
|
||||
echo "cache = true"
|
||||
} >"${bp_layer}.toml"
|
||||
3
tests/apps/python/cnb/2/bin/detect
Executable file
3
tests/apps/python/cnb/2/bin/detect
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "2" && exit 0
|
||||
9
tests/apps/python/cnb/2/buildpack.toml
Normal file
9
tests/apps/python/cnb/2/buildpack.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
api = "0.6"
|
||||
|
||||
[buildpack]
|
||||
id = "2"
|
||||
version = "0.1.0"
|
||||
name = "2 Packages Buildpack"
|
||||
|
||||
[[stacks]]
|
||||
id = "heroku-20"
|
||||
10
tests/apps/python/project2.toml
Normal file
10
tests/apps/python/project2.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[project]
|
||||
id = "python"
|
||||
name = "python"
|
||||
version = "1.0.0"
|
||||
|
||||
[[build.buildpacks]]
|
||||
uri = "./cnb/1"
|
||||
|
||||
[[build.buildpacks]]
|
||||
uri = "./cnb/1"
|
||||
1
tests/apps/python/second.Procfile
Normal file
1
tests/apps/python/second.Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: python3 web.py
|
||||
2
tests/apps/python/sub-app/Procfile
Normal file
2
tests/apps/python/sub-app/Procfile
Normal file
@@ -0,0 +1,2 @@
|
||||
web: python3 web.py
|
||||
release: python3 release.py
|
||||
0
tests/apps/python/sub-app/null
Normal file
0
tests/apps/python/sub-app/null
Normal file
10
tests/apps/python/sub-app/release.py
Normal file
10
tests/apps/python/sub-app/release.py
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
|
||||
|
||||
def main():
|
||||
print("SECRET_KEYS: {0}".format(os.getenv('SECRET_KEY')))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
23
tests/apps/python/sub-app/web.py
Normal file
23
tests/apps/python/sub-app/web.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import http.server
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
class GetHandler(http.server.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "text/plain; charset=utf-8")
|
||||
self.end_headers()
|
||||
|
||||
if self.path == '/':
|
||||
self.wfile.write("python/http.server".encode("utf-8"))
|
||||
else:
|
||||
data = json.dumps(dict(os.environ), sort_keys=True, indent=4)
|
||||
self.wfile.write(data.encode("utf-8"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = int(os.getenv("PORT", 5000))
|
||||
server = http.server.HTTPServer(("0.0.0.0", port), GetHandler)
|
||||
print("Listening on port {0}".format(port))
|
||||
server.serve_forever()
|
||||
@@ -151,3 +151,44 @@ teardown() {
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "(app-json:set)" {
|
||||
run deploy_app python
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app-nonexistent.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "touch /app/predeploy.test" 0
|
||||
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path app2.json"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "touch /app/predeploy2.test"
|
||||
|
||||
run /bin/bash -c "dokku app-json:set $TEST_APP appjson-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains "touch /app/predeploy.test"
|
||||
assert_output_contains "touch /app/predeploy2.test" 0
|
||||
}
|
||||
|
||||
50
tests/unit/builder-dockerfile.bats
Normal file
50
tests/unit/builder-dockerfile.bats
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(builder-dockerfile:set)" {
|
||||
run deploy_app dockerfile
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path nonexistent-dockerfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path second.Dockerfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'echo hi'
|
||||
|
||||
run /bin/bash -c "dokku builder-dockerfile:set $TEST_APP dockerfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'echo hi' 0
|
||||
}
|
||||
81
tests/unit/builder-pack.bats
Normal file
81
tests/unit/builder-pack.bats
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup_file() {
|
||||
if ! command -v "pack" &>/dev/null; then
|
||||
add-apt-repository --yes ppa:cncf-buildpacks/pack-cli
|
||||
apt-get update
|
||||
apt-get --yes install pack-cli
|
||||
fi
|
||||
}
|
||||
|
||||
setup() {
|
||||
create_app
|
||||
}
|
||||
|
||||
teardown() {
|
||||
destroy_app
|
||||
}
|
||||
|
||||
@test "(builder-pack:set)" {
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP selected pack"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku buildpacks:set-property $TEST_APP stack heroku/buildpacks:20"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run deploy_app python dokku@dokku.me:$TEST_APP inject_requirements_txt
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'Building with buildpack 1' 0
|
||||
assert_output_contains 'Installing requirements with pip'
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path nonexistent.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'Building with buildpack 1' 0
|
||||
assert_output_contains 'Installing requirements with pip'
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path project2.toml"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'Building with buildpack 1'
|
||||
assert_output_contains 'Installing requirements with pip' 0
|
||||
|
||||
run /bin/bash -c "dokku builder-pack:set $TEST_APP projecttoml-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'Building with buildpack 1' 0
|
||||
assert_output_contains 'Installing requirements with pip'
|
||||
}
|
||||
|
||||
inject_requirements_txt() {
|
||||
local APP="$1"
|
||||
local APP_REPO_DIR="$2"
|
||||
[[ -z "$APP" ]] && local APP="$TEST_APP"
|
||||
echo "flask" >>"$APP_REPO_DIR/requirements.txt"
|
||||
}
|
||||
@@ -187,3 +187,42 @@ teardown() {
|
||||
assert_success
|
||||
assert_line 0 "herokuish"
|
||||
}
|
||||
|
||||
@test "(builder:set)" {
|
||||
run deploy_app python
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP build-dir nonexistent-app"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP build-dir sub-app"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'SECRET_KEYS:'
|
||||
|
||||
run /bin/bash -c "dokku builder:set $TEST_APP build-dir"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'SECRET_KEY:'
|
||||
}
|
||||
|
||||
@@ -198,3 +198,44 @@ EOF
|
||||
assert_success
|
||||
assert_output_contains "bar"
|
||||
}
|
||||
|
||||
|
||||
@test "(ps:set) procfile-path" {
|
||||
run deploy_app dockerfile-procfile
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP procfile-path nonexistent-procfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_failure
|
||||
assert_output_contains "Could not start due to"
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP procfile-path second.Procfile"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'SECRET_KEY:' 0
|
||||
|
||||
run /bin/bash -c "dokku ps:set $TEST_APP procfile-path"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku ps:rebuild $TEST_APP"
|
||||
echo "output: $output"
|
||||
echo "status: $status"
|
||||
assert_success
|
||||
assert_output_contains 'SECRET_KEY:'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user