Merge pull request #6701 from dokku/0.34-release

Release 0.34.0
This commit is contained in:
Jose Diaz-Gonzalez
2024-03-18 15:48:08 -04:00
committed by GitHub
141 changed files with 1779 additions and 1139 deletions

View File

@@ -58,7 +58,7 @@ jobs:
PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get changed files in the docs folder - name: Get changed files in the docs folder
id: changed-files-specific id: changed-files-specific
uses: tj-actions/changed-files@v42.1.0 uses: tj-actions/changed-files@v43.0.0
with: with:
files: contrib/images/digitalocean/** files: contrib/images/digitalocean/**
- name: Run `packer validate` - name: Run `packer validate`

View File

@@ -75,9 +75,12 @@ go-clean:
fi ;\ fi ;\
done done
copyfiles: copydokku:
$(MAKE) go-build || exit 1
cp dokku /usr/local/bin/dokku cp dokku /usr/local/bin/dokku
chmod 0755 /usr/local/bin/dokku
copyfiles: copydokku
$(MAKE) go-build || exit 1
mkdir -p ${CORE_PLUGINS_PATH} ${PLUGINS_PATH} mkdir -p ${CORE_PLUGINS_PATH} ${PLUGINS_PATH}
rm -rf ${CORE_PLUGINS_PATH}/* rm -rf ${CORE_PLUGINS_PATH}/*
test -d ${CORE_PLUGINS_PATH}/enabled || PLUGIN_PATH=${CORE_PLUGINS_PATH} plugn init test -d ${CORE_PLUGINS_PATH}/enabled || PLUGIN_PATH=${CORE_PLUGINS_PATH} plugn init

View File

@@ -188,9 +188,14 @@ main() {
[[ " storage:ensure-directory " == *" $CMD "* ]] && unset APP [[ " storage:ensure-directory " == *" $CMD "* ]] && unset APP
[[ "$CMD" =~ events*|plugin*|ssh-keys* ]] && unset APP [[ "$CMD" =~ events*|plugin*|ssh-keys* ]] && unset APP
[[ -n "$APP_ARG" ]] && [[ "$APP_ARG" == "--global" ]] && unset APP [[ -n "$APP_ARG" ]] && [[ "$APP_ARG" == "--global" ]] && unset APP
[[ -n "$@" ]] && [[ -n "$APP" ]] && app_arg="--app $APP" if [[ -n "$@" ]] && [[ -n "$APP" ]]; then
set -- "$APP" "$@"
set -- "--app" "$@"
fi
# echo "ssh -o LogLevel=QUIET -p $DOKKU_PORT -t dokku@$DOKKU_REMOTE_HOST -- $app_arg $@" # echo "ssh -o LogLevel=QUIET -p $DOKKU_PORT -t dokku@$DOKKU_REMOTE_HOST -- $app_arg $@"
ssh -o LogLevel=QUIET -p $DOKKU_PORT -t dokku@$DOKKU_REMOTE_HOST -- $app_arg $@ || { local ssh_args=("-o" "LogLevel=QUIET" "-p" "$DOKKU_PORT" "-t" "dokku@$DOKKU_REMOTE_HOST" "--")
ssh_args+=("$@")
ssh "${ssh_args[@]}" || {
ssh_exit_code="$?" ssh_exit_code="$?"
echo " ! Failed to execute dokku command over ssh: exit code $?" 1>&2 echo " ! Failed to execute dokku command over ssh: exit code $?" 1>&2
echo " ! If there was no output from Dokku, ensure your configured SSH Key can connect to the remote server" 1>&2 echo " ! If there was no output from Dokku, ensure your configured SSH Key can connect to the remote server" 1>&2

View File

@@ -3,7 +3,7 @@ click==8.1.7
ghp-import==2.1.0 ghp-import==2.1.0
importlib-metadata==7.0.2 importlib-metadata==7.0.2
Jinja2==3.1.3 Jinja2==3.1.3
Markdown>=3.2.1,<3.6 Markdown>=3.2.1,<3.7
MarkupSafe==2.1.5 MarkupSafe==2.1.5
mergedeep==1.3.4 mergedeep==1.3.4
mkdocs==1.5.3 mkdocs==1.5.3
@@ -20,4 +20,4 @@ pyyaml_env_tag==0.1
six==1.16.0 six==1.16.0
soupsieve==2.5 soupsieve==2.5
watchdog==4.0.0 watchdog==4.0.0
zipp==3.17.0 zipp==3.18.1

View File

@@ -0,0 +1,14 @@
# 0.34.0 Migration Guide
## Removals
- The `disable-chown` property of the `scheduler-docker-local` plugin has been removed. Mounted paths will no longer have file permissions changed during the pre-deploy phase. Files baked into the container image for herokuish builds will always be owned by the correct user.
- The `git:unlock` command has been removed. It was previously used to "unlock" a temporary directory that already existed. The directory the `git:unlock` command used to cleanup is now properly removed on exit of the `git:from-image` command.
## Changes
- The k3s scheduler now defaults to nginx as it's default proxy implementation. The traefik proxy implementation is still available, though users will need to set the global `ingress-class` k3s property to `traefik` via the following command:
```shell
dokku scheduler-k3s:set --global ingress-class traefik
```

View File

@@ -10,13 +10,12 @@ git:from-archive [--archive-type ARCHIVE_TYPE] <app> <archive-url> [<git-usernam
git:from-image [--build-dir DIRECTORY] <app> <docker-image> [<git-username> <git-email>] # Updates an app's git repository with a given docker image git:from-image [--build-dir DIRECTORY] <app> <docker-image> [<git-username> <git-email>] # Updates an app's git repository with a given docker image
git:generate-deploy-key # Generates a deploy ssh key git:generate-deploy-key # Generates a deploy ssh key
git:load-image [--build-dir DIRECTORY] <app> <docker-image> [<git-username> <git-email>] # Updates an app's git repository with a docker image loaded from stdin git:load-image [--build-dir DIRECTORY] <app> <docker-image> [<git-username> <git-email>] # Updates an app's git repository with a docker image loaded from stdin
git:sync [--build] <app> <repository> [<git-ref>] # Clone or fetch an app from remote git repo git:sync [--build|build-if-changes] <app> <repository> [<git-ref>] # Clone or fetch an app from remote git repo
git:initialize <app> # Initialize a git repository for an app git:initialize <app> # Initialize a git repository for an app
git:public-key # Outputs the dokku public deploy key git:public-key # Outputs the dokku public deploy key
git:report [<app>] [<flag>] # Displays a git report for one or more apps git:report [<app>] [<flag>] # Displays a git report for one or more apps
git:set <app> <key> (<value>) # Set or clear a git property for an app git:set <app> <key> (<value>) # Set or clear a git property for an app
git:status <app> # Show the working tree status for an app git:status <app> # Show the working tree status for an app
git:unlock <app> [--force] # Removes previous git clone folder for new deployment
``` ```
Git-based deployment has been the traditional method of deploying applications in Dokku. As of v0.12.0, Dokku introduces a few ways to customize the experience of deploying via `git push`. A Git-based deployment currently supports building applications via: Git-based deployment has been the traditional method of deploying applications in Dokku. As of v0.12.0, Dokku introduces a few ways to customize the experience of deploying via `git push`. A Git-based deployment currently supports building applications via:
@@ -158,6 +157,12 @@ By default, this command does not trigger an application build. To do so during
dokku git:sync --build node-js-app https://github.com/heroku/node-js-getting-started.git dokku git:sync --build node-js-app https://github.com/heroku/node-js-getting-started.git
``` ```
When running `git:sync` without a reference, it may be useful to only build when there are changes. To do so, specify the `--build-if-changes` flag.
```shell
dokku git:sync --build-if-changes node-js-app https://github.com/heroku/node-js-getting-started.git
```
### Initializing from private repositories ### Initializing from private repositories
> [!IMPORTANT] > [!IMPORTANT]

View File

@@ -32,20 +32,6 @@ dokku scheduler:set node-js-app selected
Many builders only produce amd64-compatible images. The docker-local scheduler will automatically detect these and run them via the `--platform=linux/amd64` on arm64 deploy targets. Many builders only produce amd64-compatible images. The docker-local scheduler will automatically detect these and run them via the `--platform=linux/amd64` on arm64 deploy targets.
### Disabling chown of persistent storage
The `scheduler-docker-local` plugin will ensure your storage mounts are owned by either `herokuishuser` or the overridden value you have set in `DOKKU_APP_USER`. You may disable this by running the following `scheduler-docker-local:set` command for your application:
```shell
dokku scheduler-docker-local:set node-js-app disable-chown true
```
Once set, you may re-enable it by setting a blank value for `disable-chown`:
```shell
dokku scheduler-docker-local:set node-js-app disable-chown
```
### Disabling the init process ### Disabling the init process
The `scheduler-docker-local` injects an init process by default via the `--init`. For some apps - such as those where the built docker image uses S6 as the init - this may be undesirable and cause issues with process starts. You may disable this by running the following `scheduler-docker-local:set` command for your application: The `scheduler-docker-local` injects an init process by default via the `--init`. For some apps - such as those where the built docker image uses S6 as the init - this may be undesirable and cause issues with process starts. You may disable this by running the following `scheduler-docker-local:set` command for your application:

View File

@@ -58,12 +58,12 @@ By default, Dokku will attempt to auto-detect the IP address of the server. In c
dokku scheduler-k3s:initialize --server-ip 192.168.20.15 dokku scheduler-k3s:initialize --server-ip 192.168.20.15
``` ```
Dokku's k3s integration natively uses `Traefik` as it's ingress load balancer via [Traefik's CRDs](https://doc.traefik.io/traefik/providers/kubernetes-crd/), but a cluster can be set to use `nginx` via the [ingress-nginx](https://github.com/kubernetes/ingress-nginx) project. Switching to nginx will result in any `nginx` plugin settings being respected, either by turning them into annotations or creating a custom server snippet. Dokku's k3s integration natively uses `nginx` as it's ingress load balancer via [ingress-nginx](https://github.com/kubernetes/ingress-nginx). Properties set by the `nginx` plugin will be respected, either by turning them into annotations or creating a custom server/location snippet that the `ingress-nginx` project can use.
To change the ingress, set the `--ingress-class` flag: Dokku can also use Traefik on cluster initialization via the [Traefik's CRDs](https://doc.traefik.io/traefik/providers/kubernetes-crd/). To change the ingress, set the `--ingress-class` flag:
```shell ```shell
dokku scheduler-k3s:initialize --ingress-class nginx dokku scheduler-k3s:initialize --ingress-class traefik
``` ```
### Adding nodes to the cluster ### Adding nodes to the cluster

View File

@@ -18,6 +18,7 @@ Docker releases updates periodically to their engine. We recommend reading their
Before upgrading, check the migration guides to get comfortable with new features and prepare your deployment to be upgraded. Before upgrading, check the migration guides to get comfortable with new features and prepare your deployment to be upgraded.
- [Upgrading to 0.34](/docs/appendices/0.34.0-migration-guide.md)
- [Upgrading to 0.33](/docs/appendices/0.33.0-migration-guide.md) - [Upgrading to 0.33](/docs/appendices/0.33.0-migration-guide.md)
- [Upgrading to 0.32](/docs/appendices/0.32.0-migration-guide.md) - [Upgrading to 0.32](/docs/appendices/0.32.0-migration-guide.md)
- [Upgrading to 0.31](/docs/appendices/0.31.0-migration-guide.md) - [Upgrading to 0.31](/docs/appendices/0.31.0-migration-guide.md)

View File

@@ -116,16 +116,6 @@ dokku traefik:set --global log-level DEBUG
After modifying, the Traefik container will need to be restarted. After modifying, the Traefik container will need to be restarted.
### Setting rule priority
By default, app deployments will result in the newer traefik rules using a higher priority in order to have any newer rules respected by Traefik. Rule priorities will always increase according to the current unix timestamp. The priority may be fixed by setting the app-level `priority` property:
```shell
dokku traefik:set node-js-app priority 12345
```
After modifying, the app container will need to be recreated via a `ps:rebuild` or an app deployment.
### SSL Configuration ### SSL Configuration
The traefik plugin only supports automatic ssl certificates from it's letsencrypt integration. Managed certificates provided by the `certs` plugin are ignored. The traefik plugin only supports automatic ssl certificates from it's letsencrypt integration. Managed certificates provided by the `certs` plugin are ignored.

View File

@@ -12,7 +12,7 @@ proxy:report [<app>] [<flag>] # Displays a proxy report fo
proxy:set [<app>|--global] <proxy-type> # Set proxy type for app proxy:set [<app>|--global] <proxy-type> # Set proxy type for app
``` ```
In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into the proxy plugin. Dokku 0.6.0 introduced the ability to map host ports to specific container ports. In the future this will allow other proxy software - such as HAProxy or Caddy - to be used in place of nginx. In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into the proxy plugin. Dokku 0.6.0 introduced the ability to map host ports to specific container ports. This allows other proxy software - such as HAProxy or Caddy - to be used in place of nginx.
## Usage ## Usage

19
dokku
View File

@@ -55,7 +55,7 @@ export DOKKU_SYSTEM_USER=${DOKKU_SYSTEM_USER:="dokku"}
export DOKKU_API_VERSION=1 export DOKKU_API_VERSION=1
export DOKKU_NOT_IMPLEMENTED_EXIT=10 export DOKKU_NOT_IMPLEMENTED_EXIT=10
export DOKKU_VALID_EXIT=0 export DOKKU_VALID_EXIT=0
export DOKKU_PID="$BASHPID" export DOKKU_PID="${DOKKU_PID:=$$}"
export DOKKU_LOGS_DIR=${DOKKU_LOGS_DIR:="/var/log/dokku"} export DOKKU_LOGS_DIR=${DOKKU_LOGS_DIR:="/var/log/dokku"}
export DOKKU_LOGS_HOST_DIR=${DOKKU_LOGS_HOST_DIR:=$DOKKU_LOGS_DIR} export DOKKU_LOGS_HOST_DIR=${DOKKU_LOGS_HOST_DIR:=$DOKKU_LOGS_DIR}
@@ -88,8 +88,8 @@ fi
! has_tty && DOKKU_QUIET_OUTPUT=1 ! has_tty && DOKKU_QUIET_OUTPUT=1
if [[ $(id -un) != "dokku" ]]; then if [[ $(id -un) != "dokku" ]]; then
unset TMP TMPDIR TEMP TEMPDIR
if [[ ! $1 =~ plugin:* ]] && [[ $1 != "ssh-keys:add" ]] && [[ $1 != "ssh-keys:remove" ]] && [[ $1 != "scheduler-k3s:initialize" ]] && [[ $1 != "scheduler-k3s:uninstall" ]]; then if [[ ! $1 =~ plugin:* ]] && [[ $1 != "ssh-keys:add" ]] && [[ $1 != "ssh-keys:remove" ]] && [[ $1 != "scheduler-k3s:initialize" ]] && [[ $1 != "scheduler-k3s:uninstall" ]]; then
unset DOKKU_PID TMP TMPDIR TEMP TEMPDIR
export SSH_USER=$(id -un) export SSH_USER=$(id -un)
sudo -u dokku -E -H "$0" "$@" sudo -u dokku -E -H "$0" "$@"
exit $? exit $?
@@ -106,15 +106,20 @@ fi
if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then
export -n SSH_ORIGINAL_COMMAND export -n SSH_ORIGINAL_COMMAND
if [[ $1 =~ config-* ]] || [[ $1 =~ docker-options* ]]; then exit_code=0
xargs $0 <<<$SSH_ORIGINAL_COMMAND if [[ $1 =~ git-* ]] || [[ $1 =~ git:* ]]; then
exit $?
else
set -f set -f
$0 $SSH_ORIGINAL_COMMAND $0 $SSH_ORIGINAL_COMMAND
exit_code=$?
set +f
else
readarray -t -O "${#ssh_arg_array[@]}" ssh_arg_array < <(printf '%s' "$SSH_ORIGINAL_COMMAND" | xargs -n 1)
set -f
$0 "${ssh_arg_array[@]}"
exit_code=$?
set +f set +f
exit $?
fi fi
exit $exit_code
fi fi
if ! dokku_auth "$@"; then if ! dokku_auth "$@"; then

View File

@@ -17,6 +17,10 @@ cmd-report() {
dokku_log_info1 "uname: $(uname -a)" dokku_log_info1 "uname: $(uname -a)"
dokku_log_info1 "memory: " dokku_log_info1 "memory: "
free -m | sed "s/^/ /" free -m | sed "s/^/ /"
dokku_log_info1 "disk utilization: "
df -h --type btrfs --type ext4 --type ext3 --type ext2 --type vfat --type iso9660 | sed "s/^/ /"
dokku_log_info1 "disk inode utilization: "
df -hi --type btrfs --type ext4 --type ext3 --type ext2 --type vfat --type iso9660 | sed "s/^/ /"
dokku_log_info1 "docker version: " dokku_log_info1 "docker version: "
"$DOCKER_BIN" version | sed "s/^/ /" "$DOCKER_BIN" version | sed "s/^/ /"
dokku_log_info1 "docker daemon info: " dokku_log_info1 "docker daemon info: "

View File

@@ -56,16 +56,12 @@ EOF
cat >"$DOKKU_LOGROTATE_FILE" <<EOF cat >"$DOKKU_LOGROTATE_FILE" <<EOF
$DOKKU_LOGS_DIR/*.log { $DOKKU_LOGS_DIR/*.log {
daily daily
rotate 7
missingok missingok
notifempty rotate 7
su syslog dokku
compress compress
delaycompress delaycompress
postrotate notifempty
reload rsyslog &>/dev/null || true copytruncate
endscript
create 664 syslog dokku
} }
EOF EOF

View File

@@ -102,8 +102,11 @@ func getPhaseScript(appName string, phase string) (string, error) {
func getReleaseCommand(appName string, image string) string { func getReleaseCommand(appName string, image string) string {
processType := "release" processType := "release"
port := "5000" port := "5000"
b, _ := common.PlugnTriggerOutput("procfile-get-command", []string{appName, processType, port}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
return strings.TrimSpace(string(b[:])) Trigger: "procfile-get-command",
Args: []string{appName, processType, port},
})
return results.StdoutContents()
} }
func getDokkuAppShell(appName string) string { func getDokkuAppShell(appName string) string {
@@ -114,13 +117,19 @@ func getDokkuAppShell(appName string) string {
ctx := context.Background() ctx := context.Background()
errs, ctx := errgroup.WithContext(ctx) errs, ctx := errgroup.WithContext(ctx)
errs.Go(func() error { errs.Go(func() error {
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_APP_SHELL"}...) results, _ := common.CallPlugnTriggerWithContext(ctx, common.PlugnTriggerInput{
globalShell = strings.TrimSpace(string(b[:])) Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell = results.StdoutContents()
return nil return nil
}) })
errs.Go(func() error { errs.Go(func() error {
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_SHELL"}...) results, _ := common.CallPlugnTriggerWithContext(ctx, common.PlugnTriggerInput{
appShell = strings.TrimSpace(string(b[:])) Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell = results.StdoutContents()
return nil return nil
}) })
@@ -204,8 +213,13 @@ func executeScript(appName string, image string, imageTag string, phase string)
} }
var dockerArgs []string var dockerArgs []string
if b, err := common.PlugnTriggerSetup("docker-args-deploy", []string{appName, imageTag}...).SetInput("").Output(); err == nil { results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
words, err := shellquote.Split(strings.TrimSpace(string(b[:]))) Trigger: "docker-args-deploy",
Args: []string{appName, imageTag},
Stdin: strings.NewReader(""),
})
if err == nil {
words, err := shellquote.Split(results.StdoutContents())
if err != nil { if err != nil {
return err return err
} }
@@ -213,8 +227,13 @@ func executeScript(appName string, image string, imageTag string, phase string)
dockerArgs = append(dockerArgs, words...) dockerArgs = append(dockerArgs, words...)
} }
if b, err := common.PlugnTriggerSetup("docker-args-process-deploy", []string{appName, imageSourceType, imageTag}...).SetInput("").Output(); err == nil { results, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
words, err := shellquote.Split(strings.TrimSpace(string(b[:]))) Trigger: "docker-args-process-deploy",
Args: []string{appName, imageSourceType, imageTag},
Stdin: strings.NewReader(""),
})
if err == nil {
words, err := shellquote.Split(results.StdoutContents())
if err != nil { if err != nil {
return err return err
} }
@@ -398,12 +417,15 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma
arguments = append(arguments, image) arguments = append(arguments, image)
arguments = append(arguments, command...) arguments = append(arguments, command...)
b, err := common.PlugnTriggerOutput("config-export", []string{appName, "false", "true", "json"}...) results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-export",
Args: []string{appName, "false", "true", "json"},
})
if err != nil { if err != nil {
return "", err return "", err
} }
var env map[string]string var env map[string]string
if err := json.Unmarshal(b, &env); err != nil { if err := json.Unmarshal(results.StdoutBytes(), &env); err != nil {
return "", err return "", err
} }
@@ -420,7 +442,11 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma
} }
containerID := result.StdoutContents() containerID := result.StdoutContents()
err = common.PlugnTrigger("post-container-create", []string{"app", containerID, appName, phase}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-container-create",
Args: []string{"app", containerID, appName, phase},
StreamStdio: true,
})
return containerID, err return containerID, err
} }
@@ -440,12 +466,27 @@ func setScale(appName string, image string) error {
} }
if len(args) == 3 { if len(args) == 3 {
return common.PlugnTrigger("ps-can-scale", []string{appName, "true"}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
} Trigger: "ps-can-scale",
Args: []string{appName, "true"},
if err := common.PlugnTrigger("ps-can-scale", []string{appName, "false"}...); err != nil { StreamStdio: true,
})
return err return err
} }
return common.PlugnTrigger("ps-set-scale", args...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "ps-can-scale",
Args: []string{appName, "false"},
StreamStdio: true,
})
if err != nil {
return err
}
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "ps-set-scale",
Args: args,
StreamStdio: true,
})
return err
} }

View File

@@ -12,8 +12,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@@ -101,11 +101,17 @@ func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
} }
processSpecificAppJSON := fmt.Sprintf("%s.%s", existingAppJSON, os.Getenv("DOKKU_PID")) processSpecificAppJSON := fmt.Sprintf("%s.%s", existingAppJSON, os.Getenv("DOKKU_PID"))
b, _ := common.PlugnTriggerOutput("git-get-property", []string{appName, "source-image"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
appSourceImage := strings.TrimSpace(string(b[:])) Trigger: "git-get-property",
Args: []string{appName, "source-image"},
})
appSourceImage := results.StdoutContents()
b, _ = common.PlugnTriggerOutput("builder-get-property", []string{appName, "build-dir"}...) results, _ = common.CallPlugnTrigger(common.PlugnTriggerInput{
buildDir := strings.TrimSpace(string(b[:])) Trigger: "builder-get-property",
Args: []string{appName, "build-dir"},
})
buildDir := results.StdoutContents()
repoDefaultAppJSONPath := path.Join(sourceWorkDir, "app.json") repoDefaultAppJSONPath := path.Join(sourceWorkDir, "app.json")
if appSourceImage == "" { if appSourceImage == "" {
@@ -179,7 +185,7 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
return common.CloneAppData("app-json", oldAppName, newAppName) return common.CloneAppData("app-json", oldAppName, newAppName)
} }
// TriggerPostCreate ensures apps the correct data directory structure // TriggerPostCreate ensures apps have the correct data directory structure
func TriggerPostCreate(appName string) error { func TriggerPostCreate(appName string) error {
return common.CreateAppDataDirectory("app-json", appName) return common.CreateAppDataDirectory("app-json", appName)
} }

View File

@@ -1,5 +1,5 @@
SUBCOMMANDS = subcommands/clone subcommands/create subcommands/destroy subcommands/exists subcommands/list subcommands/lock subcommands/locked subcommands/rename subcommands/report subcommands/unlock SUBCOMMANDS = subcommands/clone subcommands/create subcommands/destroy subcommands/exists subcommands/list subcommands/lock subcommands/locked subcommands/rename subcommands/report subcommands/unlock
TRIGGERS = triggers/app-create triggers/app-destroy triggers/app-exists triggers/app-maybe-create triggers/deploy-source-set triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report TRIGGERS = triggers/app-create triggers/app-destroy triggers/app-exists triggers/app-maybe-create triggers/deploy-source-set triggers/install triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/report
BUILD = commands subcommands triggers BUILD = commands subcommands triggers
PLUGIN_NAME = apps PLUGIN_NAME = apps

View File

@@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"strings"
"time" "time"
"github.com/dokku/dokku/plugins/common" "github.com/dokku/dokku/plugins/common"
@@ -17,8 +16,8 @@ func appExists(appName string) error {
// checks if an app is locked // checks if an app is locked
func appIsLocked(appName string) bool { func appIsLocked(appName string) bool {
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName)) lockPath := getLockPath(appName)
_, err := os.Stat(lockfilePath) _, err := os.Stat(lockPath)
return !os.IsNotExist(err) return !os.IsNotExist(err)
} }
@@ -39,11 +38,12 @@ func createApp(appName string) error {
return err return err
} }
if err := common.PlugnTrigger("post-create", []string{appName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
return err Trigger: "post-create",
} Args: []string{appName},
StreamStdio: true,
return nil })
return err
} }
// destroys an app // destroys an app
@@ -57,19 +57,41 @@ func destroyApp(appName string) error {
common.LogInfo1(fmt.Sprintf("Destroying %s (including all add-ons)", appName)) common.LogInfo1(fmt.Sprintf("Destroying %s (including all add-ons)", appName))
imageTag, _ := common.GetRunningImageTag(appName, "") imageTag, _ := common.GetRunningImageTag(appName, "")
if err := common.PlugnTrigger("pre-delete", []string{appName, imageTag}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "pre-delete",
Args: []string{appName, imageTag},
StreamStdio: true,
})
if err != nil {
return err return err
} }
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
removeContainers := "true" removeContainers := "true"
if err := common.PlugnTrigger("scheduler-stop", []string{scheduler, appName, removeContainers}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-stop",
Args: []string{scheduler, appName, removeContainers},
StreamStdio: true,
})
if err != nil {
return err return err
} }
if err := common.PlugnTrigger("scheduler-post-delete", []string{scheduler, appName, imageTag}...); err != nil {
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-post-delete",
Args: []string{scheduler, appName, imageTag},
StreamStdio: true,
})
if err != nil {
return err return err
} }
if err := common.PlugnTrigger("post-delete", []string{appName, imageTag}...); err != nil {
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-delete",
Args: []string{appName, imageTag},
StreamStdio: true,
})
if err != nil {
return err return err
} }
@@ -77,7 +99,12 @@ func destroyApp(appName string) error {
common.DockerCleanup(appName, forceCleanup) common.DockerCleanup(appName, forceCleanup)
common.LogInfo1("Retiring old containers and images") common.LogInfo1("Retiring old containers and images")
if err := common.PlugnTrigger("scheduler-retire", []string{scheduler, appName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-retire",
Args: []string{scheduler, appName},
StreamStdio: true,
})
if err != nil {
return err return err
} }
@@ -94,14 +121,22 @@ func destroyApp(appName string) error {
return nil return nil
} }
// returns the lock path
func getLockPath(appName string) string {
return fmt.Sprintf("%v/.deploy.lock", common.GetAppDataDirectory("apps", appName))
}
// creates an app if allowed // creates an app if allowed
func maybeCreateApp(appName string) error { func maybeCreateApp(appName string) error {
if err := appExists(appName); err == nil { if err := appExists(appName); err == nil {
return nil return nil
} }
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_DISABLE_APP_AUTOCREATION"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
disableAutocreate := strings.TrimSpace(string(b[:])) Trigger: "config-get-global",
Args: []string{"DOKKU_DISABLE_APP_AUTOCREATION"},
})
disableAutocreate := results.StdoutContents()
if disableAutocreate == "true" { if disableAutocreate == "true" {
common.LogWarn("App auto-creation disabled.") common.LogWarn("App auto-creation disabled.")
return fmt.Errorf("Re-enable app auto-creation or create an app with 'dokku apps:create %s'", appName) return fmt.Errorf("Re-enable app auto-creation or create an app with 'dokku apps:create %s'", appName)

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -41,10 +41,17 @@ func main() {
oldAppName := flag.Arg(0) oldAppName := flag.Arg(0)
newAppName := flag.Arg(1) newAppName := flag.Arg(1)
err = apps.TriggerPostAppCloneSetup(oldAppName, newAppName) err = apps.TriggerPostAppCloneSetup(oldAppName, newAppName)
case "post-app-rename":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = apps.TriggerPostAppRename(oldAppName, newAppName)
case "post-app-rename-setup": case "post-app-rename-setup":
oldAppName := flag.Arg(0) oldAppName := flag.Arg(0)
newAppName := flag.Arg(1) newAppName := flag.Arg(1)
err = apps.TriggerPostAppRenameSetup(oldAppName, newAppName) err = apps.TriggerPostAppRenameSetup(oldAppName, newAppName)
case "post-create":
appName := flag.Arg(0)
err = apps.TriggerPostCreate(appName)
case "post-delete": case "post-delete":
appName := flag.Arg(0) appName := flag.Arg(0)
err = apps.TriggerPostDelete(appName) err = apps.TriggerPostDelete(appName)

View File

@@ -40,7 +40,12 @@ func CommandClone(oldAppName string, newAppName string, skipDeploy bool, ignoreE
return err return err
} }
if err := common.PlugnTrigger("post-app-clone-setup", []string{oldAppName, newAppName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-app-clone-setup",
Args: []string{oldAppName, newAppName},
StreamStdio: true,
})
if err != nil {
return err return err
} }
@@ -48,15 +53,21 @@ func CommandClone(oldAppName string, newAppName string, skipDeploy bool, ignoreE
os.Setenv("SKIP_REBUILD", "true") os.Setenv("SKIP_REBUILD", "true")
} }
if err := common.PlugnTrigger("git-has-code", []string{newAppName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "git-has-code",
Args: []string{newAppName},
StreamStdio: true,
})
if err != nil {
os.Setenv("SKIP_REBUILD", "true") os.Setenv("SKIP_REBUILD", "true")
} }
if err := common.PlugnTrigger("post-app-clone", []string{oldAppName, newAppName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
return err Trigger: "post-app-clone",
} Args: []string{oldAppName, newAppName},
StreamStdio: true,
return nil })
return err
} }
// CommandCreate creates app via command line // CommandCreate creates app via command line
@@ -108,8 +119,8 @@ func CommandLock(appName string) error {
return err return err
} }
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName)) lockPath := getLockPath(appName)
if _, err := os.Create(lockfilePath); err != nil { if _, err := os.Create(lockPath); err != nil {
return errors.New("Unable to create deploy lock") return errors.New("Unable to create deploy lock")
} }
@@ -158,7 +169,12 @@ func CommandRename(oldAppName string, newAppName string, skipDeploy bool) error
return err return err
} }
if err := common.PlugnTrigger("post-app-rename-setup", []string{oldAppName, newAppName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-app-rename-setup",
Args: []string{oldAppName, newAppName},
StreamStdio: true,
})
if err != nil {
return err return err
} }
@@ -171,15 +187,21 @@ func CommandRename(oldAppName string, newAppName string, skipDeploy bool) error
os.Setenv("SKIP_REBUILD", "true") os.Setenv("SKIP_REBUILD", "true")
} }
if err := common.PlugnTrigger("git-has-code", []string{newAppName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "git-has-code",
Args: []string{newAppName},
StreamStdio: true,
})
if err != nil {
os.Setenv("SKIP_REBUILD", "true") os.Setenv("SKIP_REBUILD", "true")
} }
if err := common.PlugnTrigger("post-app-rename", []string{oldAppName, newAppName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
return err Trigger: "post-app-rename",
} Args: []string{oldAppName, newAppName},
StreamStdio: true,
return nil })
return err
} }
// CommandReport displays an app report for one or more apps // CommandReport displays an app report for one or more apps
@@ -206,7 +228,7 @@ func CommandUnlock(appName string) error {
return err return err
} }
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName)) lockfilePath := getLockPath(appName)
if _, err := os.Stat(lockfilePath); !os.IsNotExist(err) { if _, err := os.Stat(lockfilePath); !os.IsNotExist(err) {
common.LogWarn("A deploy may be in progress.") common.LogWarn("A deploy may be in progress.")
common.LogWarn("Removing the app lock will not stop in progress deploys.") common.LogWarn("Removing the app lock will not stop in progress deploys.")

View File

@@ -43,6 +43,10 @@ func TriggerInstall() error {
return fmt.Errorf("Unable to install the apps plugin: %s", err.Error()) return fmt.Errorf("Unable to install the apps plugin: %s", err.Error())
} }
if err := common.SetupAppData("apps"); err != nil {
return err
}
apps, err := common.UnfilteredDokkuApps() apps, err := common.UnfilteredDokkuApps()
if err != nil { if err != nil {
return nil return nil
@@ -79,7 +83,12 @@ func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
return err return err
} }
return nil return common.CloneAppData("apps", oldAppName, newAppName)
}
// TriggerPostAppRename removes the old app data
func TriggerPostAppRename(oldAppName string, newAppName string) error {
return common.MigrateAppDataDirectory("apps", oldAppName, newAppName)
} }
// TriggerPostAppRenameSetup renames apps files // TriggerPostAppRenameSetup renames apps files
@@ -92,14 +101,22 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
return err return err
} }
return nil return common.CloneAppData("apps", oldAppName, newAppName)
} }
// TriggerPostDelete is the apps post-delete plugin trigger // TriggerPostCreate ensures apps have the correct data directory structure
func TriggerPostCreate(appName string) error {
return common.CreateAppDataDirectory("apps", appName)
}
// TriggerPostDelete destroys the apps data for a given app container
func TriggerPostDelete(appName string) error { func TriggerPostDelete(appName string) error {
if err := common.PropertyDestroy("apps", appName); err != nil { dataErr := common.RemoveAppDataDirectory("apps", appName)
common.LogWarn(err.Error()) propertyErr := common.PropertyDestroy("apps", appName)
if dataErr != nil {
return dataErr
} }
return nil return propertyErr
} }

View File

@@ -33,7 +33,10 @@ trigger-builder-herokuish-builder-release() {
DOCKER_BUILD_ARGS+=("--platform=linux/amd64") DOCKER_BUILD_ARGS+=("--platform=linux/amd64")
fi fi
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-herokuish/dockerfiles/builder-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" -t "$IMAGE" "$TMP_WORK_DIR"; then DOKKU_APP_USER=$(config_get "$APP" DOKKU_APP_USER || true)
DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"}
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-herokuish/dockerfiles/builder-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" --build-arg DOKKU_APP_USER=$DOKKU_APP_USER -t "$IMAGE" "$TMP_WORK_DIR"; then
dokku_log_warn "Failure injecting environment variables" dokku_log_warn "Failure injecting environment variables"
return 1 return 1
fi fi

View File

@@ -1,4 +1,8 @@
ARG APP_IMAGE ARG APP_IMAGE
FROM $APP_IMAGE FROM $APP_IMAGE
COPY 00-global-env.sh 01-app-env.sh /app/.profile.d/ ARG DOKKU_APP_USER herokuishuser
COPY --chown=$DOKKU_APP_USER 00-global-env.sh 01-app-env.sh /app/.profile.d/
RUN chown -R "$DOKKU_APP_USER:$DOKKU_APP_USER" /app
USER $DOKKU_APP_USER
ENV HEROKUISH_SETUIDGUID false

View File

@@ -4,4 +4,5 @@ FROM $APP_IMAGE
ARG DOKKU_APP_USER herokuishuser ARG DOKKU_APP_USER herokuishuser
RUN USER=$DOKKU_APP_USER /exec true RUN USER=$DOKKU_APP_USER /exec true
COPY --chown=$DOKKU_APP_USER . /app COPY --chown=$DOKKU_APP_USER . /app
WORKDIR /app WORKDIR /app
ENV HEROKUISH_DISABLE_CHOWN true

View File

@@ -1,5 +1,5 @@
ARG APP_IMAGE ARG APP_IMAGE
FROM $APP_IMAGE FROM $APP_IMAGE
COPY .env.d /tmp/env COPY --chown=$DOKKU_APP_USER .env.d /tmp/env
COPY .env /app/.env COPY --chown=$DOKKU_APP_USER .env /app/.env

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
trigger-builder-herokuish-post-app-clone-setup() {
declare desc="builder-herokuish post-app-clone-setup plugin trigger"
declare trigger="post-app-clone-setup"
declare OLD_APP="$1" NEW_APP="$2"
local NEW_CACHE_DIR="$DOKKU_ROOT/$NEW_APP/cache"
local NEW_CACHE_HOST_DIR="$DOKKU_HOST_ROOT/$NEW_APP/cache"
pushd "$DOKKU_ROOT/$OLD_APP/." >/dev/null
find ./* \( -name ".cache" -o -name "cache" \) -prune -o -print | cpio -pdmu --quiet "$DOKKU_ROOT/$NEW_APP"
popd &>/dev/null || pushd "/tmp" >/dev/null
if [[ -d "$NEW_CACHE_DIR" ]] && ! rmdir "$NEW_CACHE_DIR"; then
local DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$NEW_APP"
"$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --rm --volume "$NEW_CACHE_HOST_DIR:/cache" "dokku/$OLD_APP" chmod 777 -R /cache
fi
rm -rf "$NEW_CACHE_DIR"
}
trigger-builder-herokuish-post-app-clone-setup "$@"

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
trigger-builder-herokuish-post-app-clone-setup() {
declare desc="builder-herokuish post-app-clone-setup plugin trigger"
declare trigger="post-app-clone-setup"
declare OLD_APP="$1" NEW_APP="$2"
local OLD_CACHE_DIR="$DOKKU_ROOT/$OLD_APP/cache"
local OLD_CACHE_HOST_DIR="$DOKKU_HOST_ROOT/$OLD_APP/cache"
if [[ -d "$OLD_CACHE_DIR" ]] && ! rmdir "$OLD_CACHE_DIR" &>/dev/null; then
local DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$NEW_APP"
"$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS --rm --volume "$OLD_CACHE_HOST_DIR:/cache" "dokku/$OLD_APP" chmod 777 -R /cache
fi
rm -rf "$OLD_CACHE_DIR"
pushd "$DOKKU_ROOT/$OLD_APP/." >/dev/null
find ./* \( -name ".cache" -o -name "cache" \) -prune -o -print | cpio -pdmu --quiet "$DOKKU_ROOT/$NEW_APP"
popd &>/dev/null || pushd "/tmp" >/dev/null
}
trigger-builder-herokuish-post-app-clone-setup "$@"

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -44,7 +44,7 @@ func rewriteBuildpacksFile(sourceWorkDir string) error {
func validBuildpackURL(buildpack string) (string, error) { func validBuildpackURL(buildpack string) (string, error) {
if buildpack == "" { if buildpack == "" {
return buildpack, errors.New("Must specify a buildpack to add") return buildpack, errors.New("Must specify a buildpack url or reference")
} }
reHerokuValue := regexp.MustCompile(`(?m)^([\w-]+\/[\w-]+)$`) reHerokuValue := regexp.MustCompile(`(?m)^([\w-]+\/[\w-]+)$`)

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -40,8 +40,11 @@ func reportComputedStack(appName string) string {
return stack return stack
} }
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_IMAGE"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
if dokkuImage := strings.TrimSpace(string(b[:])); dokkuImage != "" { Trigger: "config-get",
Args: []string{appName, "DOKKU_IMAGE"},
})
if dokkuImage := results.StdoutContents(); dokkuImage != "" {
common.LogWarn("Deprecated: use buildpacks:set-property instead of specifying DOKKU_IMAGE environment variable") common.LogWarn("Deprecated: use buildpacks:set-property instead of specifying DOKKU_IMAGE environment variable")
return dokkuImage return dokkuImage
} }

View File

@@ -65,7 +65,7 @@ func CommandRemove(appName string, buildpack string, index int) (err error) {
} }
buildpack, err = validBuildpackURL(buildpack) buildpack, err = validBuildpackURL(buildpack)
if err != nil { if index == 0 && err != nil {
return err return err
} }
@@ -149,7 +149,12 @@ func CommandSetProperty(appName string, property string, value string) error {
common.CommandPropertySet("buildpacks", appName, property, value, DefaultProperties, GlobalProperties) common.CommandPropertySet("buildpacks", appName, property, value, DefaultProperties, GlobalProperties)
if property == "stack" && oldStack != value { if property == "stack" && oldStack != value {
if appName != "--global" { if appName != "--global" {
return common.PlugnTrigger("post-stack-set", []string{appName, value}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-stack-set",
Args: []string{appName, value},
StreamStdio: true,
})
return err
} }
apps, err := common.DokkuApps() apps, err := common.DokkuApps()
@@ -157,7 +162,12 @@ func CommandSetProperty(appName string, property string, value string) error {
return err return err
} }
for _, app := range apps { for _, app := range apps {
if err := common.PlugnTrigger("post-stack-set", []string{app, value}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-stack-set",
Args: []string{app, value},
StreamStdio: true,
})
if err != nil {
return err return err
} }
} }

View File

@@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/dokku/dokku/plugins/common" "github.com/dokku/dokku/plugins/common"
) )
@@ -22,8 +21,11 @@ func TriggerBuildpackStackName(appName string) error {
return nil return nil
} }
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_IMAGE"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
dokkuImage := strings.TrimSpace(string(b[:])) Trigger: "config-get",
Args: []string{appName, "DOKKU_IMAGE"},
})
dokkuImage := results.StdoutContents()
if dokkuImage != "" { if dokkuImage != "" {
common.LogWarn("Deprecated: use buildpacks:set-property instead of specifying DOKKU_IMAGE environment variable") common.LogWarn("Deprecated: use buildpacks:set-property instead of specifying DOKKU_IMAGE environment variable")
fmt.Println(dokkuImage) fmt.Println(dokkuImage)

View File

@@ -124,8 +124,11 @@ func GetAppScheduler(appName string) string {
} }
func getAppScheduler(appName string) string { func getAppScheduler(appName string) string {
b, _ := PlugnTriggerOutput("scheduler-detect", []string{appName}...) results, _ := CallPlugnTrigger(PlugnTriggerInput{
value := strings.TrimSpace(string(b[:])) Trigger: "scheduler-detect",
Args: []string{appName},
})
value := results.StdoutContents()
if value != "" { if value != "" {
return value return value
} }
@@ -134,8 +137,11 @@ func getAppScheduler(appName string) string {
// GetGlobalScheduler fetchs the global scheduler // GetGlobalScheduler fetchs the global scheduler
func GetGlobalScheduler() string { func GetGlobalScheduler() string {
b, _ := PlugnTriggerOutput("scheduler-detect", []string{"--global"}...) results, _ := CallPlugnTrigger(PlugnTriggerInput{
value := strings.TrimSpace(string(b[:])) Trigger: "scheduler-detect",
Args: []string{"--global"},
})
value := results.StdoutContents()
if value != "" { if value != "" {
return value return value
} }
@@ -152,24 +158,34 @@ func GetDeployingAppImageName(appName, imageTag, imageRepo string) (string, erro
ctx := context.Background() ctx := context.Background()
errs, ctx := errgroup.WithContext(ctx) errs, ctx := errgroup.WithContext(ctx)
errs.Go(func() error { errs.Go(func() error {
b, err := PlugnTriggerOutput("deployed-app-repository", []string{appName}...) results, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: "deployed-app-repository",
Args: []string{appName},
})
if err == nil { if err == nil {
imageRemoteRepository = strings.TrimSpace(string(b[:])) imageRemoteRepository = results.StdoutContents()
} }
return err return err
}) })
errs.Go(func() error { errs.Go(func() error {
b, err := PlugnTriggerOutput("deployed-app-image-tag", []string{appName}...) results, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: "deployed-app-image-tag",
Args: []string{appName},
})
if err == nil { if err == nil {
newImageTag = strings.TrimSpace(string(b[:])) newImageTag = results.StdoutContents()
} }
return err return err
}) })
errs.Go(func() error { errs.Go(func() error {
b, err := PlugnTriggerOutput("deployed-app-image-repo", []string{appName}...) results, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: "deployed-app-image-repo",
Args: []string{appName},
})
if err == nil { if err == nil {
newImageRepo = strings.TrimSpace(string(b[:])) newImageRepo = results.StdoutContents()
} }
return err return err
}) })
@@ -251,11 +267,14 @@ func GetAppRunningContainerIDs(appName string, containerType string) ([]string,
// GetRunningImageTag retrieves current deployed image tag for a given app // GetRunningImageTag retrieves current deployed image tag for a given app
func GetRunningImageTag(appName string, imageTag string) (string, error) { func GetRunningImageTag(appName string, imageTag string) (string, error) {
b, err := PlugnTriggerOutput("deployed-app-image-tag", []string{appName}...) results, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: "deployed-app-image-tag",
Args: []string{appName},
})
if err != nil { if err != nil {
return imageTag, err return imageTag, err
} }
newImageTag := strings.TrimSpace(string(b[:])) newImageTag := results.StdoutContents()
if newImageTag != "" { if newImageTag != "" {
imageTag = newImageTag imageTag = newImageTag
} }
@@ -326,7 +345,10 @@ func IsDeployed(appName string) bool {
if deployed == "" { if deployed == "" {
deployed = "false" deployed = "false"
scheduler := GetAppScheduler(appName) scheduler := GetAppScheduler(appName)
_, err := PlugnTriggerOutput("scheduler-is-deployed", []string{scheduler, appName}...) _, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: "scheduler-is-deployed",
Args: []string{scheduler, appName},
})
if err == nil { if err == nil {
deployed = "true" deployed = "true"
} }

View File

@@ -182,9 +182,11 @@ func DockerCleanup(appName string, forceCleanup bool) error {
triggerArgs = []string{"DOKKU_SKIP_CLEANUP"} triggerArgs = []string{"DOKKU_SKIP_CLEANUP"}
} }
b, _ := PlugnTriggerOutput(triggerName, triggerArgs...) results, _ := CallPlugnTrigger(PlugnTriggerInput{
output := strings.TrimSpace(string(b[:])) Trigger: triggerName,
if output == "true" { Args: triggerArgs,
})
if results.StdoutContents() == "true" {
skipCleanup = true skipCleanup = true
} }
} }
@@ -309,9 +311,12 @@ func IsImageHerokuishBased(image string, appName string) bool {
dokkuAppUser := "" dokkuAppUser := ""
if len(appName) != 0 { if len(appName) != 0 {
b, err := PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_USER"}...) results, err := CallPlugnTrigger(PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_USER"},
})
if err == nil { if err == nil {
dokkuAppUser = strings.TrimSpace(string(b)) dokkuAppUser = results.StdoutContents()
} }
} }

View File

@@ -77,6 +77,16 @@ func (ecr ExecCommandResponse) StderrContents() string {
return strings.TrimSpace(ecr.Stderr) return strings.TrimSpace(ecr.Stderr)
} }
// StderrBytes returns the trimmed stderr of the command as bytes
func (ecr ExecCommandResponse) StderrBytes() []byte {
return []byte(ecr.StderrContents())
}
// StdoutBytes returns the trimmed stdout of the command as bytes
func (ecr ExecCommandResponse) StdoutBytes() []byte {
return []byte(ecr.StdoutContents())
}
// CallExecCommand executes a command on the local host // CallExecCommand executes a command on the local host
func CallExecCommand(input ExecCommandInput) (ExecCommandResponse, error) { func CallExecCommand(input ExecCommandInput) (ExecCommandResponse, error) {
ctx := context.Background() ctx := context.Background()

View File

@@ -944,7 +944,7 @@ acquire_app_deploy_lock() {
declare desc="acquire advisory lock for use in deploys" declare desc="acquire advisory lock for use in deploys"
local APP="$1" local APP="$1"
local LOCK_TYPE="${2:-waiting}" local LOCK_TYPE="${2:-waiting}"
local APP_DEPLOY_LOCK_FILE="$DOKKU_ROOT/$APP/.deploy.lock" local APP_DEPLOY_LOCK_FILE="$DOKKU_LIB_ROOT/data/apps/$APP/.deploy.lock"
local LOCK_WAITING_MSG="$APP currently has a deploy lock in place. Waiting..." local LOCK_WAITING_MSG="$APP currently has a deploy lock in place. Waiting..."
local LOCK_FAILED_MSG="$APP currently has a deploy lock in place. Exiting..." local LOCK_FAILED_MSG="$APP currently has a deploy lock in place. Exiting..."
@@ -954,7 +954,7 @@ acquire_app_deploy_lock() {
release_app_deploy_lock() { release_app_deploy_lock() {
declare desc="release advisory lock used in deploys" declare desc="release advisory lock used in deploys"
local APP="$1" local APP="$1"
local APP_DEPLOY_LOCK_FILE="$DOKKU_ROOT/$APP/.deploy.lock" local APP_DEPLOY_LOCK_FILE="$DOKKU_LIB_ROOT/data/apps/$APP/.deploy.lock"
release_advisory_lock "$APP_DEPLOY_LOCK_FILE" release_advisory_lock "$APP_DEPLOY_LOCK_FILE"
} }
@@ -983,6 +983,7 @@ acquire_advisory_lock() {
dokku_log_fail "Run 'apps:unlock' to release the existing deploy lock" dokku_log_fail "Run 'apps:unlock' to release the existing deploy lock"
fi fi
fi fi
echo "$DOKKU_PID" >"$LOCK_FILE"
} }
release_advisory_lock() { release_advisory_lock() {
@@ -997,13 +998,14 @@ suppress_output() {
declare desc="suppress all output from a given command unless there is an error" declare desc="suppress all output from a given command unless there is an error"
local TMP_COMMAND_OUTPUT local TMP_COMMAND_OUTPUT
TMP_COMMAND_OUTPUT=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") TMP_COMMAND_OUTPUT=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_COMMAND_OUTPUT' >/dev/null" RETURN
"$@" >"$TMP_COMMAND_OUTPUT" 2>&1 || { "$@" >"$TMP_COMMAND_OUTPUT" 2>&1 || {
local exit_code="$?" local exit_code="$?"
cat "$TMP_COMMAND_OUTPUT" cat "$TMP_COMMAND_OUTPUT"
rm -rf "$TMP_COMMAND_OUTPUT" >/dev/null
return "$exit_code" return "$exit_code"
} }
rm -rf "$TMP_COMMAND_OUTPUT" >/dev/null
return 0 return 0
} }

View File

@@ -25,8 +25,11 @@ func filterApps(apps []string) ([]string, error) {
} }
args := append([]string{sshUser, sshName}, apps...) args := append([]string{sshUser, sshName}, apps...)
b, _ := PlugnTriggerOutput("user-auth-app", args...) results, _ := CallPlugnTrigger(PlugnTriggerInput{
filteredApps := strings.Split(strings.TrimSpace(string(b[:])), "\n") Trigger: "user-auth-app",
Args: args,
})
filteredApps := strings.Split(results.StdoutContents(), "\n")
filteredApps = removeEmptyEntries(filteredApps) filteredApps = removeEmptyEntries(filteredApps)
if len(filteredApps) == 0 { if len(filteredApps) == 0 {

View File

@@ -4,7 +4,6 @@ go 1.21
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 github.com/alexellis/go-execute/v2 v2.2.1
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
github.com/fatih/color v1.16.0 github.com/fatih/color v1.16.0
github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-multierror v1.1.1
github.com/melbahja/goph v1.4.0 github.com/melbahja/goph v1.4.0
@@ -17,7 +16,6 @@ require (
) )
require ( require (
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/kr/fs v0.1.0 // indirect github.com/kr/fs v0.1.0 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -1,158 +1,10 @@
package common package common
import ( import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/codeskyblue/go-sh"
) )
// ShellCmd represents a shell command to be run for dokku
type ShellCmd struct {
Env map[string]string
Command *exec.Cmd
CommandString string
Args []string
ShowOutput bool
ExitError *exec.ExitError
}
// NewShellCmd returns a new ShellCmd struct
//
// Deprecated: use CallExecCommand instead
func NewShellCmd(command string) *ShellCmd {
items := strings.Split(command, " ")
cmd := items[0]
args := items[1:]
return NewShellCmdWithArgs(cmd, args...)
}
// NewShellCmdWithArgs returns a new ShellCmd struct
//
// Deprecated: use CallExecCommand instead
func NewShellCmdWithArgs(cmd string, args ...string) *ShellCmd {
commandString := strings.Join(append([]string{cmd}, args...), " ")
return &ShellCmd{
Command: exec.Command(cmd, args...),
CommandString: commandString,
Args: args,
ShowOutput: true,
}
}
func (sc *ShellCmd) setup() {
env := os.Environ()
for k, v := range sc.Env {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
sc.Command.Env = env
if sc.ShowOutput {
sc.Command.Stdout = os.Stdout
sc.Command.Stderr = os.Stderr
}
}
// Execute is a lightweight wrapper around exec.Command
func (sc *ShellCmd) Execute() bool {
sc.setup()
if err := sc.Command.Run(); err != nil {
exitError, ok := err.(*exec.ExitError)
if ok {
sc.ExitError = exitError
}
return false
}
return true
}
// Start is a wrapper around exec.Command.Start()
func (sc *ShellCmd) Start() error {
sc.setup()
return sc.Command.Start()
}
// Output is a lightweight wrapper around exec.Command.Output()
func (sc *ShellCmd) Output() ([]byte, error) {
sc.setup()
return sc.Command.Output()
}
// CombinedOutput is a lightweight wrapper around exec.Command.CombinedOutput()
func (sc *ShellCmd) CombinedOutput() ([]byte, error) {
sc.setup()
return sc.Command.CombinedOutput()
}
// PlugnTrigger fire the given plugn trigger with the given args
//
// Deprecated: use CallPlugnTrigger instead
func PlugnTrigger(triggerName string, args ...string) error {
LogDebug(fmt.Sprintf("plugn trigger %s %v", triggerName, args))
return PlugnTriggerSetup(triggerName, args...).Run()
}
// PlugnTriggerOutput fire the given plugn trigger with the given args
//
// Deprecated: use CallPlugnTrigger with CaptureOutput=true instead
func PlugnTriggerOutput(triggerName string, args ...string) ([]byte, error) {
LogDebug(fmt.Sprintf("plugn trigger %s %v", triggerName, args))
rE, wE, _ := os.Pipe()
rO, wO, _ := os.Pipe()
session := PlugnTriggerSetup(triggerName, args...)
session.Stderr = wE
session.Stdout = wO
err := session.Run()
wE.Close()
wO.Close()
readStderr, _ := io.ReadAll(rE)
readStdout, _ := io.ReadAll(rO)
stderr := string(readStderr[:])
if err != nil {
err = fmt.Errorf(stderr)
}
if os.Getenv("DOKKU_TRACE") == "1" {
for _, line := range strings.Split(stderr, "\n") {
LogDebug(fmt.Sprintf("plugn trigger %s stderr: %s", triggerName, line))
}
for _, line := range strings.Split(string(readStdout[:]), "\n") {
LogDebug(fmt.Sprintf("plugn trigger %s stdout: %s", triggerName, line))
}
}
return readStdout, err
}
// PlugnTriggerOutputAsString fires the given plugn trigger with the given args and returns the string contents instead of bytes
//
// Deprecated: use CallPlugnTrigger with CaptureOutput=true instead
func PlugnTriggerOutputAsString(triggerName string, args ...string) (string, error) {
b, err := PlugnTriggerOutput(triggerName, args...)
return strings.TrimSpace(string(b[:])), err
}
// PlugnTriggerSetup sets up a plugn trigger call
//
// Deprecated: use CallPlugnTrigger instead
func PlugnTriggerSetup(triggerName string, args ...string) *sh.Session {
shellArgs := make([]interface{}, len(args)+2)
shellArgs[0] = "trigger"
shellArgs[1] = triggerName
for i, arg := range args {
shellArgs[i+2] = arg
}
return sh.Command("plugn", shellArgs...)
}
// PlugnTriggerExists returns whether a plugin trigger exists (ignoring the existence of any within the 20_events plugin) // PlugnTriggerExists returns whether a plugin trigger exists (ignoring the existence of any within the 20_events plugin)
func PlugnTriggerExists(triggerName string) bool { func PlugnTriggerExists(triggerName string) bool {
pluginPath := MustGetEnv("PLUGIN_PATH") pluginPath := MustGetEnv("PLUGIN_PATH")

View File

@@ -4,3 +4,4 @@
/triggers /triggers
/config-* /config-*
/config_sub /config_sub
/post-*

View File

@@ -1,6 +1,6 @@
GOARCH ?= amd64 GOARCH ?= amd64
SUBCOMMANDS = subcommands/bundle subcommands/clear subcommands/export subcommands/get subcommands/keys subcommands/show subcommands/set subcommands/unset SUBCOMMANDS = subcommands/bundle subcommands/clear subcommands/export subcommands/get subcommands/keys subcommands/show subcommands/set subcommands/unset
TRIGGERS = triggers/config-export triggers/config-get triggers/config-get-global TRIGGERS = triggers/config-export triggers/config-get triggers/config-get-global triggers/post-app-clone-setup triggers/post-app-rename-setup
BUILD = commands config_sub subcommands triggers BUILD = commands config_sub subcommands triggers
PLUGIN_NAME = config PLUGIN_NAME = config

View File

@@ -129,14 +129,24 @@ func UnsetAll(appName string, restart bool) (err error) {
func triggerRestart(appName string) { func triggerRestart(appName string) {
common.LogInfo1(fmt.Sprintf("Restarting app %s", appName)) common.LogInfo1(fmt.Sprintf("Restarting app %s", appName))
if err := common.PlugnTrigger("release-and-deploy", appName); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "release-and-deploy",
Args: []string{appName},
StreamStdio: true,
})
if err != nil {
common.LogWarn(fmt.Sprintf("Failure while restarting app: %s", err)) common.LogWarn(fmt.Sprintf("Failure while restarting app: %s", err))
} }
} }
func triggerUpdate(appName string, operation string, args []string) { func triggerUpdate(appName string, operation string, args []string) {
args = append([]string{appName, operation}, args...) args = append([]string{appName, operation}, args...)
if err := common.PlugnTrigger("post-config-update", args...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-config-update",
Args: args,
StreamStdio: true,
})
if err != nil {
common.LogWarn(fmt.Sprintf("Failure while triggering post-config-update: %s", err)) common.LogWarn(fmt.Sprintf("Failure while triggering post-config-update: %s", err))
} }
} }

View File

@@ -16,7 +16,7 @@ import (
"github.com/ryanuber/columnize" "github.com/ryanuber/columnize"
) )
//ExportFormat types of possible exports // ExportFormat types of possible exports
type ExportFormat int type ExportFormat int
const ( const (
@@ -40,14 +40,14 @@ const (
ExportFormatPackArgKeys ExportFormatPackArgKeys
) )
//Env is a representation for global or app environment // Env is a representation for global or app environment
type Env struct { type Env struct {
name string name string
filename string filename string
env map[string]string env map[string]string
} }
//newEnvFromString creates an env from the given ENVFILE contents representation // newEnvFromString creates an env from the given ENVFILE contents representation
func newEnvFromString(rep string) (env *Env, err error) { func newEnvFromString(rep string) (env *Env, err error) {
envMap, err := godotenv.Unmarshal(rep) envMap, err := godotenv.Unmarshal(rep)
env = &Env{ env = &Env{
@@ -58,7 +58,7 @@ func newEnvFromString(rep string) (env *Env, err error) {
return return
} }
//LoadAppEnv loads an environment for the given app // LoadAppEnv loads an environment for the given app
func LoadAppEnv(appName string) (env *Env, err error) { func LoadAppEnv(appName string) (env *Env, err error) {
appfile, err := getAppFile(appName) appfile, err := getAppFile(appName)
if err != nil { if err != nil {
@@ -67,7 +67,7 @@ func LoadAppEnv(appName string) (env *Env, err error) {
return loadFromFile(appName, appfile) return loadFromFile(appName, appfile)
} }
//LoadMergedAppEnv loads an app environment merged with the global environment // LoadMergedAppEnv loads an app environment merged with the global environment
func LoadMergedAppEnv(appName string) (env *Env, err error) { func LoadMergedAppEnv(appName string) (env *Env, err error) {
env, err = LoadAppEnv(appName) env, err = LoadAppEnv(appName)
if err != nil { if err != nil {
@@ -83,7 +83,7 @@ func LoadMergedAppEnv(appName string) (env *Env, err error) {
return global, err return global, err
} }
//LoadGlobalEnv loads the global environment // LoadGlobalEnv loads the global environment
func LoadGlobalEnv() (*Env, error) { func LoadGlobalEnv() (*Env, error) {
return loadFromFile("<global>", getGlobalFile()) return loadFromFile("<global>", getGlobalFile())
} }
@@ -93,13 +93,13 @@ func (e *Env) Filename() string {
return e.filename return e.filename
} }
//Get an environment variable // Get an environment variable
func (e *Env) Get(key string) (value string, ok bool) { func (e *Env) Get(key string) (value string, ok bool) {
value, ok = e.env[key] value, ok = e.env[key]
return return
} }
//GetDefault an environment variable or a default if it doesn't exist // GetDefault an environment variable or a default if it doesn't exist
func (e *Env) GetDefault(key string, defaultValue string) string { func (e *Env) GetDefault(key string, defaultValue string) string {
v, ok := e.env[key] v, ok := e.env[key]
if !ok { if !ok {
@@ -108,8 +108,8 @@ func (e *Env) GetDefault(key string, defaultValue string) string {
return v return v
} }
//GetBoolDefault gets the bool value of the given key with the given default // GetBoolDefault gets the bool value of the given key with the given default
//right now that is evaluated as `value != "0"` // right now that is evaluated as `value != "0"`
func (e *Env) GetBoolDefault(key string, defaultValue bool) bool { func (e *Env) GetBoolDefault(key string, defaultValue bool) bool {
v, ok := e.Get(key) v, ok := e.Get(key)
if !ok { if !ok {
@@ -118,17 +118,17 @@ func (e *Env) GetBoolDefault(key string, defaultValue bool) bool {
return v != "0" return v != "0"
} }
//Set an environment variable // Set an environment variable
func (e *Env) Set(key string, value string) { func (e *Env) Set(key string, value string) {
e.env[key] = value e.env[key] = value
} }
//Unset an environment variable // Unset an environment variable
func (e *Env) Unset(key string) { func (e *Env) Unset(key string) {
delete(e.env, key) delete(e.env, key)
} }
//Keys gets the keys in this environment // Keys gets the keys in this environment
func (e *Env) Keys() (keys []string) { func (e *Env) Keys() (keys []string) {
keys = make([]string, 0, len(e.env)) keys = make([]string, 0, len(e.env))
for k := range e.env { for k := range e.env {
@@ -138,12 +138,12 @@ func (e *Env) Keys() (keys []string) {
return return
} }
//Len returns the number of items in this environment // Len returns the number of items in this environment
func (e *Env) Len() int { func (e *Env) Len() int {
return len(e.env) return len(e.env)
} }
//Map returns the Env as a map // Map returns the Env as a map
func (e *Env) Map() map[string]string { func (e *Env) Map() map[string]string {
return e.env return e.env
} }
@@ -152,14 +152,14 @@ func (e *Env) String() string {
return e.EnvfileString() return e.EnvfileString()
} }
//Merge merges the given environment on top of the receiver // Merge merges the given environment on top of the receiver
func (e *Env) Merge(other *Env) { func (e *Env) Merge(other *Env) {
for _, k := range other.Keys() { for _, k := range other.Keys() {
e.Set(k, other.GetDefault(k, "")) e.Set(k, other.GetDefault(k, ""))
} }
} }
//Write an Env back to the file it was read from as an exportfile // Write an Env back to the file it was read from as an exportfile
func (e *Env) Write() error { func (e *Env) Write() error {
if e.filename == "" { if e.filename == "" {
return errors.New("this Env was created unbound to a file") return errors.New("this Env was created unbound to a file")
@@ -167,7 +167,7 @@ func (e *Env) Write() error {
return godotenv.Write(e.Map(), e.filename) return godotenv.Write(e.Map(), e.filename)
} }
//Export the Env in the given format // Export the Env in the given format
func (e *Env) Export(format ExportFormat) string { func (e *Env) Export(format ExportFormat) string {
switch format { switch format {
case ExportFormatExports: case ExportFormatExports:
@@ -194,23 +194,23 @@ func (e *Env) Export(format ExportFormat) string {
} }
} }
//EnvfileString returns the contents of this Env in dotenv format // EnvfileString returns the contents of this Env in dotenv format
func (e *Env) EnvfileString() string { func (e *Env) EnvfileString() string {
rep, _ := godotenv.Marshal(e.Map()) rep, _ := godotenv.Marshal(e.Map())
return rep return rep
} }
//ExportfileString returns the contents of this Env as bash exports // ExportfileString returns the contents of this Env as bash exports
func (e *Env) ExportfileString() string { func (e *Env) ExportfileString() string {
return e.stringWithPrefixAndSeparator("export ", "\n") return e.stringWithPrefixAndSeparator("export ", "\n")
} }
//DockerArgsString gets the contents of this Env in the form -env=KEY=VALUE --env... // DockerArgsString gets the contents of this Env in the form -env=KEY=VALUE --env...
func (e *Env) DockerArgsString() string { func (e *Env) DockerArgsString() string {
return e.stringWithPrefixAndSeparator("--env=", " ") return e.stringWithPrefixAndSeparator("--env=", " ")
} }
//DockerArgsKeysString gets the contents of this Env in the form -env=KEY --env... // DockerArgsKeysString gets the contents of this Env in the form -env=KEY --env...
func (e *Env) DockerArgsKeysString() string { func (e *Env) DockerArgsKeysString() string {
keys := e.Keys() keys := e.Keys()
entries := make([]string, len(keys)) entries := make([]string, len(keys))
@@ -220,7 +220,7 @@ func (e *Env) DockerArgsKeysString() string {
return strings.Join(entries, " ") return strings.Join(entries, " ")
} }
//JSONString returns the contents of this Env as a key/value json object // JSONString returns the contents of this Env as a key/value json object
func (e *Env) JSONString() string { func (e *Env) JSONString() string {
data, err := json.Marshal(e.Map()) data, err := json.Marshal(e.Map())
if err != nil { if err != nil {
@@ -230,7 +230,7 @@ func (e *Env) JSONString() string {
return string(data) return string(data)
} }
//JSONListString returns the contents of this Env as a json list of objects containing the name and the value of the env var // JSONListString returns the contents of this Env as a json list of objects containing the name and the value of the env var
func (e *Env) JSONListString() string { func (e *Env) JSONListString() string {
var list []map[string]string var list []map[string]string
for _, key := range e.Keys() { for _, key := range e.Keys() {
@@ -249,7 +249,7 @@ func (e *Env) JSONListString() string {
return string(data) return string(data)
} }
//PackArgKeysAsString gets the contents of this Env in the form -env KEY --env... // PackArgKeysAsString gets the contents of this Env in the form -env KEY --env...
func (e *Env) PackArgKeysAsString() string { func (e *Env) PackArgKeysAsString() string {
keys := e.Keys() keys := e.Keys()
entries := make([]string, len(keys)) entries := make([]string, len(keys))
@@ -259,13 +259,13 @@ func (e *Env) PackArgKeysAsString() string {
return strings.Join(entries, " ") return strings.Join(entries, " ")
} }
//ShellString gets the contents of this Env in the form "KEY='value' KEY2='value'" // ShellString gets the contents of this Env in the form "KEY='value' KEY2='value'"
// for passing the environment in the shell // for passing the environment in the shell
func (e *Env) ShellString() string { func (e *Env) ShellString() string {
return e.stringWithPrefixAndSeparator("", " ") return e.stringWithPrefixAndSeparator("", " ")
} }
//ExportBundle writes a tarfile of the environment to the given io.Writer. // ExportBundle writes a tarfile of the environment to the given io.Writer.
// for every environment variable there is a file with the variable's key // for every environment variable there is a file with the variable's key
// with its content set to the variable's value // with its content set to the variable's value
func (e *Env) ExportBundle(dest io.Writer) error { func (e *Env) ExportBundle(dest io.Writer) error {
@@ -287,7 +287,7 @@ func (e *Env) ExportBundle(dest io.Writer) error {
return nil return nil
} }
//stringWithPrefixAndSeparator makes a string of the environment // stringWithPrefixAndSeparator makes a string of the environment
// with the given prefix and separator for each entry // with the given prefix and separator for each entry
func (e *Env) stringWithPrefixAndSeparator(prefix string, separator string) string { func (e *Env) stringWithPrefixAndSeparator(prefix string, separator string) string {
keys := e.Keys() keys := e.Keys()
@@ -299,12 +299,12 @@ func (e *Env) stringWithPrefixAndSeparator(prefix string, separator string) stri
return strings.Join(entries, separator) return strings.Join(entries, separator)
} }
//singleQuoteEscape escapes the value as if it were shell-quoted in single quotes // singleQuoteEscape escapes the value as if it were shell-quoted in single quotes
func singleQuoteEscape(value string) string { // so that 'esc'aped' -> 'esc'\''aped' func singleQuoteEscape(value string) string { // so that 'esc'aped' -> 'esc'\''aped'
return strings.Replace(value, "'", "'\\''", -1) return strings.Replace(value, "'", "'\\''", -1)
} }
//prettyPrintEnvEntries in columns // prettyPrintEnvEntries in columns
func prettyPrintEnvEntries(prefix string, entries map[string]string) string { func prettyPrintEnvEntries(prefix string, entries map[string]string) string {
colConfig := columnize.DefaultConfig() colConfig := columnize.DefaultConfig()
colConfig.Prefix = prefix colConfig.Prefix = prefix

View File

@@ -12,8 +12,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -36,6 +36,14 @@ func main() {
case "config-get-global": case "config-get-global":
key := flag.Arg(0) key := flag.Arg(0)
err = config.TriggerConfigGetGlobal(key) err = config.TriggerConfigGetGlobal(key)
case "post-app-clone-setup":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = config.TriggerPostAppCloneSetup(oldAppName, newAppName)
case "post-app-rename-setup":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = config.TriggerPostAppRenameSetup(oldAppName, newAppName)
default: default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
} }

View File

@@ -44,3 +44,43 @@ func TriggerConfigGetGlobal(key string) error {
return nil return nil
} }
// TriggerPostAppCloneSetup creates new buildpacks files
func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
oldEnv, err := LoadAppEnv(oldAppName)
if err != nil {
return fmt.Errorf("Unable to load old environment: %s", err.Error())
}
newEnv, err := LoadAppEnv(newAppName)
if err != nil {
return fmt.Errorf("Unable to load new environment: %s", err.Error())
}
newEnv.Merge(oldEnv)
if err := newEnv.Write(); err != nil {
return fmt.Errorf("Unable to write new environment: %s", err.Error())
}
return nil
}
// TriggerPostAppRenameSetup renames buildpacks files
func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
oldEnv, err := LoadAppEnv(oldAppName)
if err != nil {
return fmt.Errorf("Unable to load old environment: %s", err.Error())
}
newEnv, err := LoadAppEnv(newAppName)
if err != nil {
return fmt.Errorf("Unable to load new environment: %s", err.Error())
}
newEnv.Merge(oldEnv)
if err := newEnv.Write(); err != nil {
return fmt.Errorf("Unable to write new environment: %s", err.Error())
}
return nil
}

View File

@@ -14,8 +14,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@@ -14,6 +14,7 @@ import (
func main() { func main() {
parts := strings.Split(os.Args[0], "/") parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1] trigger := parts[len(parts)-1]
global := flag.Bool("global", false, "--global: Whether global or app-specific")
flag.Parse() flag.Parse()
var err error var err error
@@ -21,6 +22,10 @@ func main() {
case "cron-get-property": case "cron-get-property":
appName := flag.Arg(0) appName := flag.Arg(0)
property := flag.Arg(1) property := flag.Arg(1)
if *global {
appName = "--global"
property = flag.Arg(0)
}
err = cron.TriggerCronGetProperty(appName, property) err = cron.TriggerCronGetProperty(appName, property)
case "install": case "install":
err = cron.TriggerInstall() err = cron.TriggerInstall()

View File

@@ -110,7 +110,12 @@ func CommandRun(appName string, cronID string, detached bool) error {
os.Setenv("DOKKU_RM_CONTAINER", "1") os.Setenv("DOKKU_RM_CONTAINER", "1")
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
args := append([]string{scheduler, appName, "0", "--"}, fields...) args := append([]string{scheduler, appName, "0", "--"}, fields...)
return common.PlugnTrigger("scheduler-run", args...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-run",
Args: args,
StreamStdio: true,
})
return err
} }
// CommandSet set or clear a cron property for an app // CommandSet set or clear a cron property for an app
@@ -120,5 +125,9 @@ func CommandSet(appName string, property string, value string) error {
} }
common.CommandPropertySet("cron", appName, property, value, DefaultProperties, GlobalProperties) common.CommandPropertySet("cron", appName, property, value, DefaultProperties, GlobalProperties)
return common.PlugnTrigger("cron-write") _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "cron-write",
StreamStdio: true,
})
return err
} }

View File

@@ -6,8 +6,6 @@ require github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/docker-options/functions"
trigger-docker-options-post-app-clone-setup() {
declare desc="copies docker options over"
declare trigger="post-app-clone-setup"
declare OLD_APP="$1" NEW_APP="$2"
declare -a phases
phases=("build" "deploy" "run")
for phase in "${phases[@]}"; do
if [[ -f "$(fn-get-phase-file-path "$OLD_APP" "$phase")" ]]; then
cp "$(fn-get-phase-file-path "$OLD_APP" "$phase")" "$(fn-get-phase-file-path "$NEW_APP" "$phase")"
fi
done
}
trigger-docker-options-post-app-clone-setup "$@"

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/docker-options/functions"
trigger-docker-options-post-app-rename-setup() {
declare desc="copies docker options over"
declare trigger="post-app-rename-setup"
declare OLD_APP="$1" NEW_APP="$2"
declare -a phases
phases=("build" "deploy" "run")
for phase in "${phases[@]}"; do
if [[ -f "$(fn-get-phase-file-path "$OLD_APP" "$phase")" ]]; then
cp "$(fn-get-phase-file-path "$OLD_APP" "$phase")" "$(fn-get-phase-file-path "$NEW_APP" "$phase")"
fi
done
}
trigger-docker-options-post-app-rename-setup "$@"

View File

@@ -7,9 +7,9 @@ trigger-domains-post-app-rename-setup() {
declare trigger="post-app-rename-setup" declare trigger="post-app-rename-setup"
declare OLD_APP="$1" NEW_APP="$2" declare OLD_APP="$1" NEW_APP="$2"
if [[ -f "$DOKKU_ROOT/$NEW_APP/VHOST" ]]; then if [[ -f "$DOKKU_ROOT/$OLD_APP/VHOST" ]]; then
while read -r VHOST || [[ -n "$VHOST" ]]; do while read -r VHOST || [[ -n "$VHOST" ]]; do
sed -i -e "s/$OLD_APP.$VHOST/$NEW_APP.$VHOST/g" "$DOKKU_ROOT/$NEW_APP/VHOST" sed -e "s/$OLD_APP.$VHOST/$NEW_APP.$VHOST/g" "$DOKKU_ROOT/$OLD_APP/VHOST" >"$DOKKU_ROOT/$NEW_APP/VHOST"
done <"$DOKKU_ROOT/VHOST" done <"$DOKKU_ROOT/VHOST"
fi fi
} }

View File

@@ -17,10 +17,9 @@ trigger-git-git-from-directory() {
local TMP_WORK_DIR_2=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") local TMP_WORK_DIR_2=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_WORK_DIR' '$TMP_WORK_DIR_2' >/dev/null" RETURN INT TERM EXIT trap "rm -rf '$TMP_WORK_DIR' '$TMP_WORK_DIR_2' >/dev/null" RETURN INT TERM EXIT
local has_code=true local has_code=false
local git_objects="$(fn-git-cmd "$APP_ROOT" count-objects 2>/dev/null || true)" if fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
if [[ -z "$git_objects" ]] || [[ "$git_objects" == "0 objects, 0 kilobytes" ]]; then has_code=true
local has_code=false
fi fi
dokku_log_info1 "Updating git repository with specified build context" dokku_log_info1 "Updating git repository with specified build context"

View File

@@ -38,7 +38,6 @@ fn-help-content() {
git:public-key, Outputs the dokku public deploy key git:public-key, Outputs the dokku public deploy key
git:report [<app>] [<flag>], Displays a git report for one or more apps git:report [<app>] [<flag>], Displays a git report for one or more apps
git:set <app> <property> (<value>), Set or clear a git property for an app git:set <app> <property> (<value>), Set or clear a git property for an app
git:unlock <app> [--force], Removes previous git clone folder for new deployment
git:status <app>, show the working tree status for an app git:status <app>, show the working tree status for an app
help_content help_content
} }

View File

@@ -179,6 +179,7 @@ cmd-git-sync() {
local cmd="git:sync" local cmd="git:sync"
[[ "$1" == "$cmd" ]] && shift 1 [[ "$1" == "$cmd" ]] && shift 1
declare APP GIT_REMOTE GIT_REF FLAG declare APP GIT_REMOTE GIT_REF FLAG
local CURRENT_REF DOKKU_DEPLOY_BRANCH SHOULD_BUILD UPDATED_REF
ARGS=() ARGS=()
for arg in "$@"; do for arg in "$@"; do
@@ -187,6 +188,11 @@ cmd-git-sync() {
continue continue
fi fi
if [[ "$arg" == "--build-if-changes" ]]; then
FLAG="--build-if-changes"
continue
fi
ARGS+=("$arg") ARGS+=("$arg")
done done
@@ -196,32 +202,37 @@ cmd-git-sync() {
verify_app_name "$APP" verify_app_name "$APP"
if [[ -d "$DOKKU_LIB_ROOT/data/git/$APP" ]]; then
if has_tty eq 0; then
cmd-git-unlock "$APP"
if [[ -d "$DOKKU_LIB_ROOT/data/git/$APP" ]]; then
dokku_log_fail "Failed to delete existing clone folder"
exit 15
fi
else
dokku_log_fail "Run 'git:unlock' to remove the existing temporary clone"
fi
fi
if [[ -z "$GIT_REMOTE" ]]; then if [[ -z "$GIT_REMOTE" ]]; then
dokku_log_fail "Missing GIT_REMOTE parameter" dokku_log_fail "Missing GIT_REMOTE parameter"
return return
fi fi
local APP_ROOT="$DOKKU_ROOT/$APP" local APP_ROOT="$DOKKU_ROOT/$APP"
if [[ "$(fn-git-cmd "$APP_ROOT" count-objects)" == "0 objects, 0 kilobytes" ]]; then DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
CURRENT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true)"
if ! fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
dokku_log_info1_quiet "Cloning $APP from $GIT_REMOTE#$GIT_REF" dokku_log_info1_quiet "Cloning $APP from $GIT_REMOTE#$GIT_REF"
fn-git-clone "$APP" "$GIT_REMOTE" "$GIT_REF" fn-git-clone "$APP" "$GIT_REMOTE" "$GIT_REF"
else else
dokku_log_verbose "Fetching remote code for $APP from $GIT_REMOTE#$GIT_REF"
fn-git-fetch "$APP" "$GIT_REMOTE" "$GIT_REF" fn-git-fetch "$APP" "$GIT_REMOTE" "$GIT_REF"
fi fi
UPDATED_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true)"
local SHOULD_BUILD=false
if [[ "$FLAG" == "--build" ]]; then if [[ "$FLAG" == "--build" ]]; then
SHOULD_BUILD=true
elif [[ "$FLAG" == "--build-if-changes" ]]; then
if [[ "$CURRENT_REF" == "$UPDATED_REF" ]]; then
dokku_log_verbose "Skipping build as no changes were detected"
return
fi
SHOULD_BUILD=true
fi
if [[ "$SHOULD_BUILD" == "true" ]]; then
if [[ -n "$GIT_REF" ]]; then if [[ -n "$GIT_REF" ]]; then
GIT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$GIT_REF")" GIT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$GIT_REF")"
plugn trigger receive-app "$APP" "$GIT_REF" plugn trigger receive-app "$APP" "$GIT_REF"
@@ -232,40 +243,6 @@ cmd-git-sync() {
fi fi
} }
cmd-git-unlock() {
declare desc="removes the clone folder for an app"
local cmd="git:unlock"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" FLAG
for arg in "$@"; do
if [[ "$arg" == "--force" ]]; then
FLAG="--force"
continue
fi
ARGS+=("$arg")
done
local APP_CLONE_ROOT="$DOKKU_LIB_ROOT/data/git/$APP"
if [[ -d "$APP_CLONE_ROOT" ]]; then
if [[ "$FLAG" == "--force" ]]; then
fn-git-remove-clone-folder "$APP_CLONE_ROOT"
else
read -rp "Are you sure that want to delete clone folder (y/n)?" choice
case "$choice" in
y | Y)
fn-git-remove-clone-folder "$APP_CLONE_ROOT"
;;
n | N) echo "no" ;;
*) echo "please answer with yes or no" ;;
esac
fi
else
dokku_log_info1 "No clone folder exists app already unlocked"
fi
}
cmd-git-public-key() { cmd-git-public-key() {
declare desc="outputs the dokku public deploy key" declare desc="outputs the dokku public deploy key"
local cmd="git:public-key" local cmd="git:public-key"
@@ -396,11 +373,11 @@ EOF
fn-git-clone() { fn-git-clone() {
declare desc="creates an app from remote git repo" declare desc="creates an app from remote git repo"
declare APP="$1" GIT_REMOTE="$2" GIT_REF="$3" declare APP="$1" GIT_REMOTE="$2" GIT_REF="$3"
local APP_CLONE_ROOT="$DOKKU_LIB_ROOT/data/git/$APP"
local APP_ROOT="$DOKKU_ROOT/$APP" local APP_ROOT="$DOKKU_ROOT/$APP"
[[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on" [[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ "$(fn-git-cmd "$APP_ROOT" count-objects)" != "0 objects, 0 kilobytes" ]]; then local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
if fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
dokku_log_fail "The clone subcommand can only be executed for new applications" dokku_log_fail "The clone subcommand can only be executed for new applications"
fi fi
@@ -408,20 +385,24 @@ fn-git-clone() {
GIT_REF="$(fn-git-deploy-branch "$APP")" GIT_REF="$(fn-git-deploy-branch "$APP")"
fi fi
trap "rm -rf '$APP_CLONE_ROOT' > /dev/null" RETURN INT TERM EXIT local TMP_IS_REF_DIR=$(mktemp -d "/tmp/dokku-ref-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_IS_REF_DIR' >/dev/null" RETURN INT TERM EXIT
is_ref=true is_ref=true
if GIT_TERMINAL_PROMPT=0 git clone --depth 1 -n --branch "$GIT_REF" "$GIT_REMOTE" "$APP_CLONE_ROOT" 2>/dev/null; then if GIT_TERMINAL_PROMPT=0 git clone --depth 1 -n --branch "$GIT_REF" "$GIT_REMOTE" "$TMP_IS_REF_DIR" 2>/dev/null; then
is_ref=false is_ref=false
fi fi
rm -rf "$APP_CLONE_ROOT" rm -rf "$TMP_IS_REF_DIR"
local TMP_CLONE_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
trap "rm -rf '$TMP_CLONE_DIR' >/dev/null" RETURN INT TERM EXIT
if [[ "$is_ref" == "true" ]]; then if [[ "$is_ref" == "true" ]]; then
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n "$GIT_REMOTE" "$APP_CLONE_ROOT" GIT_TERMINAL_PROMPT=0 suppress_output git clone -n "$GIT_REMOTE" "$TMP_CLONE_DIR"
fn-git-cmd "$APP_CLONE_ROOT" checkout -qq "$GIT_REF" fn-git-cmd "$TMP_CLONE_DIR" checkout -qq "$GIT_REF"
else else
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n --branch "$GIT_REF" "$GIT_REMOTE" "$APP_CLONE_ROOT" GIT_TERMINAL_PROMPT=0 suppress_output git clone -n --branch "$GIT_REF" "$GIT_REMOTE" "$TMP_CLONE_DIR"
if fn-git-cmd "$APP_CLONE_ROOT" show-ref --verify "refs/heads/$GIT_REF" &>/dev/null; then if fn-git-cmd "$TMP_CLONE_DIR" show-ref --verify "refs/heads/$GIT_REF" &>/dev/null; then
dokku_log_verbose "Detected branch, setting deploy-branch to $GIT_REF" dokku_log_verbose "Detected branch, setting deploy-branch to $GIT_REF"
fn-plugin-property-write "git" "$APP" "deploy-branch" "$GIT_REF" fn-plugin-property-write "git" "$APP" "deploy-branch" "$GIT_REF"
fi fi
@@ -430,13 +411,13 @@ fn-git-clone() {
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")" DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
if [[ "$GIT_REF" != "$DOKKU_DEPLOY_BRANCH" ]]; then if [[ "$GIT_REF" != "$DOKKU_DEPLOY_BRANCH" ]]; then
if [[ "$is_ref" == "true" ]]; then if [[ "$is_ref" == "true" ]]; then
fn-git-cmd "$APP_CLONE_ROOT" branch -qq -D "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true fn-git-cmd "$TMP_CLONE_DIR" branch -qq -D "$DOKKU_DEPLOY_BRANCH" 2>/dev/null || true
fi fi
fn-git-cmd "$APP_CLONE_ROOT" checkout -qq -b "$DOKKU_DEPLOY_BRANCH" fn-git-cmd "$TMP_CLONE_DIR" checkout -qq -b "$DOKKU_DEPLOY_BRANCH"
fi fi
rsync -a "$APP_CLONE_ROOT/.git/" "$APP_ROOT" rsync -a "$TMP_CLONE_DIR/.git/" "$APP_ROOT"
fn-git-create-hook "$APP" fn-git-create-hook "$APP"
fn-git-cmd "$APP_ROOT" config --add core.bare true fn-git-cmd "$APP_ROOT" config --add core.bare true
} }
@@ -458,7 +439,8 @@ fn-git-fetch() {
local DOKKU_DEPLOY_BRANCH local DOKKU_DEPLOY_BRANCH
local APP_ROOT="$DOKKU_ROOT/$APP" local APP_ROOT="$DOKKU_ROOT/$APP"
if [[ "$(fn-git-cmd "$APP_ROOT" count-objects)" == "0 objects, 0 kilobytes" ]]; then local DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
if ! fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
dokku_log_fail "The fetch subcommand can only be executed for existing applications" dokku_log_fail "The fetch subcommand can only be executed for existing applications"
fi fi

View File

@@ -7,8 +7,10 @@ trigger-git-post-delete() {
declare desc="destroys the git properties for a given app" declare desc="destroys the git properties for a given app"
declare trigger="post-delete" declare trigger="post-delete"
declare APP="$1" declare APP="$1"
local APP_CLONE_ROOT="$DOKKU_LIB_ROOT/data/git/$APP"
fn-plugin-property-destroy "git" "$APP" fn-plugin-property-destroy "git" "$APP"
rm -rf "$APP_CLONE_ROOT"
} }
trigger-git-post-delete "$@" trigger-git-post-delete "$@"

View File

@@ -11,8 +11,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -40,9 +40,11 @@ var templates embed.FS
// GetFailedLogs outputs failed deploy logs for a given app // GetFailedLogs outputs failed deploy logs for a given app
func GetFailedLogs(appName string) error { func GetFailedLogs(appName string) error {
common.LogInfo2Quiet(fmt.Sprintf("%s failed deploy logs", appName)) common.LogInfo2Quiet(fmt.Sprintf("%s failed deploy logs", appName))
s := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
if err := common.PlugnTrigger("scheduler-logs-failed", s, appName); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
return err Trigger: "scheduler-logs-failed",
} Args: []string{scheduler, appName},
return nil StreamStdio: true,
})
return err
} }

View File

@@ -134,7 +134,7 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
return common.CloneAppData("logs", oldAppName, newAppName) return common.CloneAppData("logs", oldAppName, newAppName)
} }
// TriggerPostCreate ensures apps the correct data directory structure // TriggerPostCreate ensures apps have the correct data directory structure
func TriggerPostCreate(appName string) error { func TriggerPostCreate(appName string) error {
return common.CreateAppDataDirectory("logs", appName) return common.CreateAppDataDirectory("logs", appName)
} }

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -43,12 +43,15 @@ func BuildConfig(appName string) error {
} }
appRoot := common.AppRoot(appName) appRoot := common.AppRoot(appName)
s, err := common.PlugnTriggerOutput("ps-current-scale", []string{appName}...) results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "ps-current-scale",
Args: []string{appName},
})
if err != nil { if err != nil {
return err return err
} }
scale, err := common.ParseScaleOutput(s) scale, err := common.ParseScaleOutput(results.StdoutBytes())
if err != nil { if err != nil {
return err return err
} }
@@ -78,7 +81,10 @@ func BuildConfig(appName string) error {
ipAddress := GetContainerIpaddress(appName, processType, containerID) ipAddress := GetContainerIpaddress(appName, processType, containerID)
if ipAddress != "" { if ipAddress != "" {
args := []string{appName, processType, containerIndexString, ipAddress} args := []string{appName, processType, containerIndexString, ipAddress}
_, err := common.PlugnTriggerOutput("network-write-ipaddr", args...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "network-write-ipaddr",
Args: args,
})
if err != nil { if err != nil {
common.LogWarn(err.Error()) common.LogWarn(err.Error())
} }

View File

@@ -40,7 +40,12 @@ func TriggerInstall() error {
if common.PropertyExists("network", appName, "bind-all-interfaces") { if common.PropertyExists("network", appName, "bind-all-interfaces") {
continue continue
} }
if err := common.PlugnTrigger("proxy-is-enabled", []string{appName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-is-enabled",
Args: []string{appName},
StreamStdio: true,
})
if err != nil {
common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to false") common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to false")
if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil { if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil {
common.LogWarn(err.Error()) common.LogWarn(err.Error())

View File

@@ -1 +1,2 @@
/pagesize /pagesize
/nginx-property

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -33,13 +33,19 @@ func clearPorts(appName string) error {
// doesCertExist checks if a cert exists for an app // doesCertExist checks if a cert exists for an app
func doesCertExist(appName string) bool { func doesCertExist(appName string) bool {
certsExists, _ := common.PlugnTriggerOutputAsString("certs-exists", []string{appName}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
if certsExists == "true" { Trigger: "certs-exists",
Args: []string{appName},
})
if results.StdoutContents() == "true" {
return true return true
} }
certsForce, _ := common.PlugnTriggerOutputAsString("certs-force", []string{appName}...) results, _ = common.CallPlugnTrigger(common.PlugnTriggerInput{
return certsForce == "true" Trigger: "certs-force",
Args: []string{appName},
})
return results.StdoutContents() == "true"
} }
// filterAppPortMaps filters the port mappings for an app // filterAppPortMaps filters the port mappings for an app
@@ -156,8 +162,11 @@ func getDetectedPortMaps(appName string) []PortMap {
// getGlobalProxyPort gets the global proxy port // getGlobalProxyPort gets the global proxy port
func getGlobalProxyPort() int { func getGlobalProxyPort() int {
port := 0 port := 0
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_PORT"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil { Trigger: "config-get-global",
Args: []string{"DOKKU_PROXY_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar port = intVar
} }
@@ -167,8 +176,11 @@ func getGlobalProxyPort() int {
// getGlobalProxySSLPort gets the global proxy ssl port // getGlobalProxySSLPort gets the global proxy ssl port
func getGlobalProxySSLPort() int { func getGlobalProxySSLPort() int {
port := 0 port := 0
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_SSL_PORT"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil { Trigger: "config-get-global",
Args: []string{"DOKKU_PROXY_SSL_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar port = intVar
} }
@@ -189,8 +201,11 @@ func getPortMaps(appName string) []PortMap {
// getProxyPort gets the proxy port for an app // getProxyPort gets the proxy port for an app
func getProxyPort(appName string) int { func getProxyPort(appName string) int {
port := 0 port := 0
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_PORT"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil { Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar port = intVar
} }
@@ -200,8 +215,11 @@ func getProxyPort(appName string) int {
// getProxySSLPort gets the proxy ssl port for an app // getProxySSLPort gets the proxy ssl port for an app
func getProxySSLPort(appName string) int { func getProxySSLPort(appName string) int {
port := 0 port := 0
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_SSL_PORT"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil { Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_SSL_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar port = intVar
} }
@@ -268,10 +286,12 @@ func inRange(value int, min int, max int) bool {
// isAppVhostEnabled checks if the app vhost is enabled // isAppVhostEnabled checks if the app vhost is enabled
func isAppVhostEnabled(appName string) bool { func isAppVhostEnabled(appName string) bool {
if err := common.PlugnTrigger("domains-vhost-enabled", []string{appName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
return false Trigger: "domains-vhost-enabled",
} Args: []string{appName},
return true StreamStdio: true,
})
return err == nil
} }
// listAppPortMaps lists the port mappings for an app // listAppPortMaps lists the port mappings for an app

View File

@@ -11,8 +11,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -46,7 +46,12 @@ func CommandAdd(appName string, portMapStrings []string) error {
return err return err
} }
return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "add"}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-proxy-ports-update",
Args: []string{appName, "add"},
StreamStdio: true,
})
return err
} }
// CommandClear clears all port mappings for an app // CommandClear clears all port mappings for an app
@@ -59,7 +64,12 @@ func CommandClear(appName string) error {
return err return err
} }
return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "clear"}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-proxy-ports-update",
Args: []string{appName, "clear"},
StreamStdio: true,
})
return err
} }
// CommandRemove removes specific port mappings from an app // CommandRemove removes specific port mappings from an app
@@ -81,7 +91,12 @@ func CommandRemove(appName string, portMapStrings []string) error {
return err return err
} }
return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "remove"}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-proxy-ports-update",
Args: []string{appName, "remove"},
StreamStdio: true,
})
return err
} }
// CommandSet sets port mappings for an app // CommandSet sets port mappings for an app
@@ -107,7 +122,12 @@ func CommandSet(appName string, portMapStrings []string) error {
return err return err
} }
return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "set"}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-proxy-ports-update",
Args: []string{appName, "set"},
StreamStdio: true,
})
return err
} }
// CommandReport displays a ports report for one or more apps // CommandReport displays a ports report for one or more apps

View File

@@ -10,8 +10,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -11,12 +11,22 @@ const RunInSerial = 0
// BuildConfig rebuilds the proxy config for the specified app // BuildConfig rebuilds the proxy config for the specified app
func BuildConfig(appName string) error { func BuildConfig(appName string) error {
return common.PlugnTrigger("proxy-build-config", []string{appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-build-config",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
// ClearConfig clears the proxy config for the specified app // ClearConfig clears the proxy config for the specified app
func ClearConfig(appName string) error { func ClearConfig(appName string) error {
return common.PlugnTrigger("proxy-clear-config", []string{appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-clear-config",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
// Disable disables proxy implementations for the specified app // Disable disables proxy implementations for the specified app
@@ -35,7 +45,12 @@ func Disable(appName string) error {
return err return err
} }
return common.PlugnTrigger("proxy-disable", []string{appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-disable",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
// Enable enables proxy implementations for the specified app // Enable enables proxy implementations for the specified app
@@ -50,8 +65,12 @@ func Enable(appName string) error {
if err := config.UnsetMany(appName, keys, false); err != nil { if err := config.UnsetMany(appName, keys, false); err != nil {
return err return err
} }
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
return common.PlugnTrigger("proxy-enable", []string{appName}...) Trigger: "proxy-enable",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
// IsAppProxyEnabled returns true if proxy is enabled; otherwise return false // IsAppProxyEnabled returns true if proxy is enabled; otherwise return false

View File

@@ -69,15 +69,21 @@ func getRestartPolicy(appName string) (string, error) {
func getProcessCount(appName string) (int, error) { func getProcessCount(appName string) (int, error) {
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
b, _ := common.PlugnTriggerOutput("scheduler-app-status", []string{scheduler, appName}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
count := strings.Split(strings.TrimSpace(string(b[:])), " ")[0] Trigger: "scheduler-app-status",
Args: []string{scheduler, appName},
})
count := strings.Split(results.StdoutContents(), " ")[0]
return strconv.Atoi(count) return strconv.Atoi(count)
} }
func getRunningState(appName string) string { func getRunningState(appName string) string {
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
b, _ := common.PlugnTriggerOutput("scheduler-app-status", []string{scheduler, appName}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
return strings.Split(strings.TrimSpace(string(b[:])), " ")[1] Trigger: "scheduler-app-status",
Args: []string{scheduler, appName},
})
return strings.Split(results.StdoutContents(), " ")[1]
} }
func hasProcfile(appName string) bool { func hasProcfile(appName string) bool {
@@ -204,7 +210,12 @@ func getFormations(appName string) (FormationSlice, error) {
} }
func restorePrep() error { func restorePrep() error {
if err := common.PlugnTrigger("proxy-clear-config", []string{"--all"}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-clear-config",
Args: []string{"--all"},
StreamStdio: true,
})
if err != nil {
return fmt.Errorf("Error clearing proxy config: %s", err) return fmt.Errorf("Error clearing proxy config: %s", err)
} }
@@ -260,7 +271,12 @@ func scaleSet(appName string, skipDeploy bool, clearExisting bool, processTuples
} }
for _, formation := range formations { for _, formation := range formations {
if err := common.PlugnTrigger("deploy", []string{appName, imageTag, formation.ProcessType}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "deploy",
Args: []string{appName, imageTag, formation.ProcessType},
StreamStdio: true,
})
if err != nil {
return err return err
} }
} }

View File

@@ -12,8 +12,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -2,7 +2,6 @@ package ps
import ( import (
"fmt" "fmt"
"strings"
"github.com/dokku/dokku/plugins/common" "github.com/dokku/dokku/plugins/common"
) )
@@ -69,7 +68,12 @@ func (d FormationSlice) Less(i, j int) bool {
// Rebuild rebuilds app from base image // Rebuild rebuilds app from base image
func Rebuild(appName string) error { func Rebuild(appName string) error {
return common.PlugnTrigger("receive-app", []string{appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "receive-app",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
// Restart restarts the app // Restart restarts the app
@@ -86,10 +90,20 @@ func Restart(appName string) error {
if imageTag == "" { if imageTag == "" {
common.LogWarn("No deployed-image-tag property saved, falling back to full release-and-deploy") common.LogWarn("No deployed-image-tag property saved, falling back to full release-and-deploy")
return common.PlugnTrigger("release-and-deploy", []string{appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "release-and-deploy",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
return common.PlugnTrigger("deploy", []string{appName, imageTag}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "deploy",
Args: []string{appName, imageTag},
StreamStdio: true,
})
return err
} }
// RestartProcess restarts a process type within an app // RestartProcess restarts a process type within an app
@@ -106,21 +120,41 @@ func RestartProcess(appName string, processName string) error {
if imageTag == "" { if imageTag == "" {
common.LogWarn("No deployed-image-tag property saved, falling back to full release-and-deploy") common.LogWarn("No deployed-image-tag property saved, falling back to full release-and-deploy")
return common.PlugnTrigger("release-and-deploy", []string{appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "release-and-deploy",
Args: []string{appName},
StreamStdio: true,
})
return err
} }
return common.PlugnTrigger("deploy", []string{appName, imageTag, processName}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "deploy",
Args: []string{appName, imageTag, processName},
StreamStdio: true,
})
return err
} }
// Restore ensures an app that should be running is running on boot // Restore ensures an app that should be running is running on boot
func Restore(appName string) error { func Restore(appName string) error {
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
if err := common.PlugnTrigger("scheduler-pre-restore", []string{scheduler, appName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-pre-restore",
Args: []string{scheduler, appName},
StreamStdio: true,
})
if err != nil {
return fmt.Errorf("Error running scheduler-pre-restore: %s", err) return fmt.Errorf("Error running scheduler-pre-restore: %s", err)
} }
common.LogInfo1("Clearing potentially invalid proxy configuration") common.LogInfo1("Clearing potentially invalid proxy configuration")
if err := common.PlugnTrigger("proxy-clear-config", []string{appName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-clear-config",
Args: []string{appName},
StreamStdio: true,
})
if err != nil {
common.LogWarn(fmt.Sprintf("Error clearing proxy config: %s", err)) common.LogWarn(fmt.Sprintf("Error clearing proxy config: %s", err))
} }
@@ -129,8 +163,11 @@ func Restore(appName string) error {
return nil return nil
} }
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_RESTORE"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
restore := strings.TrimSpace(string(b[:])) Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_RESTORE"},
})
restore := results.StdoutContents()
if restore == "0" { if restore == "0" {
common.LogWarn(fmt.Sprintf("Skipping ps:restore for %s as DOKKU_APP_RESTORE=%s", appName, restore)) common.LogWarn(fmt.Sprintf("Skipping ps:restore for %s as DOKKU_APP_RESTORE=%s", appName, restore))
return nil return nil
@@ -149,7 +186,12 @@ func Start(appName string) error {
return nil return nil
} }
if err := common.PlugnTrigger("pre-start", []string{appName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "pre-start",
Args: []string{appName},
StreamStdio: true,
})
if err != nil {
return fmt.Errorf("Failure in pre-start hook: %s", err) return fmt.Errorf("Failure in pre-start hook: %s", err)
} }
@@ -162,18 +204,24 @@ func Start(appName string) error {
} }
if runningState != "true" { if runningState != "true" {
if err := common.PlugnTrigger("release-and-deploy", []string{appName, imageTag}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "release-and-deploy",
Args: []string{appName, imageTag},
StreamStdio: true,
})
if err != nil {
return err return err
} }
} else { } else {
common.LogWarn(fmt.Sprintf("App %s already running", appName)) common.LogWarn(fmt.Sprintf("App %s already running", appName))
} }
if err := common.PlugnTrigger("proxy-build-config", []string{appName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
return err Trigger: "proxy-build-config",
} Args: []string{appName},
StreamStdio: true,
return nil })
return err
} }
// Stop stops the app // Stop stops the app
@@ -186,13 +234,19 @@ func Stop(appName string) error {
common.LogInfo1Quiet(fmt.Sprintf("Stopping %s", appName)) common.LogInfo1Quiet(fmt.Sprintf("Stopping %s", appName))
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
if err := common.PlugnTrigger("scheduler-stop", []string{scheduler, appName}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-stop",
Args: []string{scheduler, appName},
StreamStdio: true,
})
if err != nil {
return err return err
} }
if err := common.PlugnTrigger("post-stop", []string{appName}...); err != nil { _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
return err Trigger: "post-stop",
} Args: []string{appName},
StreamStdio: true,
return nil })
return err
} }

View File

@@ -129,8 +129,11 @@ func reportRestartPolicy(appName string) string {
} }
func reportRestore(appName string) string { func reportRestore(appName string) string {
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_RESTORE"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
restore := strings.TrimSpace(string(b[:])) Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_RESTORE"},
})
restore := results.StdoutContents()
if restore == "0" { if restore == "0" {
restore = "false" restore = "false"
} else { } else {

View File

@@ -18,7 +18,12 @@ func CommandInspect(appName string) error {
} }
scheduler := common.GetAppScheduler(appName) scheduler := common.GetAppScheduler(appName)
return common.PlugnTrigger("scheduler-inspect", []string{scheduler, appName}...) _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-inspect",
Args: []string{scheduler, appName},
StreamStdio: true,
})
return err
} }
// CommandRebuild rebuilds an app from source // CommandRebuild rebuilds an app from source
@@ -74,7 +79,11 @@ func CommandRestart(appName string, processName string, allApps bool, parallelCo
// CommandRestore starts previously running apps e.g. after reboot // CommandRestore starts previously running apps e.g. after reboot
func CommandRestore(appName string, allApps bool, parallelCount int) error { func CommandRestore(appName string, allApps bool, parallelCount int) error {
if err := common.PlugnTrigger("pre-restore", []string{}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "pre-restore",
StreamStdio: true,
})
if err != nil {
return fmt.Errorf("Error running pre-restore: %s", err) return fmt.Errorf("Error running pre-restore: %s", err)
} }
@@ -124,7 +133,12 @@ func CommandRetire(appName string) error {
} }
common.LogInfo1("Retiring old containers and images") common.LogInfo1("Retiring old containers and images")
return common.PlugnTrigger("scheduler-retire", []string{scheduler, appName}...) _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-retire",
Args: []string{scheduler, appName},
StreamStdio: true,
})
return err
} }
// CommandScale gets or sets how many instances of a given process to run // CommandScale gets or sets how many instances of a given process to run

View File

@@ -72,8 +72,11 @@ func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
} }
processSpecificProcfile := fmt.Sprintf("%s.%s", existingProcfile, os.Getenv("DOKKU_PID")) processSpecificProcfile := fmt.Sprintf("%s.%s", existingProcfile, os.Getenv("DOKKU_PID"))
b, _ := common.PlugnTriggerOutput("git-get-property", []string{appName, "source-image"}...) results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
appSourceImage := strings.TrimSpace(string(b[:])) Trigger: "git-get-property",
Args: []string{appName, "source-image"},
})
appSourceImage := results.StdoutContents()
repoDefaultProcfilePath := path.Join(sourceWorkDir, "Procfile") repoDefaultProcfilePath := path.Join(sourceWorkDir, "Procfile")
if appSourceImage == "" { if appSourceImage == "" {

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -90,7 +90,12 @@ func TriggerPostDelete(appName string) error {
func TriggerPostReleaseBuilder(appName string, image string) error { func TriggerPostReleaseBuilder(appName string, image string) error {
parts := strings.Split(image, ":") parts := strings.Split(image, ":")
imageTag := parts[len(parts)-1] imageTag := parts[len(parts)-1]
if err := common.PlugnTrigger("pre-deploy", []string{appName, imageTag}...); err != nil { _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "pre-deploy",
Args: []string{appName, imageTag},
StreamStdio: true,
})
if err != nil {
return err return err
} }

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -9,8 +9,6 @@ require (
require ( require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

View File

@@ -1,9 +1,5 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI= github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ= github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

Some files were not shown because too many files have changed in this diff Show More