mirror of
https://github.com/dokku/dokku.git
synced 2025-12-29 00:25:08 +01:00
Merge pull request #4765 from dokku/2184-process-type-restarts
Allow specifying a single process type to restart
This commit is contained in:
@@ -428,6 +428,24 @@ case "$DOKKU_DISTRO" in
|
||||
esac
|
||||
```
|
||||
|
||||
### `deploy`
|
||||
|
||||
- Description: Triggers a deploy for the given app. Can override the image tag to deploy, as well as specify a single process type to deploy.
|
||||
- Invoked by: `dokku deploy`
|
||||
- Arguments: `$APP [$IMAGE_TAG] [$PROC_TYPE]`
|
||||
- Example:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
|
||||
APP="$1" IMAGE_TAG="$2" PROC_TYPE="$3"
|
||||
|
||||
# TODO
|
||||
```
|
||||
|
||||
### `deploy-source`
|
||||
|
||||
- Description: Used for reporting what the current detected deployment source is. The first detected source should always win.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
ps:inspect <app> # Displays a sanitized version of docker inspect for an app
|
||||
ps:rebuild [--parallel count] [--all|<app>] # Rebuilds an app from source
|
||||
ps:report [<app>] [<flag>] # Displays a process report for one or more apps
|
||||
ps:restart [--parallel count] [--all|<app>] # Restart an app
|
||||
ps:restart [--parallel count] [--all|<app>] [<process-name>] # Restart an app
|
||||
ps:restore [<app>] # Start previously running apps e.g. after reboot
|
||||
ps:scale [--skip-deploy] <app> <proc>=<count> [<proc>=<count>...] # Get/Set how many instances of a given process to run
|
||||
ps:set <app> <key> <value> # Set or clear a ps property for an app
|
||||
@@ -64,7 +64,13 @@ An app may be restarted using the `ps:restart` command.
|
||||
dokku ps:restart node-js-app
|
||||
```
|
||||
|
||||
All apps may be restarted by using the `--all` flag.
|
||||
A single process type - such as `web` or `worker` - may also be specified. This _does not_ support specifying a given instance of a process type, and only supports restarting all instances of that process type.
|
||||
|
||||
```shell
|
||||
dokku ps:restart node-js-app web
|
||||
```
|
||||
|
||||
All apps may be restarted by using the `--all` flag. This flag is incompatible with specifying a process type.
|
||||
|
||||
```shell
|
||||
dokku ps:restart --all
|
||||
|
||||
@@ -52,7 +52,7 @@ func destroyApp(appName string) error {
|
||||
|
||||
common.LogInfo1(fmt.Sprintf("Destroying %s (including all add-ons)", appName))
|
||||
|
||||
imageTag, _ := common.GetRunningImageTag(appName)
|
||||
imageTag, _ := common.GetRunningImageTag(appName, "")
|
||||
if err := common.PlugnTrigger("pre-delete", []string{appName, imageTag}...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -226,20 +226,21 @@ func GetAppRunningContainerIDs(appName string, containerType string) ([]string,
|
||||
return runningContainerIDs, nil
|
||||
}
|
||||
|
||||
// GetRunningImageTag retrieves current image tag for a given app and returns empty string if no deployed containers are found
|
||||
func GetRunningImageTag(appName string) (string, error) {
|
||||
containerIDs, err := GetAppContainerIDs(appName, "")
|
||||
// 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}...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return imageTag, err
|
||||
}
|
||||
newImageTag := strings.TrimSpace(string(b[:]))
|
||||
if newImageTag != "" {
|
||||
imageTag = newImageTag
|
||||
}
|
||||
if imageTag == "" {
|
||||
imageTag = "latest"
|
||||
}
|
||||
|
||||
for _, containerID := range containerIDs {
|
||||
if image, err := DockerInspect(containerID, "{{ .Config.Image }}"); err == nil {
|
||||
return strings.Split(image, ":")[1], nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("No image tag found")
|
||||
return imageTag, nil
|
||||
}
|
||||
|
||||
// DokkuApps returns a list of all local apps
|
||||
|
||||
6
plugins/common/deploy
Executable file
6
plugins/common/deploy
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-deploy "$@"
|
||||
@@ -286,16 +286,14 @@ get_deploying_app_image_name() {
|
||||
declare desc="return deploying image identifier for a given app, tag tuple. validate if tag is presented"
|
||||
local APP="$1"
|
||||
local IMAGE_TAG="$2"
|
||||
IMAGE_REPO="$3"
|
||||
local IMAGE_REPO="$3"
|
||||
|
||||
IMAGE_TAG="$(get_running_image_tag "$APP" "$IMAGE_TAG")"
|
||||
local IMAGE_REMOTE_REPOSITORY=$(plugn trigger deployed-app-repository "$APP")
|
||||
local NEW_IMAGE_TAG=$(plugn trigger deployed-app-image-tag "$APP")
|
||||
local NEW_IMAGE_REPO=$(plugn trigger deployed-app-image-repo "$APP")
|
||||
|
||||
[[ -n "$NEW_IMAGE_REPO" ]] && IMAGE_REPO="$NEW_IMAGE_REPO"
|
||||
[[ -n "$NEW_IMAGE_TAG" ]] && IMAGE_TAG="$NEW_IMAGE_TAG"
|
||||
[[ -z "$IMAGE_REPO" ]] && IMAGE_REPO=$(get_app_image_repo "$APP")
|
||||
[[ -z "$IMAGE_TAG" ]] && IMAGE_TAG="latest"
|
||||
|
||||
local IMAGE="${IMAGE_REMOTE_REPOSITORY}${IMAGE_REPO}:${IMAGE_TAG}"
|
||||
verify_image "$IMAGE" || dokku_log_fail "App image ($IMAGE) not found"
|
||||
@@ -329,12 +327,14 @@ get_app_scheduler() {
|
||||
}
|
||||
|
||||
get_running_image_tag() {
|
||||
declare desc="retrieve current image tag for a given app. returns empty string if no deployed containers are found"
|
||||
local APP="$1"
|
||||
declare desc="retrieves current deployed image tag for a given app"
|
||||
local APP="$1" IMAGE_TAG="$2"
|
||||
|
||||
local CIDS=($(get_app_container_ids "$APP"))
|
||||
local RUNNING_IMAGE_TAG=$("$DOCKER_BIN" container inspect --format '{{ .Config.Image }}' "${CIDS[0]}" 2>/dev/null | awk -F: '{ print $2 }' || echo '')
|
||||
echo "$RUNNING_IMAGE_TAG"
|
||||
local NEW_IMAGE_TAG=$(plugn trigger deployed-app-image-tag "$APP")
|
||||
[[ -n "$NEW_IMAGE_TAG" ]] && IMAGE_TAG="$NEW_IMAGE_TAG"
|
||||
[[ -z "$IMAGE_TAG" ]] && IMAGE_TAG="latest"
|
||||
|
||||
echo "$IMAGE_TAG"
|
||||
}
|
||||
|
||||
is_image_cnb_based() {
|
||||
@@ -638,12 +638,11 @@ dokku_release() {
|
||||
|
||||
cmd-deploy() {
|
||||
declare desc="deploy phase"
|
||||
declare APP="$1" IMAGE_TAG="$2"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
declare APP="$1" IMAGE_TAG="$2" PROCESS_TYPE="$3"
|
||||
|
||||
verify_app_name "$APP"
|
||||
local DOKKU_SCHEDULER=$(get_app_scheduler "$APP")
|
||||
plugn trigger scheduler-deploy "$DOKKU_SCHEDULER" "$APP" "$IMAGE_TAG"
|
||||
plugn trigger scheduler-deploy "$DOKKU_SCHEDULER" "$APP" "$IMAGE_TAG" "$PROCESS_TYPE"
|
||||
}
|
||||
|
||||
release_and_deploy() {
|
||||
|
||||
@@ -117,7 +117,7 @@ func UnsetAll(appName string, restart bool) (err error) {
|
||||
|
||||
func triggerRestart(appName string) {
|
||||
common.LogInfo1(fmt.Sprintf("Restarting app %s", appName))
|
||||
if err := common.PlugnTrigger("app-restart", appName); err != nil {
|
||||
if err := common.PlugnTrigger("release-and-deploy", appName); err != nil {
|
||||
common.LogWarn(fmt.Sprintf("Failure while restarting app: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,12 +282,18 @@ func scaleSet(appName string, skipDeploy bool, clearExisting bool, processTuples
|
||||
return nil
|
||||
}
|
||||
|
||||
imageTag, err := common.GetRunningImageTag(appName)
|
||||
imageTag, err := common.GetRunningImageTag(appName, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return common.PlugnTrigger("release-and-deploy", []string{appName, imageTag}...)
|
||||
for _, formation := range formations {
|
||||
if err := common.PlugnTrigger("deploy", []string{appName, imageTag, formation.ProcessType}...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateScale(appName string, clearExisting bool, formationUpdates FormationSlice) error {
|
||||
|
||||
@@ -57,7 +57,37 @@ func Restart(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return common.PlugnTrigger("release-and-deploy", []string{appName}...)
|
||||
imageTag, err := common.GetRunningImageTag(appName, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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}...)
|
||||
}
|
||||
|
||||
return common.PlugnTrigger("deploy", []string{appName, imageTag}...)
|
||||
}
|
||||
|
||||
// RestartProcess restarts a process type within an app
|
||||
func RestartProcess(appName string, processName string) error {
|
||||
if !common.IsDeployed(appName) {
|
||||
common.LogWarn(fmt.Sprintf("App %s has not been deployed", appName))
|
||||
return nil
|
||||
}
|
||||
|
||||
imageTag, err := common.GetRunningImageTag(appName, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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}...)
|
||||
}
|
||||
|
||||
return common.PlugnTrigger("deploy", []string{appName, imageTag, processName}...)
|
||||
}
|
||||
|
||||
// Restore ensures an app that should be running is running on boot
|
||||
@@ -90,7 +120,7 @@ func Restore(appName string) error {
|
||||
|
||||
// Start starts the app
|
||||
func Start(appName string) error {
|
||||
imageTag, _ := common.GetRunningImageTag(appName)
|
||||
imageTag, _ := common.GetRunningImageTag(appName, "")
|
||||
|
||||
if !common.IsDeployed(appName) {
|
||||
common.LogWarn(fmt.Sprintf("App %s has not been deployed", appName))
|
||||
|
||||
@@ -21,7 +21,7 @@ Additional commands:`
|
||||
ps:inspect <app>, Displays a sanitized version of docker inspect for an app
|
||||
ps:rebuild [--parallel count] [--all|<app>], Rebuilds an app from source
|
||||
ps:report [<app>] [<flag>], Displays a process report for one or more apps
|
||||
ps:restart [--parallel count] [--all|<app>], Restart an app
|
||||
ps:restart [--parallel count] [--all|<app>] [<process-name>], Restart an app
|
||||
ps:restore [<app>], Start previously running apps e.g. after reboot
|
||||
ps:scale [--skip-deploy] <app> <proc>=<count> [<proc>=<count>...], Get/Set how many instances of a given process to run
|
||||
ps:set <app> <key> <value>, Set or clear a ps property for an app
|
||||
|
||||
@@ -45,7 +45,8 @@ func main() {
|
||||
parallelCount := args.Int("parallel", ps.RunInSerial, "--parallel: number of apps to restart in parallel, -1 to match cpu count")
|
||||
args.Parse(os.Args[2:])
|
||||
appName := args.Arg(0)
|
||||
err = ps.CommandRestart(appName, *allApps, *parallelCount)
|
||||
processName := args.Arg(1)
|
||||
err = ps.CommandRestart(appName, processName, *allApps, *parallelCount)
|
||||
case "restore":
|
||||
args := flag.NewFlagSet("ps:restore", flag.ExitOnError)
|
||||
allApps := args.Bool("all", false, "--all: restore all apps")
|
||||
|
||||
@@ -54,8 +54,11 @@ func CommandReport(appName string, format string, infoFlag string) error {
|
||||
}
|
||||
|
||||
// CommandRestart restarts an app
|
||||
func CommandRestart(appName string, allApps bool, parallelCount int) error {
|
||||
func CommandRestart(appName string, processName string, allApps bool, parallelCount int) error {
|
||||
if allApps {
|
||||
if processName != "" {
|
||||
return errors.New("Unable to restart all apps when specifying a process name")
|
||||
}
|
||||
return common.RunCommandAgainstAllApps(Restart, "restart", parallelCount)
|
||||
}
|
||||
|
||||
@@ -63,6 +66,10 @@ func CommandRestart(appName string, allApps bool, parallelCount int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if processName != "" {
|
||||
return RestartProcess(appName, processName)
|
||||
}
|
||||
|
||||
return Restart(appName)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ func pushToRegistry(appName string, tag int, imageID string, imageRepo string) e
|
||||
common.LogVerboseQuiet("Retrieving image info for app")
|
||||
|
||||
registryServer := getRegistryServerForApp(appName)
|
||||
imageTag, _ := common.GetRunningImageTag(appName)
|
||||
imageTag, _ := common.GetRunningImageTag(appName, "")
|
||||
|
||||
fullImage := fmt.Sprintf("%s%s:%d", registryServer, imageRepo, tag)
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions"
|
||||
trigger-scheduler-docker-local-scheduler-deploy() {
|
||||
declare desc="deploys an image tag for a given application"
|
||||
declare trigger="scheduler-deploy"
|
||||
declare DOKKU_SCHEDULER="$1" APP="$2" IMAGE_TAG="$3"
|
||||
declare DOKKU_SCHEDULER="$1" APP="$2" IMAGE_TAG="$3" PROCESS_TYPE="$4"
|
||||
local PROCESS_TYPE
|
||||
|
||||
if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then
|
||||
return
|
||||
@@ -28,7 +29,7 @@ trigger-scheduler-docker-local-scheduler-deploy() {
|
||||
local IMAGE_SOURCE_TYPE="dockerfile"
|
||||
[[ "$DOKKU_HEROKUISH" == "true" ]] && IMAGE_SOURCE_TYPE="herokuish"
|
||||
[[ "$DOKKU_CNB" == "true" ]] && IMAGE_SOURCE_TYPE="pack"
|
||||
local oldids=$(get_app_container_ids "$APP")
|
||||
local oldids=$(get_app_container_ids "$APP" "$PROCESS_TYPE")
|
||||
|
||||
DOKKU_NETWORK_BIND_ALL="$(plugn trigger network-get-property "$APP" bind-all-interfaces)"
|
||||
DOKKU_DOCKER_STOP_TIMEOUT="$(config_get "$APP" DOKKU_DOCKER_STOP_TIMEOUT || true)"
|
||||
@@ -54,6 +55,10 @@ trigger-scheduler-docker-local-scheduler-deploy() {
|
||||
local PROC_TYPE=${line%%=*}
|
||||
local PROC_COUNT=${line#*=}
|
||||
|
||||
if [[ -n "$PROCESS_TYPE" ]] && [[ "$PROC_TYPE" != "$PROCESS_TYPE" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$PROC_TYPE" != "web" ]]; then
|
||||
echo "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/bin/scheduler-deploy-process $APP $IMAGE_SOURCE_TYPE $IMAGE $IMAGE_TAG $PROC_TYPE $PROC_COUNT" >>"$TMP_FILE"
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user