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 }}
- name: Get changed files in the docs folder
id: changed-files-specific
uses: tj-actions/changed-files@v42.1.0
uses: tj-actions/changed-files@v43.0.0
with:
files: contrib/images/digitalocean/**
- name: Run `packer validate`

View File

@@ -75,9 +75,12 @@ go-clean:
fi ;\
done
copyfiles:
$(MAKE) go-build || exit 1
copydokku:
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}
rm -rf ${CORE_PLUGINS_PATH}/*
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
[[ "$CMD" =~ events*|plugin*|ssh-keys* ]] && 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 $@"
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="$?"
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

View File

@@ -3,7 +3,7 @@ click==8.1.7
ghp-import==2.1.0
importlib-metadata==7.0.2
Jinja2==3.1.3
Markdown>=3.2.1,<3.6
Markdown>=3.2.1,<3.7
MarkupSafe==2.1.5
mergedeep==1.3.4
mkdocs==1.5.3
@@ -20,4 +20,4 @@ pyyaml_env_tag==0.1
six==1.16.0
soupsieve==2.5
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: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: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:public-key # Outputs the dokku public deploy key
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: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:
@@ -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
```
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
> [!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.
### 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
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'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
dokku scheduler-k3s:initialize --ingress-class nginx
dokku scheduler-k3s:initialize --ingress-class traefik
```
### 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.
- [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.32](/docs/appendices/0.32.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.
### 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
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
```
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

19
dokku
View File

@@ -55,7 +55,7 @@ export DOKKU_SYSTEM_USER=${DOKKU_SYSTEM_USER:="dokku"}
export DOKKU_API_VERSION=1
export DOKKU_NOT_IMPLEMENTED_EXIT=10
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_HOST_DIR=${DOKKU_LOGS_HOST_DIR:=$DOKKU_LOGS_DIR}
@@ -88,8 +88,8 @@ fi
! has_tty && DOKKU_QUIET_OUTPUT=1
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
unset DOKKU_PID TMP TMPDIR TEMP TEMPDIR
export SSH_USER=$(id -un)
sudo -u dokku -E -H "$0" "$@"
exit $?
@@ -106,15 +106,20 @@ fi
if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then
export -n SSH_ORIGINAL_COMMAND
if [[ $1 =~ config-* ]] || [[ $1 =~ docker-options* ]]; then
xargs $0 <<<$SSH_ORIGINAL_COMMAND
exit $?
else
exit_code=0
if [[ $1 =~ git-* ]] || [[ $1 =~ git:* ]]; then
set -f
$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
exit $?
fi
exit $exit_code
fi
if ! dokku_auth "$@"; then

View File

@@ -17,6 +17,10 @@ cmd-report() {
dokku_log_info1 "uname: $(uname -a)"
dokku_log_info1 "memory: "
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: "
"$DOCKER_BIN" version | sed "s/^/ /"
dokku_log_info1 "docker daemon info: "

View File

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

View File

@@ -102,8 +102,11 @@ func getPhaseScript(appName string, phase string) (string, error) {
func getReleaseCommand(appName string, image string) string {
processType := "release"
port := "5000"
b, _ := common.PlugnTriggerOutput("procfile-get-command", []string{appName, processType, port}...)
return strings.TrimSpace(string(b[:]))
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "procfile-get-command",
Args: []string{appName, processType, port},
})
return results.StdoutContents()
}
func getDokkuAppShell(appName string) string {
@@ -114,13 +117,19 @@ func getDokkuAppShell(appName string) string {
ctx := context.Background()
errs, ctx := errgroup.WithContext(ctx)
errs.Go(func() error {
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_APP_SHELL"}...)
globalShell = strings.TrimSpace(string(b[:]))
results, _ := common.CallPlugnTriggerWithContext(ctx, common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_APP_SHELL"},
})
globalShell = results.StdoutContents()
return nil
})
errs.Go(func() error {
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_SHELL"}...)
appShell = strings.TrimSpace(string(b[:]))
results, _ := common.CallPlugnTriggerWithContext(ctx, common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_SHELL"},
})
appShell = results.StdoutContents()
return nil
})
@@ -204,8 +213,13 @@ func executeScript(appName string, image string, imageTag string, phase string)
}
var dockerArgs []string
if b, err := common.PlugnTriggerSetup("docker-args-deploy", []string{appName, imageTag}...).SetInput("").Output(); err == nil {
words, err := shellquote.Split(strings.TrimSpace(string(b[:])))
results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "docker-args-deploy",
Args: []string{appName, imageTag},
Stdin: strings.NewReader(""),
})
if err == nil {
words, err := shellquote.Split(results.StdoutContents())
if err != nil {
return err
}
@@ -213,8 +227,13 @@ func executeScript(appName string, image string, imageTag string, phase string)
dockerArgs = append(dockerArgs, words...)
}
if b, err := common.PlugnTriggerSetup("docker-args-process-deploy", []string{appName, imageSourceType, imageTag}...).SetInput("").Output(); err == nil {
words, err := shellquote.Split(strings.TrimSpace(string(b[:])))
results, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
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 {
return err
}
@@ -398,12 +417,15 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma
arguments = append(arguments, image)
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 {
return "", err
}
var env map[string]string
if err := json.Unmarshal(b, &env); err != nil {
if err := json.Unmarshal(results.StdoutBytes(), &env); err != nil {
return "", err
}
@@ -420,7 +442,11 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma
}
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
}
@@ -440,12 +466,27 @@ func setScale(appName string, image string) error {
}
if len(args) == 3 {
return common.PlugnTrigger("ps-can-scale", []string{appName, "true"}...)
}
if err := common.PlugnTrigger("ps-can-scale", []string{appName, "false"}...); err != nil {
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "ps-can-scale",
Args: []string{appName, "true"},
StreamStdio: true,
})
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 (
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/hashicorp/errwrap v1.0.0 // 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/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
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"))
b, _ := common.PlugnTriggerOutput("git-get-property", []string{appName, "source-image"}...)
appSourceImage := strings.TrimSpace(string(b[:]))
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "git-get-property",
Args: []string{appName, "source-image"},
})
appSourceImage := results.StdoutContents()
b, _ = common.PlugnTriggerOutput("builder-get-property", []string{appName, "build-dir"}...)
buildDir := strings.TrimSpace(string(b[:]))
results, _ = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "builder-get-property",
Args: []string{appName, "build-dir"},
})
buildDir := results.StdoutContents()
repoDefaultAppJSONPath := path.Join(sourceWorkDir, "app.json")
if appSourceImage == "" {
@@ -179,7 +185,7 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
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 {
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
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
PLUGIN_NAME = apps

View File

@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"os"
"strings"
"time"
"github.com/dokku/dokku/plugins/common"
@@ -17,8 +16,8 @@ func appExists(appName string) error {
// checks if an app is locked
func appIsLocked(appName string) bool {
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName))
_, err := os.Stat(lockfilePath)
lockPath := getLockPath(appName)
_, err := os.Stat(lockPath)
return !os.IsNotExist(err)
}
@@ -39,11 +38,12 @@ func createApp(appName string) error {
return err
}
if err := common.PlugnTrigger("post-create", []string{appName}...); err != nil {
return err
}
return nil
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-create",
Args: []string{appName},
StreamStdio: true,
})
return err
}
// destroys an app
@@ -57,19 +57,41 @@ func destroyApp(appName string) error {
common.LogInfo1(fmt.Sprintf("Destroying %s (including all add-ons)", 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
}
scheduler := common.GetAppScheduler(appName)
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
}
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
}
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
}
@@ -77,7 +99,12 @@ func destroyApp(appName string) error {
common.DockerCleanup(appName, forceCleanup)
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
}
@@ -94,14 +121,22 @@ func destroyApp(appName string) error {
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
func maybeCreateApp(appName string) error {
if err := appExists(appName); err == nil {
return nil
}
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_DISABLE_APP_AUTOCREATION"}...)
disableAutocreate := strings.TrimSpace(string(b[:]))
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_DISABLE_APP_AUTOCREATION"},
})
disableAutocreate := results.StdoutContents()
if disableAutocreate == "true" {
common.LogWarn("App auto-creation disabled.")
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 (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -41,10 +41,17 @@ func main() {
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
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":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
err = apps.TriggerPostAppRenameSetup(oldAppName, newAppName)
case "post-create":
appName := flag.Arg(0)
err = apps.TriggerPostCreate(appName)
case "post-delete":
appName := flag.Arg(0)
err = apps.TriggerPostDelete(appName)

View File

@@ -40,7 +40,12 @@ func CommandClone(oldAppName string, newAppName string, skipDeploy bool, ignoreE
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
}
@@ -48,15 +53,21 @@ func CommandClone(oldAppName string, newAppName string, skipDeploy bool, ignoreE
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")
}
if err := common.PlugnTrigger("post-app-clone", []string{oldAppName, newAppName}...); err != nil {
return err
}
return nil
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-app-clone",
Args: []string{oldAppName, newAppName},
StreamStdio: true,
})
return err
}
// CommandCreate creates app via command line
@@ -108,8 +119,8 @@ func CommandLock(appName string) error {
return err
}
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName))
if _, err := os.Create(lockfilePath); err != nil {
lockPath := getLockPath(appName)
if _, err := os.Create(lockPath); err != nil {
return errors.New("Unable to create deploy lock")
}
@@ -158,7 +169,12 @@ func CommandRename(oldAppName string, newAppName string, skipDeploy bool) error
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
}
@@ -171,15 +187,21 @@ func CommandRename(oldAppName string, newAppName string, skipDeploy bool) error
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")
}
if err := common.PlugnTrigger("post-app-rename", []string{oldAppName, newAppName}...); err != nil {
return err
}
return nil
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-app-rename",
Args: []string{oldAppName, newAppName},
StreamStdio: true,
})
return err
}
// CommandReport displays an app report for one or more apps
@@ -206,7 +228,7 @@ func CommandUnlock(appName string) error {
return err
}
lockfilePath := fmt.Sprintf("%v/.deploy.lock", common.AppRoot(appName))
lockfilePath := getLockPath(appName)
if _, err := os.Stat(lockfilePath); !os.IsNotExist(err) {
common.LogWarn("A deploy may be in progress.")
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())
}
if err := common.SetupAppData("apps"); err != nil {
return err
}
apps, err := common.UnfilteredDokkuApps()
if err != nil {
return nil
@@ -79,7 +83,12 @@ func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
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
@@ -92,14 +101,22 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
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 {
if err := common.PropertyDestroy("apps", appName); err != nil {
common.LogWarn(err.Error())
dataErr := common.RemoveAppDataDirectory("apps", appName)
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")
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"
return 1
fi

View File

@@ -1,4 +1,8 @@
ARG 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
RUN USER=$DOKKU_APP_USER /exec true
COPY --chown=$DOKKU_APP_USER . /app
WORKDIR /app
WORKDIR /app
ENV HEROKUISH_DISABLE_CHOWN true

View File

@@ -1,5 +1,5 @@
ARG APP_IMAGE
FROM $APP_IMAGE
COPY .env.d /tmp/env
COPY .env /app/.env
COPY --chown=$DOKKU_APP_USER .env.d /tmp/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 (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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) {
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-]+)$`)

View File

@@ -9,8 +9,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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
}
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_IMAGE"}...)
if dokkuImage := strings.TrimSpace(string(b[:])); dokkuImage != "" {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
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")
return dokkuImage
}

View File

@@ -65,7 +65,7 @@ func CommandRemove(appName string, buildpack string, index int) (err error) {
}
buildpack, err = validBuildpackURL(buildpack)
if err != nil {
if index == 0 && err != nil {
return err
}
@@ -149,7 +149,12 @@ func CommandSetProperty(appName string, property string, value string) error {
common.CommandPropertySet("buildpacks", appName, property, value, DefaultProperties, GlobalProperties)
if property == "stack" && oldStack != value {
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()
@@ -157,7 +162,12 @@ func CommandSetProperty(appName string, property string, value string) error {
return err
}
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
}
}

View File

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

View File

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

View File

@@ -182,9 +182,11 @@ func DockerCleanup(appName string, forceCleanup bool) error {
triggerArgs = []string{"DOKKU_SKIP_CLEANUP"}
}
b, _ := PlugnTriggerOutput(triggerName, triggerArgs...)
output := strings.TrimSpace(string(b[:]))
if output == "true" {
results, _ := CallPlugnTrigger(PlugnTriggerInput{
Trigger: triggerName,
Args: triggerArgs,
})
if results.StdoutContents() == "true" {
skipCleanup = true
}
}
@@ -309,9 +311,12 @@ func IsImageHerokuishBased(image string, appName string) bool {
dokkuAppUser := ""
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 {
dokkuAppUser = strings.TrimSpace(string(b))
dokkuAppUser = results.StdoutContents()
}
}

View File

@@ -77,6 +77,16 @@ func (ecr ExecCommandResponse) StderrContents() string {
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
func CallExecCommand(input ExecCommandInput) (ExecCommandResponse, error) {
ctx := context.Background()

View File

@@ -944,7 +944,7 @@ acquire_app_deploy_lock() {
declare desc="acquire advisory lock for use in deploys"
local APP="$1"
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_FAILED_MSG="$APP currently has a deploy lock in place. Exiting..."
@@ -954,7 +954,7 @@ acquire_app_deploy_lock() {
release_app_deploy_lock() {
declare desc="release advisory lock used in deploys"
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"
}
@@ -983,6 +983,7 @@ acquire_advisory_lock() {
dokku_log_fail "Run 'apps:unlock' to release the existing deploy lock"
fi
fi
echo "$DOKKU_PID" >"$LOCK_FILE"
}
release_advisory_lock() {
@@ -997,13 +998,14 @@ suppress_output() {
declare desc="suppress all output from a given command unless there is an error"
local TMP_COMMAND_OUTPUT
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 || {
local exit_code="$?"
cat "$TMP_COMMAND_OUTPUT"
rm -rf "$TMP_COMMAND_OUTPUT" >/dev/null
return "$exit_code"
}
rm -rf "$TMP_COMMAND_OUTPUT" >/dev/null
return 0
}

View File

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

View File

@@ -4,7 +4,6 @@ go 1.21
require (
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/hashicorp/go-multierror v1.1.1
github.com/melbahja/goph v1.4.0
@@ -17,7 +16,6 @@ require (
)
require (
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/errwrap v1.0.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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -1,158 +1,10 @@
package common
import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"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)
func PlugnTriggerExists(triggerName string) bool {
pluginPath := MustGetEnv("PLUGIN_PATH")

View File

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

View File

@@ -1,6 +1,6 @@
GOARCH ?= amd64
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
PLUGIN_NAME = config

View File

@@ -129,14 +129,24 @@ func UnsetAll(appName string, restart bool) (err error) {
func triggerRestart(appName string) {
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))
}
}
func triggerUpdate(appName string, operation string, args []string) {
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))
}
}

View File

@@ -16,7 +16,7 @@ import (
"github.com/ryanuber/columnize"
)
//ExportFormat types of possible exports
// ExportFormat types of possible exports
type ExportFormat int
const (
@@ -40,14 +40,14 @@ const (
ExportFormatPackArgKeys
)
//Env is a representation for global or app environment
// Env is a representation for global or app environment
type Env struct {
name string
filename 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) {
envMap, err := godotenv.Unmarshal(rep)
env = &Env{
@@ -58,7 +58,7 @@ func newEnvFromString(rep string) (env *Env, err error) {
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) {
appfile, err := getAppFile(appName)
if err != nil {
@@ -67,7 +67,7 @@ func LoadAppEnv(appName string) (env *Env, err error) {
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) {
env, err = LoadAppEnv(appName)
if err != nil {
@@ -83,7 +83,7 @@ func LoadMergedAppEnv(appName string) (env *Env, err error) {
return global, err
}
//LoadGlobalEnv loads the global environment
// LoadGlobalEnv loads the global environment
func LoadGlobalEnv() (*Env, error) {
return loadFromFile("<global>", getGlobalFile())
}
@@ -93,13 +93,13 @@ func (e *Env) Filename() string {
return e.filename
}
//Get an environment variable
// Get an environment variable
func (e *Env) Get(key string) (value string, ok bool) {
value, ok = e.env[key]
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 {
v, ok := e.env[key]
if !ok {
@@ -108,8 +108,8 @@ func (e *Env) GetDefault(key string, defaultValue string) string {
return v
}
//GetBoolDefault gets the bool value of the given key with the given default
//right now that is evaluated as `value != "0"`
// GetBoolDefault gets the bool value of the given key with the given default
// right now that is evaluated as `value != "0"`
func (e *Env) GetBoolDefault(key string, defaultValue bool) bool {
v, ok := e.Get(key)
if !ok {
@@ -118,17 +118,17 @@ func (e *Env) GetBoolDefault(key string, defaultValue bool) bool {
return v != "0"
}
//Set an environment variable
// Set an environment variable
func (e *Env) Set(key string, value string) {
e.env[key] = value
}
//Unset an environment variable
// Unset an environment variable
func (e *Env) Unset(key string) {
delete(e.env, key)
}
//Keys gets the keys in this environment
// Keys gets the keys in this environment
func (e *Env) Keys() (keys []string) {
keys = make([]string, 0, len(e.env))
for k := range e.env {
@@ -138,12 +138,12 @@ func (e *Env) Keys() (keys []string) {
return
}
//Len returns the number of items in this environment
// Len returns the number of items in this environment
func (e *Env) Len() int {
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 {
return e.env
}
@@ -152,14 +152,14 @@ func (e *Env) String() string {
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) {
for _, k := range other.Keys() {
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 {
if e.filename == "" {
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)
}
//Export the Env in the given format
// Export the Env in the given format
func (e *Env) Export(format ExportFormat) string {
switch format {
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 {
rep, _ := godotenv.Marshal(e.Map())
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 {
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 {
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 {
keys := e.Keys()
entries := make([]string, len(keys))
@@ -220,7 +220,7 @@ func (e *Env) DockerArgsKeysString() string {
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 {
data, err := json.Marshal(e.Map())
if err != nil {
@@ -230,7 +230,7 @@ func (e *Env) JSONString() string {
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 {
var list []map[string]string
for _, key := range e.Keys() {
@@ -249,7 +249,7 @@ func (e *Env) JSONListString() string {
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 {
keys := e.Keys()
entries := make([]string, len(keys))
@@ -259,13 +259,13 @@ func (e *Env) PackArgKeysAsString() string {
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
func (e *Env) ShellString() string {
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
// with its content set to the variable's value
func (e *Env) ExportBundle(dest io.Writer) error {
@@ -287,7 +287,7 @@ func (e *Env) ExportBundle(dest io.Writer) error {
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
func (e *Env) stringWithPrefixAndSeparator(prefix string, separator string) string {
keys := e.Keys()
@@ -299,12 +299,12 @@ func (e *Env) stringWithPrefixAndSeparator(prefix string, separator string) stri
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'
return strings.Replace(value, "'", "'\\''", -1)
}
//prettyPrintEnvEntries in columns
// prettyPrintEnvEntries in columns
func prettyPrintEnvEntries(prefix string, entries map[string]string) string {
colConfig := columnize.DefaultConfig()
colConfig.Prefix = prefix

View File

@@ -12,8 +12,6 @@ require (
require (
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/google/go-cmp v0.6.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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -36,6 +36,14 @@ func main() {
case "config-get-global":
key := flag.Arg(0)
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:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}

View File

@@ -44,3 +44,43 @@ func TriggerConfigGetGlobal(key string) error {
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 (
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/hashicorp/errwrap v1.0.0 // 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/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

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

View File

@@ -110,7 +110,12 @@ func CommandRun(appName string, cronID string, detached bool) error {
os.Setenv("DOKKU_RM_CONTAINER", "1")
scheduler := common.GetAppScheduler(appName)
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
@@ -120,5 +125,9 @@ func CommandSet(appName string, property string, value string) error {
}
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 (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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 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
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"
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")
trap "rm -rf '$TMP_WORK_DIR' '$TMP_WORK_DIR_2' >/dev/null" RETURN INT TERM EXIT
local has_code=true
local git_objects="$(fn-git-cmd "$APP_ROOT" count-objects 2>/dev/null || true)"
if [[ -z "$git_objects" ]] || [[ "$git_objects" == "0 objects, 0 kilobytes" ]]; then
local has_code=false
local has_code=false
if fn-git-cmd "$APP_ROOT" rev-parse "$DOKKU_DEPLOY_BRANCH" >/dev/null 2>&1; then
has_code=true
fi
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: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:unlock <app> [--force], Removes previous git clone folder for new deployment
git:status <app>, show the working tree status for an app
help_content
}

View File

@@ -179,6 +179,7 @@ cmd-git-sync() {
local cmd="git:sync"
[[ "$1" == "$cmd" ]] && shift 1
declare APP GIT_REMOTE GIT_REF FLAG
local CURRENT_REF DOKKU_DEPLOY_BRANCH SHOULD_BUILD UPDATED_REF
ARGS=()
for arg in "$@"; do
@@ -187,6 +188,11 @@ cmd-git-sync() {
continue
fi
if [[ "$arg" == "--build-if-changes" ]]; then
FLAG="--build-if-changes"
continue
fi
ARGS+=("$arg")
done
@@ -196,32 +202,37 @@ cmd-git-sync() {
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
dokku_log_fail "Missing GIT_REMOTE parameter"
return
fi
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"
fn-git-clone "$APP" "$GIT_REMOTE" "$GIT_REF"
else
dokku_log_verbose "Fetching remote code for $APP from $GIT_REMOTE#$GIT_REF"
fn-git-fetch "$APP" "$GIT_REMOTE" "$GIT_REF"
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
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
GIT_REF="$(fn-git-cmd "$APP_ROOT" rev-parse "$GIT_REF")"
plugn trigger receive-app "$APP" "$GIT_REF"
@@ -232,40 +243,6 @@ cmd-git-sync() {
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() {
declare desc="outputs the dokku public deploy key"
local cmd="git:public-key"
@@ -396,11 +373,11 @@ EOF
fn-git-clone() {
declare desc="creates an app from remote git repo"
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"
[[ -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"
fi
@@ -408,20 +385,24 @@ fn-git-clone() {
GIT_REF="$(fn-git-deploy-branch "$APP")"
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
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
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
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n "$GIT_REMOTE" "$APP_CLONE_ROOT"
fn-git-cmd "$APP_CLONE_ROOT" checkout -qq "$GIT_REF"
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n "$GIT_REMOTE" "$TMP_CLONE_DIR"
fn-git-cmd "$TMP_CLONE_DIR" checkout -qq "$GIT_REF"
else
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n --branch "$GIT_REF" "$GIT_REMOTE" "$APP_CLONE_ROOT"
if fn-git-cmd "$APP_CLONE_ROOT" show-ref --verify "refs/heads/$GIT_REF" &>/dev/null; then
GIT_TERMINAL_PROMPT=0 suppress_output git clone -n --branch "$GIT_REF" "$GIT_REMOTE" "$TMP_CLONE_DIR"
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"
fn-plugin-property-write "git" "$APP" "deploy-branch" "$GIT_REF"
fi
@@ -430,13 +411,13 @@ fn-git-clone() {
DOKKU_DEPLOY_BRANCH="$(fn-git-deploy-branch "$APP")"
if [[ "$GIT_REF" != "$DOKKU_DEPLOY_BRANCH" ]]; 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
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
rsync -a "$APP_CLONE_ROOT/.git/" "$APP_ROOT"
rsync -a "$TMP_CLONE_DIR/.git/" "$APP_ROOT"
fn-git-create-hook "$APP"
fn-git-cmd "$APP_ROOT" config --add core.bare true
}
@@ -458,7 +439,8 @@ fn-git-fetch() {
local DOKKU_DEPLOY_BRANCH
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"
fi

View File

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

View File

@@ -11,8 +11,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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
func GetFailedLogs(appName string) error {
common.LogInfo2Quiet(fmt.Sprintf("%s failed deploy logs", appName))
s := common.GetAppScheduler(appName)
if err := common.PlugnTrigger("scheduler-logs-failed", s, appName); err != nil {
return err
}
return nil
scheduler := common.GetAppScheduler(appName)
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-logs-failed",
Args: []string{scheduler, appName},
StreamStdio: true,
})
return err
}

View File

@@ -134,7 +134,7 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
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 {
return common.CreateAppDataDirectory("logs", appName)
}

View File

@@ -9,8 +9,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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)
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 {
return err
}
scale, err := common.ParseScaleOutput(s)
scale, err := common.ParseScaleOutput(results.StdoutBytes())
if err != nil {
return err
}
@@ -78,7 +81,10 @@ func BuildConfig(appName string) error {
ipAddress := GetContainerIpaddress(appName, processType, containerID)
if 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 {
common.LogWarn(err.Error())
}

View File

@@ -40,7 +40,12 @@ func TriggerInstall() error {
if common.PropertyExists("network", appName, "bind-all-interfaces") {
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")
if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil {
common.LogWarn(err.Error())

View File

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

View File

@@ -9,8 +9,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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
func doesCertExist(appName string) bool {
certsExists, _ := common.PlugnTriggerOutputAsString("certs-exists", []string{appName}...)
if certsExists == "true" {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "certs-exists",
Args: []string{appName},
})
if results.StdoutContents() == "true" {
return true
}
certsForce, _ := common.PlugnTriggerOutputAsString("certs-force", []string{appName}...)
return certsForce == "true"
results, _ = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "certs-force",
Args: []string{appName},
})
return results.StdoutContents() == "true"
}
// filterAppPortMaps filters the port mappings for an app
@@ -156,8 +162,11 @@ func getDetectedPortMaps(appName string) []PortMap {
// getGlobalProxyPort gets the global proxy port
func getGlobalProxyPort() int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_PROXY_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar
}
@@ -167,8 +176,11 @@ func getGlobalProxyPort() int {
// getGlobalProxySSLPort gets the global proxy ssl port
func getGlobalProxySSLPort() int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_SSL_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_PROXY_SSL_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar
}
@@ -189,8 +201,11 @@ func getPortMaps(appName string) []PortMap {
// getProxyPort gets the proxy port for an app
func getProxyPort(appName string) int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar
}
@@ -200,8 +215,11 @@ func getProxyPort(appName string) int {
// getProxySSLPort gets the proxy ssl port for an app
func getProxySSLPort(appName string) int {
port := 0
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_SSL_PORT"}...)
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_SSL_PORT"},
})
if intVar, err := strconv.Atoi(results.StdoutContents()); err == nil {
port = intVar
}
@@ -268,10 +286,12 @@ func inRange(value int, min int, max int) bool {
// isAppVhostEnabled checks if the app vhost is enabled
func isAppVhostEnabled(appName string) bool {
if err := common.PlugnTrigger("domains-vhost-enabled", []string{appName}...); err != nil {
return false
}
return true
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "domains-vhost-enabled",
Args: []string{appName},
StreamStdio: true,
})
return err == nil
}
// listAppPortMaps lists the port mappings for an app

View File

@@ -11,8 +11,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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 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
@@ -59,7 +64,12 @@ func CommandClear(appName string) error {
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
@@ -81,7 +91,12 @@ func CommandRemove(appName string, portMapStrings []string) error {
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
@@ -107,7 +122,12 @@ func CommandSet(appName string, portMapStrings []string) error {
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

View File

@@ -10,8 +10,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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
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
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
@@ -35,7 +45,12 @@ func Disable(appName string) error {
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
@@ -50,8 +65,12 @@ func Enable(appName string) error {
if err := config.UnsetMany(appName, keys, false); err != nil {
return err
}
return common.PlugnTrigger("proxy-enable", []string{appName}...)
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-enable",
Args: []string{appName},
StreamStdio: true,
})
return err
}
// 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) {
scheduler := common.GetAppScheduler(appName)
b, _ := common.PlugnTriggerOutput("scheduler-app-status", []string{scheduler, appName}...)
count := strings.Split(strings.TrimSpace(string(b[:])), " ")[0]
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-app-status",
Args: []string{scheduler, appName},
})
count := strings.Split(results.StdoutContents(), " ")[0]
return strconv.Atoi(count)
}
func getRunningState(appName string) string {
scheduler := common.GetAppScheduler(appName)
b, _ := common.PlugnTriggerOutput("scheduler-app-status", []string{scheduler, appName}...)
return strings.Split(strings.TrimSpace(string(b[:])), " ")[1]
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "scheduler-app-status",
Args: []string{scheduler, appName},
})
return strings.Split(results.StdoutContents(), " ")[1]
}
func hasProcfile(appName string) bool {
@@ -204,7 +210,12 @@ func getFormations(appName string) (FormationSlice, 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)
}
@@ -260,7 +271,12 @@ func scaleSet(appName string, skipDeploy bool, clearExisting bool, processTuples
}
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
}
}

View File

@@ -12,8 +12,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -2,7 +2,6 @@ package ps
import (
"fmt"
"strings"
"github.com/dokku/dokku/plugins/common"
)
@@ -69,7 +68,12 @@ func (d FormationSlice) Less(i, j int) bool {
// Rebuild rebuilds app from base image
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
@@ -86,10 +90,20 @@ func Restart(appName string) error {
if imageTag == "" {
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
@@ -106,21 +120,41 @@ func RestartProcess(appName string, processName string) error {
if imageTag == "" {
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
func Restore(appName string) error {
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)
}
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))
}
@@ -129,8 +163,11 @@ func Restore(appName string) error {
return nil
}
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_APP_RESTORE"}...)
restore := strings.TrimSpace(string(b[:]))
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_APP_RESTORE"},
})
restore := results.StdoutContents()
if restore == "0" {
common.LogWarn(fmt.Sprintf("Skipping ps:restore for %s as DOKKU_APP_RESTORE=%s", appName, restore))
return nil
@@ -149,7 +186,12 @@ func Start(appName string) error {
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)
}
@@ -162,18 +204,24 @@ func Start(appName string) error {
}
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
}
} else {
common.LogWarn(fmt.Sprintf("App %s already running", appName))
}
if err := common.PlugnTrigger("proxy-build-config", []string{appName}...); err != nil {
return err
}
return nil
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "proxy-build-config",
Args: []string{appName},
StreamStdio: true,
})
return err
}
// Stop stops the app
@@ -186,13 +234,19 @@ func Stop(appName string) error {
common.LogInfo1Quiet(fmt.Sprintf("Stopping %s", 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
}
if err := common.PlugnTrigger("post-stop", []string{appName}...); err != nil {
return err
}
return nil
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "post-stop",
Args: []string{appName},
StreamStdio: true,
})
return err
}

View File

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

View File

@@ -18,7 +18,12 @@ func CommandInspect(appName string) error {
}
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
@@ -74,7 +79,11 @@ func CommandRestart(appName string, processName string, allApps bool, parallelCo
// CommandRestore starts previously running apps e.g. after reboot
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)
}
@@ -124,7 +133,12 @@ func CommandRetire(appName string) error {
}
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

View File

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

View File

@@ -9,8 +9,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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 {
parts := strings.Split(image, ":")
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
}

View File

@@ -9,8 +9,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=

View File

@@ -9,8 +9,6 @@ require (
require (
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/hashicorp/errwrap v1.0.0 // 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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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