Merge pull request #3240 from dokku/3196-procfile-handling

Refactor Procfile handling to use go-procfile-util
This commit is contained in:
Jose Diaz-Gonzalez
2018-10-14 00:20:02 -04:00
committed by GitHub
17 changed files with 158 additions and 48 deletions

View File

@@ -1,6 +1,7 @@
DOKKU_VERSION ?= master
SSHCOMMAND_URL ?= https://raw.githubusercontent.com/dokku/sshcommand/v0.7.0/sshcommand
PROCFILE_UTIL_URL ?= https://github.com/josegonzalez/go-procfile-util/releases/download/v0.4.0/procfile-util_0.4.0_linux_x86_64.tgz
PLUGN_URL ?= https://github.com/dokku/plugn/releases/download/v0.3.0/plugn_0.3.0_linux_x86_64.tgz
SIGIL_URL ?= https://github.com/gliderlabs/sigil/releases/download/v0.4.0/sigil_0.4.0_Linux_x86_64.tgz
STACK_URL ?= https://github.com/gliderlabs/herokuish.git
@@ -26,7 +27,7 @@ endif
include common.mk
.PHONY: all apt-update install version copyfiles copyplugin man-db plugins dependencies sshcommand plugn docker aufs stack count dokku-installer vagrant-acl-add vagrant-dokku go-build
.PHONY: all apt-update install version copyfiles copyplugin man-db plugins dependencies sshcommand procfile-util plugn docker aufs stack count dokku-installer vagrant-acl-add vagrant-dokku go-build
include tests.mk
include deb.mk
@@ -109,13 +110,13 @@ else
echo $(DOKKU_VERSION) > ~dokku/VERSION
endif
plugin-dependencies: plugn
plugin-dependencies: plugn procfile-util
sudo -E dokku plugin:install-dependencies --core
plugins: plugn docker
plugins: plugn procfile-util docker
sudo -E dokku plugin:install --core
dependencies: apt-update sshcommand plugn docker help2man man-db sigil
dependencies: apt-update sshcommand plugn procfile-util docker help2man man-db sigil
$(MAKE) -e stack
apt-update:
@@ -132,6 +133,10 @@ sshcommand:
chmod +x /usr/local/bin/sshcommand
sshcommand create dokku /usr/local/bin/dokku
procfile-util:
wget -qO /tmp/procfile-util_latest.tgz ${PROCFILE_UTIL_URL}
tar xzf /tmp/procfile-util_latest.tgz -C /usr/local/bin
plugn:
wget -qO /tmp/plugn_latest.tgz ${PLUGN_URL}
tar xzf /tmp/plugn_latest.tgz -C /usr/local/bin

2
debian/control vendored
View File

@@ -3,7 +3,7 @@ Version: 0.12.13
Section: web
Priority: optional
Architecture: amd64
Depends: locales, git, make, curl, gcc, man-db, netcat, sshcommand (>= 0.6.0), gliderlabs-sigil, docker-engine-cs (>= 1.7.1) | docker-engine (>= 1.7.1) | docker-io (>= 1.7.1) | docker-ce | docker-ee, net-tools, software-properties-common, python-software-properties | python3-software-properties, rsyslog
Depends: locales, git, make, curl, gcc, man-db, netcat, sshcommand (>= 0.6.0), gliderlabs-sigil, docker-engine-cs (>= 1.7.1) | docker-engine (>= 1.7.1) | docker-io (>= 1.7.1) | docker-ce | docker-ee, net-tools, software-properties-common, procfile-util, python-software-properties | python3-software-properties, rsyslog
Recommends: herokuish (>= 0.3.4), parallel, dokku-update
Pre-Depends: nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn (>= 0.3.0), sudo, python2.7, debconf
Maintainer: Jose Diaz-Gonzalez <dokku@josediazgonzalez.com>

View File

@@ -392,25 +392,6 @@ get_app_running_container_types() {
echo "$CONTAINER_TYPES"
}
get_cmd_from_procfile() {
declare desc="parse cmd from app Procfile"
local APP=$1; local PROC_TYPE=$2; local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
verify_app_name "$APP"
if [[ -f $DOKKU_PROCFILE ]]; then
local line; local name; local command
while read -r line || [[ -n "$line" ]]; do
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
continue
fi
line=$(strip_inline_comments "$line")
name="${line%%:*}"
command="${line#*:[[:space:]]}"
[[ "$name" == "$PROC_TYPE" ]] && echo "$command" && break
done < "$DOKKU_PROCFILE"
fi
}
is_deployed() {
declare desc="return 0 if given app has a running container"
local APP="$1"

View File

@@ -3,6 +3,17 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
get_cmd_from_procfile() {
declare desc="parse cmd from app Procfile"
declare APP="$1" PROC_TYPE="$2" PORT="$3"
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
local COMMAND
verify_app_name "$APP"
[[ ! -f $DOKKU_PROCFILE ]] && return
procfile-util show --procfile "$DOKKU_PROCFILE" --process-type "$PROC_TYPE" --default-port "$PORT"
}
print_dokku_scale_file() {
declare desc="prints contents of DOKKU_SCALE file"
local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
@@ -23,6 +34,11 @@ extract_procfile() {
copy_from_image "$IMAGE" "Procfile" "$DOKKU_PROCFILE" 2>/dev/null || true
if [[ -f "$DOKKU_PROCFILE" ]]; then
dokku_log_info1_quiet "App Procfile file found ($DOKKU_PROCFILE)"
# shellcheck disable=SC2069
PROCFILE_ERRORS="$(procfile-util check --procfile "$DOKKU_PROCFILE" 2>&1 >/dev/null || true)"
if [[ -n "$PROCFILE_ERRORS" ]]; then
dokku_log_fail "${PROCFILE_ERRORS}"
fi
else
dokku_log_info1_quiet "No Procfile found in app image"
fi
@@ -71,12 +87,21 @@ generate_scale_file() {
set_scale() {
declare desc="sets app proc type scaling"
local APP="$1"; local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
declare APP="$1"
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
shift 1
extract_procfile "$APP" "$IMAGE_TAG" > /dev/null
trap 'remove_procfile $APP' RETURN INT TERM EXIT
local SCALE_SETTINGS=("$@")
for procscale in "${SCALE_SETTINGS[@]}"; do
local PROC_NAME=${procscale%%=*}
local PROC_COUNT=${procscale#*=}
if [[ -f "$DOKKU_PROCFILE" ]] && ! procfile-util exists --procfile "$DOKKU_PROCFILE" --process-type "$PROC_NAME" > /dev/null 2>&1; then
dokku_log_fail "${PROC_NAME} is not a valid process name"
fi
is_number "$PROC_COUNT" || dokku_log_fail "ps:scale $PROC_COUNT is not a number"
dokku_log_info1_quiet "Scaling $APP:$PROC_NAME to $PROC_COUNT"
if (egrep -q "^${PROC_NAME}=" "$DOKKU_SCALE_FILE" > /dev/null 2>&1); then
@@ -148,6 +173,7 @@ ps_scale() {
local APP="$1"; verify_app_name "$APP"
local IMAGE_TAG=$(get_running_image_tag "$APP")
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
shift 1
[[ ! -e $DOKKU_SCALE_FILE ]] && generate_scale_file "$APP" "$IMAGE_TAG"

View File

@@ -3,6 +3,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
scheduler-docker-local-scheduler-deploy() {
declare desc="deploys an image tag for a given application"
@@ -62,13 +63,8 @@ scheduler-docker-local-scheduler-deploy() {
declare -a ARG_ARRAY
eval "ARG_ARRAY=($DOCKER_ARGS)"
[[ "$DOKKU_HEROKUISH" == "true" ]] && local START_CMD="/start $PROC_TYPE"
if [[ "$DOKKU_HEROKUISH" == "false" ]]; then
local DOKKU_DOCKERFILE_START_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_START_CMD || true)
local DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE")
local START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD}
fi
local START_CMD
[[ "$DOKKU_HEROKUISH" == "true" ]] && START_CMD="/start $PROC_TYPE"
if [[ "$PROC_TYPE" == "web" ]]; then
ports=($(plugn trigger network-compute-ports "$APP" "$PROC_TYPE" "$DOKKU_HEROKUISH"))
@@ -81,6 +77,7 @@ scheduler-docker-local-scheduler-deploy() {
DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done
START_CMD=$(fn-scheduler-docker-local-extract-start-cmd "$APP" "$PROC_TYPE" "$START_CMD" "$DOKKU_HEROKUISH" "$DOKKU_PORT")
if [[ "$DOKKU_NETWORK_BIND_ALL" == "false" ]]; then
# shellcheck disable=SC2086
cid=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD)
@@ -89,6 +86,8 @@ scheduler-docker-local-scheduler-deploy() {
cid=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$DOKKU_PORT "${ARG_ARRAY[@]}" $IMAGE $START_CMD)
fi
else
START_CMD=$(fn-scheduler-docker-local-extract-start-cmd "$APP" "$PROC_TYPE" "$START_CMD" "$DOKKU_HEROKUISH")
# shellcheck disable=SC2086
cid=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d "${ARG_ARRAY[@]}" $IMAGE $START_CMD)
fi
@@ -177,4 +176,18 @@ scheduler-docker-local-scheduler-deploy() {
fi
}
fn-scheduler-docker-local-extract-start-cmd() {
declare APP="$1" PROC_TYPE="$2" START_CMD="$3" DOKKU_HEROKUISH="$4" PORT="$5"
local DOKKU_DOCKERFILE_START_CMD DOKKU_PROCFILE_START_CMD START_CMD
if [[ "$DOKKU_HEROKUISH" != "false" ]]; then
echo "$START_CMD"
return
fi
DOKKU_DOCKERFILE_START_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_START_CMD || true)
DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE" "$PORT")
START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD}
echo "$START_CMD"
}
scheduler-docker-local-scheduler-deploy "$@"

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
scheduler-docker-local-scheduler-run() {
declare desc="runs command in container based on app image"

19
rpm.mk
View File

@@ -95,20 +95,21 @@ endif
-v "$$VERSION" \
-a $(RPM_ARCHITECTURE) \
-p "dokku-$$VERSION-1.x86_64.rpm" \
--depends 'git' \
--depends 'make' \
--depends 'curl' \
--depends 'gcc' \
--depends 'man-db' \
--depends 'sshcommand' \
--depends 'gliderlabs-sigil' \
--depends '/usr/bin/docker' \
--depends 'bind-utils' \
--depends 'curl' \
--depends 'gcc' \
--depends 'git' \
--depends 'gliderlabs-sigil' \
--depends 'make' \
--depends 'man-db' \
--depends 'nc' \
--depends 'nginx >= 1.8.0' \
--depends 'plugn' \
--depends 'sudo' \
--depends 'procfile-util' \
--depends 'python' \
--depends 'nc' \
--depends 'sshcommand' \
--depends 'sudo' \
--after-install rpm/dokku.postinst \
--url "https://github.com/$(DOKKU_REPO_NAME)" \
--description $(DOKKU_DESCRIPTION) \

View File

@@ -0,0 +1,5 @@
WAIT=2 # wait 2 seconds
TIMEOUT=5 # set timeout to 5 seconds
ATTEMPTS=2 # try 2 times
/ nodejs/express

View File

@@ -0,0 +1,11 @@
FROM node:4
EXPOSE 3001/udp
EXPOSE 3000/tcp
EXPOSE 3003
COPY . /app
WORKDIR /app
RUN npm install
CMD npm start

View File

@@ -0,0 +1,12 @@
###############################
# DEVELOPMENT #
###############################
# Procfile for development using the new threaded worker (scheduler, twitter stream and delayed job)
cron: node worker.js
web: node web.js
<<<<<<< HEAD=0
worker: node worker.js
========0
worker: node worker-2.js
>>>>>>> 5bb7ec3e2a8f4f6565432a4fc82c92d4a3603d28=0

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
set -e; output="$(curl -s -S "$1")"; echo "$output"; test "$output" == "nodejs/express"

View File

@@ -0,0 +1,13 @@
{
"name": "node-example",
"version": "0.0.1",
"dependencies": {
"express": "2.5.x"
},
"engines": {
"node": "4.2.x"
},
"scripts": {
"start": "false"
}
}

View File

@@ -0,0 +1,12 @@
var express = require('express');
var app = express.createServer(express.logger());
app.get('/', function(request, response) {
response.send('nodejs/express');
});
var port = process.env.PORT || 5000;
app.listen(port, function() {
console.log("Listening on " + port);
});

View File

@@ -0,0 +1,6 @@
function worker() {
console.log('sleeping for 60 seconds');
setTimeout(worker, 60 * 1000);
}
worker();

View File

@@ -117,4 +117,4 @@ teardown() {
echo "output: "$output
echo "status: "$status
assert_success
}
}

View File

@@ -70,6 +70,21 @@ teardown() {
done
}
@test "(ps:scale) dockerfile non-existent process" {
run bash -c "dokku ps:scale $TEST_APP non-existent=2"
echo "output: $output"
echo "status: $status"
assert_success
destroy_app
create_app
deploy_app dockerfile-procfile
run bash -c "dokku ps:scale $TEST_APP non-existent=2"
echo "output: $output"
echo "status: $status"
assert_failure
}
@test "(ps:scale) dockerfile" {
run bash -c "dokku ps:scale $TEST_APP web=2"
echo "output: "$output
@@ -166,6 +181,16 @@ teardown() {
done
}
@test "(ps) dockerfile with bad procfile" {
run deploy_app dockerfile-procfile-bad
echo "output: "$output
echo "status: "$status
assert_failure
run create_app
assert_success
}
@test "(ps:scale) dockerfile with procfile" {
run bash -c "dokku ps:scale $TEST_APP web=2 worker=2"
echo "output: "$output
@@ -225,4 +250,3 @@ teardown() {
assert_success
done
}

View File

@@ -13,16 +13,15 @@ teardown() {
}
@test "(ps:scale) procfile commands extraction" {
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions"
cat <<EOF > "$DOKKU_ROOT/$TEST_APP/DOKKU_PROCFILE"
web: node web.js
web: node web.js --port \$PORT
worker: node worker.js
EOF
run get_cmd_from_procfile "$TEST_APP" web
run get_cmd_from_procfile "$TEST_APP" web 5001
echo "output: "$output
echo "status: "$status
assert_output "node web.js"
assert_output "node web.js --port 5001"
run get_cmd_from_procfile "$TEST_APP" worker
echo "output: "$output