feat: add ability to set container config options during create/clone/upgrade actions

Also add to documentation where possible.

Closes dokku/dokku-mongo#131
This commit is contained in:
Jose Diaz-Gonzalez
2021-09-12 22:16:14 -04:00
parent 658e04df6f
commit 720ddea579
9 changed files with 89 additions and 36 deletions

View File

@@ -65,6 +65,7 @@ dokku redis:create <service> [--create-flags...]
flags: flags:
- `-c|--config-options "--args --go=here"`: extra arguments to pass to the container create command (default: `None`)
- `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with - `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with
- `-i|--image IMAGE`: the image name to start the service with - `-i|--image IMAGE`: the image name to start the service with
- `-I|--image-version IMAGE_VERSION`: the image version to start the service with - `-I|--image-version IMAGE_VERSION`: the image version to start the service with
@@ -386,6 +387,7 @@ dokku redis:upgrade <service> [--upgrade-flags...]
flags: flags:
- `-c|--config-options "--args --go=here"`: extra arguments to pass to the container create command (default: `None`)
- `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with - `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with
- `-i|--image IMAGE`: the image name to start the service with - `-i|--image IMAGE`: the image name to start the service with
- `-I|--image-version IMAGE_VERSION`: the image version to start the service with - `-I|--image-version IMAGE_VERSION`: the image version to start the service with
@@ -423,6 +425,7 @@ dokku redis:clone <service> <new-service> [--clone-flags...]
flags: flags:
- `-c|--config-options "--args --go=here"`: extra arguments to pass to the container create command (default: `None`)
- `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with - `-C|--custom-env "USER=alpha;HOST=beta"`: semi-colon delimited environment variables to start the service with
- `-i|--image IMAGE`: the image name to start the service with - `-i|--image IMAGE`: the image name to start the service with
- `-I|--image-version IMAGE_VERSION`: the image version to start the service with - `-I|--image-version IMAGE_VERSION`: the image version to start the service with

View File

@@ -5,7 +5,7 @@ import os
import re import re
def compile(service, version, variable, alias, image, scheme, ports, sponsors, unimplemented, dokku_version): def compile(service, version, variable, alias, image, scheme, ports, sponsors, options, unimplemented, dokku_version):
prefix = "\n\n".join([ prefix = "\n\n".join([
header(service), header(service),
description(service, image, version), description(service, image, version),
@@ -22,7 +22,7 @@ def compile(service, version, variable, alias, image, scheme, ports, sponsors, u
requirements_section(dokku_version), requirements_section(dokku_version),
installation_section(service, dokku_version), installation_section(service, dokku_version),
commands_section(service, variable, alias, image, scheme, ports, unimplemented), commands_section(service, variable, alias, image, scheme, ports, unimplemented),
usage_section(service, variable, alias, image, scheme, ports, unimplemented), usage_section(service, variable, alias, image, scheme, ports, options, unimplemented),
] ]
) )
.replace("\n\n\n\n\n", "\n") .replace("\n\n\n\n\n", "\n")
@@ -115,31 +115,31 @@ def commands_section(service, variable, alias, image, scheme, ports, unimplement
return "\n".join(content) return "\n".join(content)
def usage_section(service, variable, alias, image, scheme, ports, unimplemented): def usage_section(service, variable, alias, image, scheme, ports, options, unimplemented):
return "\n\n".join( return "\n\n".join(
[ [
"## Usage", "## Usage",
f"Help for any commands can be displayed by specifying the command as an argument to {service}:help. Please consult the `{service}:help` command for any undocumented commands.", f"Help for any commands can be displayed by specifying the command as an argument to {service}:help. Please consult the `{service}:help` command for any undocumented commands.",
usage_intro(service, variable, alias, image, scheme, ports, unimplemented), usage_intro(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_lifecycle(service, variable, alias, image, scheme, ports, unimplemented), usage_lifecycle(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_automation(service, variable, alias, image, scheme, ports, unimplemented), usage_automation(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_data_management(service, variable, alias, image, scheme, ports, unimplemented), usage_data_management(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_backup(service, variable, alias, image, scheme, ports, unimplemented), usage_backup(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_docker_pull(service, variable, alias, image, scheme, ports, unimplemented), usage_docker_pull(service, variable, alias, image, scheme, ports, options, unimplemented),
] ]
) )
def usage_intro(service, variable, alias, image, scheme, ports, unimplemented): def usage_intro(service, variable, alias, image, scheme, ports, options, unimplemented):
commands = ["create", "info", "list", "logs", "link", "unlink"] commands = ["create", "info", "list", "logs", "link", "unlink"]
content = ["### Basic Usage"] content = ["### Basic Usage"]
return fetch_commands_content( return fetch_commands_content(
service, variable, alias, image, scheme, ports, unimplemented, commands, content service, variable, alias, image, scheme, ports, options, unimplemented, commands, content
) )
def usage_lifecycle(service, variable, alias, image, scheme, ports, unimplemented): def usage_lifecycle(service, variable, alias, image, scheme, ports, options, unimplemented):
commands = [ commands = [
"connect", "connect",
"enter", "enter",
@@ -159,11 +159,11 @@ def usage_lifecycle(service, variable, alias, image, scheme, ports, unimplemente
] ]
return fetch_commands_content( return fetch_commands_content(
service, variable, alias, image, scheme, ports, unimplemented, commands, content service, variable, alias, image, scheme, ports, options, unimplemented, commands, content
) )
def usage_automation(service, variable, alias, image, scheme, ports, unimplemented): def usage_automation(service, variable, alias, image, scheme, ports, options, unimplemented):
commands = ["app-links", "clone", "exists", "linked", "links"] commands = ["app-links", "clone", "exists", "linked", "links"]
content = [ content = [
"### Service Automation", "### Service Automation",
@@ -173,11 +173,11 @@ def usage_automation(service, variable, alias, image, scheme, ports, unimplement
] ]
return fetch_commands_content( return fetch_commands_content(
service, variable, alias, image, scheme, ports, unimplemented, commands, content service, variable, alias, image, scheme, ports, options, unimplemented, commands, content
) )
def usage_data_management(service, variable, alias, image, scheme, ports, unimplemented): def usage_data_management(service, variable, alias, image, scheme, ports, options, unimplemented):
commands = ["import", "export"] commands = ["import", "export"]
content = [ content = [
"### Data Management", "### Data Management",
@@ -187,11 +187,11 @@ def usage_data_management(service, variable, alias, image, scheme, ports, unimpl
] ]
return fetch_commands_content( return fetch_commands_content(
service, variable, alias, image, scheme, ports, unimplemented, commands, content service, variable, alias, image, scheme, ports, options, unimplemented, commands, content
) )
def usage_backup(service, variable, alias, image, scheme, ports, unimplemented): def usage_backup(service, variable, alias, image, scheme, ports, options, unimplemented):
commands = [ commands = [
"backup-auth", "backup-auth",
"backup-deauth", "backup-deauth",
@@ -214,11 +214,11 @@ def usage_backup(service, variable, alias, image, scheme, ports, unimplemented):
] ]
return fetch_commands_content( return fetch_commands_content(
service, variable, alias, image, scheme, ports, unimplemented, commands, content service, variable, alias, image, scheme, ports, options, unimplemented, commands, content
) )
def usage_docker_pull(service, variable, alias, image, scheme, ports, unimplemented): def usage_docker_pull(service, variable, alias, image, scheme, ports, options, unimplemented):
service_prefix = service.upper() service_prefix = service.upper()
return "\n".join( return "\n".join(
[ [
@@ -232,11 +232,11 @@ def usage_docker_pull(service, variable, alias, image, scheme, ports, unimplemen
def fetch_commands_content( def fetch_commands_content(
service, variable, alias, image, scheme, ports, unimplemented, commands, content service, variable, alias, image, scheme, ports, options, unimplemented, commands, content
): ):
i = 0 i = 0
for command in commands: for command in commands:
output = command_help(command, service, variable, alias, image, scheme, ports, unimplemented) output = command_help(command, service, variable, alias, image, scheme, ports, options, unimplemented)
if output == "": if output == "":
continue continue
content.append(output) content.append(output)
@@ -274,7 +274,7 @@ def parse_args(line):
return " ".join(arguments) return " ".join(arguments)
def command_help(command, service, variable, alias, image, scheme, ports, unimplemented): def command_help(command, service, variable, alias, image, scheme, ports, options, unimplemented):
if command in unimplemented: if command in unimplemented:
return "" return ""
@@ -300,6 +300,8 @@ def command_help(command, service, variable, alias, image, scheme, ports, unimpl
content.append("flags:") content.append("flags:")
content.append("") content.append("")
for flag in data["flags"]: for flag in data["flags"]:
if "--config-options" in flag and options != "":
flag = f"{flag} (default: `{options}`)"
content.append(f"- {flag}") content.append(f"- {flag}")
if len(data["examples"]) > 0: if len(data["examples"]) > 0:
@@ -477,6 +479,7 @@ def main():
variable = None variable = None
image = None image = None
alias = None alias = None
options = None
unimplemented = [] unimplemented = []
with open("Dockerfile") as f: with open("Dockerfile") as f:
@@ -503,6 +506,15 @@ def main():
if match is not None: if match is not None:
unimplemented = [s.strip('"') for s in match.group(1).split(" ")] unimplemented = [s.strip('"') for s in match.group(1).split(" ")]
with open("config") as f:
for line in f.readlines():
if f"{variable}_CONFIG_OPTIONS" in line:
print(variable)
match = re.search('"(.+)"', line)
if match is not None:
options = match.group(1)
print(options)
sponsors = [] sponsors = []
with open("plugin.toml") as f: with open("plugin.toml") as f:
for line in f.readlines(): for line in f.readlines():
@@ -510,7 +522,7 @@ def main():
sponsors = re.search("\[([\"\w\s,_-]+)\]", line).group(1) sponsors = re.search("\[([\"\w\s,_-]+)\]", line).group(1)
sponsors = [s.strip("\"") for s in sponsors.split(",")] sponsors = [s.strip("\"") for s in sponsors.split(",")]
text = compile(service, version, variable, alias, image, scheme, ports, sponsors, unimplemented, "0.19.x+") text = compile(service, version, variable, alias, image, scheme, ports, sponsors, options, unimplemented, "0.19.x+")
base_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) base_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
readme_file = os.path.join(base_path, "README.md") readme_file = os.path.join(base_path, "README.md")

View File

@@ -221,6 +221,34 @@ service_backup() {
docker run --rm $BACKUP_PARAMETERS "$PLUGIN_S3BACKUP_IMAGE" docker run --rm $BACKUP_PARAMETERS "$PLUGIN_S3BACKUP_IMAGE"
} }
service_commit_config() {
declare SERVICE="$1"
local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
local CONFIG_VARIABLE="${PLUGIN_VARIABLE}_CONFIG_OPTIONS"
local ENV_VARIABLE="${PLUGIN_VARIABLE}_CUSTOM_ENV"
custom_env="${!ENV_VARIABLE}"
[[ -n "$SERVICE_CUSTOM_ENV" ]] && custom_env="$SERVICE_CUSTOM_ENV"
if [[ -n $custom_env ]]; then
echo "$custom_env" | tr ';' "\n" >"$SERVICE_ROOT/ENV"
else
echo "" >"$SERVICE_ROOT/ENV"
fi
config_options="${!CONFIG_VARIABLE}"
[[ -n "$PLUGIN_CONFIG_OPTIONS" ]] && config_options="$PLUGIN_CONFIG_OPTIONS"
if [[ -n "$config_options" ]]; then
echo "$config_options" >"$SERVICE_ROOT/CONFIG_OPTIONS"
else
echo "" >"$SERVICE_ROOT/CONFIG_OPTIONS"
fi
if [[ -n "$SERVICE_MEMORY" ]]; then
echo "$SERVICE_MEMORY" >"$SERVICE_ROOT/SERVICE_MEMORY"
fi
}
service_backup_auth() { service_backup_auth() {
declare desc="Sets up authentication" declare desc="Sets up authentication"
declare SERVICE="$1" AWS_ACCESS_KEY_ID="$2" AWS_SECRET_ACCESS_KEY="$3" AWS_DEFAULT_REGION="$4" AWS_SIGNATURE_VERSION="$5" ENDPOINT_URL="$6" declare SERVICE="$1" AWS_ACCESS_KEY_ID="$2" AWS_SECRET_ACCESS_KEY="$3" AWS_DEFAULT_REGION="$4" AWS_SIGNATURE_VERSION="$5" ENDPOINT_URL="$6"
@@ -384,6 +412,7 @@ service_info() {
local flag_map=( local flag_map=(
"--config-dir: ${SERVICE_ROOT}/${PLUGIN_CONFIG_SUFFIX}" "--config-dir: ${SERVICE_ROOT}/${PLUGIN_CONFIG_SUFFIX}"
"--config-options: $(cat "$SERVICE_ROOT/CONFIG_OPTIONS")"
"--data-dir: ${SERVICE_ROOT}/data" "--data-dir: ${SERVICE_ROOT}/data"
"--dsn: ${SERVICE_URL}" "--dsn: ${SERVICE_URL}"
"--exposed-ports: $(service_exposed_ports "$SERVICE")" "--exposed-ports: $(service_exposed_ports "$SERVICE")"

2
config
View File

@@ -31,3 +31,5 @@ export PLUGIN_BUSYBOX_IMAGE="busybox:1.31.1-uclibc"
export PLUGIN_AMBASSADOR_IMAGE="dokku/ambassador:0.3.3" export PLUGIN_AMBASSADOR_IMAGE="dokku/ambassador:0.3.3"
export PLUGIN_S3BACKUP_IMAGE="dokku/s3backup:0.10.3" export PLUGIN_S3BACKUP_IMAGE="dokku/s3backup:0.10.3"
export PLUGIN_WAIT_IMAGE="dokku/wait:0.4.3" export PLUGIN_WAIT_IMAGE="dokku/wait:0.4.3"
export REDIS_CONFIG_OPTIONS=${REDIS_CONFIG_OPTIONS:=""}

View File

@@ -60,17 +60,7 @@ service_create() {
chmod 640 "$SERVICE_ROOT/PASSWORD" chmod 640 "$SERVICE_ROOT/PASSWORD"
sed -i.bak "s/# requirepass.*/requirepass ${PASSWORD}/" "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf" && rm "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf.bak" sed -i.bak "s/# requirepass.*/requirepass ${PASSWORD}/" "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf" && rm "$SERVICE_ROOT/$PLUGIN_CONFIG_SUFFIX/redis.conf.bak"
[[ -n "$SERVICE_CUSTOM_ENV" ]] && REDIS_CUSTOM_ENV="$SERVICE_CUSTOM_ENV" service_commit_config "$SERVICE"
if [[ -n $REDIS_CUSTOM_ENV ]]; then
echo "$REDIS_CUSTOM_ENV" | tr ';' "\n" >"$SERVICE_ROOT/ENV"
else
echo "" >"$SERVICE_ROOT/ENV"
fi
if [[ -n "$SERVICE_MEMORY" ]]; then
echo "$SERVICE_MEMORY" >"$SERVICE_ROOT/SERVICE_MEMORY"
fi
write_database_name "$SERVICE" write_database_name "$SERVICE"
plugn trigger service-action post-create "$SERVICE" plugn trigger service-action post-create "$SERVICE"
service_create_container "$SERVICE" service_create_container "$SERVICE"
@@ -83,13 +73,17 @@ service_create_container() {
local SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE" local SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$SERVICE"
local SERVICE_NAME="$(get_service_name "$SERVICE")" local SERVICE_NAME="$(get_service_name "$SERVICE")"
if [[ -f "$SERVICE_ROOT/CONFIG_OPTIONS" ]]; then
export CONFIG_OPTIONS="$(cat "$SERVICE_ROOT/CONFIG_OPTIONS")"
fi
[[ -f "$SERVICE_ROOT/SERVICE_MEMORY" ]] && SERVICE_MEMORY="$(cat "$SERVICE_ROOT/SERVICE_MEMORY")" [[ -f "$SERVICE_ROOT/SERVICE_MEMORY" ]] && SERVICE_MEMORY="$(cat "$SERVICE_ROOT/SERVICE_MEMORY")"
if [[ -n "$SERVICE_MEMORY" ]]; then if [[ -n "$SERVICE_MEMORY" ]]; then
MEMORY_LIMIT="--memory=${SERVICE_MEMORY}m" MEMORY_LIMIT="--memory=${SERVICE_MEMORY}m"
fi fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
ID=$(docker run --name "$SERVICE_NAME" $MEMORY_LIMIT -v "$SERVICE_HOST_ROOT/data:/data" -v "$SERVICE_HOST_ROOT/$PLUGIN_CONFIG_SUFFIX:/usr/local/etc/redis" --env-file="$SERVICE_ROOT/ENV" -d --restart always --label dokku=service --label dokku.service=redis "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" redis-server /usr/local/etc/redis/redis.conf --bind 0.0.0.0) ID=$(docker run --name "$SERVICE_NAME" $MEMORY_LIMIT -v "$SERVICE_HOST_ROOT/data:/data" -v "$SERVICE_HOST_ROOT/$PLUGIN_CONFIG_SUFFIX:/usr/local/etc/redis" --env-file="$SERVICE_ROOT/ENV" -d --restart always --label dokku=service --label dokku.service=redis "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" redis-server /usr/local/etc/redis/redis.conf --bind 0.0.0.0 $CONFIG_OPTIONS)
echo "$ID" >"$SERVICE_ROOT/ID" echo "$ID" >"$SERVICE_ROOT/ID"
dokku_log_verbose_quiet "Waiting for container to be ready" dokku_log_verbose_quiet "Waiting for container to be ready"

View File

@@ -42,6 +42,14 @@ plugin-install() {
EOL EOL
chmod 0440 "$_SUDOERS_FILE" chmod 0440 "$_SUDOERS_FILE"
local SERVICES=$(ls "$PLUGIN_DATA_ROOT" 2>/dev/null)
for SERVICE in $SERVICES; do
local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE"
if [[ -f "$SERVICE_ROOT/${PLUGIN_VARIABLE}_CONFIG_OPTIONS" ]]; then
mv "$SERVICE_ROOT/${PLUGIN_VARIABLE}_CONFIG_OPTIONS" "$SERVICE_ROOT/CONFIG_OPTIONS"
fi
done
} }
plugin-install "$@" plugin-install "$@"

View File

@@ -10,6 +10,7 @@ service-clone-cmd() {
#E dokku $PLUGIN_COMMAND_PREFIX:clone lolipop lolipop-2 #E dokku $PLUGIN_COMMAND_PREFIX:clone lolipop lolipop-2
#A service, service to run command against #A service, service to run command against
#A new-service, name of new service #A new-service, name of new service
#F -c|--config-options "--args --go=here", extra arguments to pass to the container create command
#F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with
#F -i|--image IMAGE, the image name to start the service with #F -i|--image IMAGE, the image name to start the service with
#F -I|--image-version IMAGE_VERSION, the image version to start the service with #F -I|--image-version IMAGE_VERSION, the image version to start the service with

View File

@@ -18,6 +18,7 @@ service-create-cmd() {
#E export ${PLUGIN_DEFAULT_ALIAS}_CUSTOM_ENV="USER=alpha;HOST=beta" #E export ${PLUGIN_DEFAULT_ALIAS}_CUSTOM_ENV="USER=alpha;HOST=beta"
#E dokku $PLUGIN_COMMAND_PREFIX:create lolipop #E dokku $PLUGIN_COMMAND_PREFIX:create lolipop
#A service, service to run command against #A service, service to run command against
#F -c|--config-options "--args --go=here", extra arguments to pass to the container create command
#F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with
#F -i|--image IMAGE, the image name to start the service with #F -i|--image IMAGE, the image name to start the service with
#F -I|--image-version IMAGE_VERSION, the image version to start the service with #F -I|--image-version IMAGE_VERSION, the image version to start the service with

View File

@@ -10,6 +10,7 @@ service-upgrade-cmd() {
#E you can upgrade an existing service to a new image or image-version #E you can upgrade an existing service to a new image or image-version
#E dokku $PLUGIN_COMMAND_PREFIX:upgrade lolipop #E dokku $PLUGIN_COMMAND_PREFIX:upgrade lolipop
#A service, service to run command against #A service, service to run command against
#F -c|--config-options "--args --go=here", extra arguments to pass to the container create command
#F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with #F -C|--custom-env "USER=alpha;HOST=beta", semi-colon delimited environment variables to start the service with
#F -i|--image IMAGE, the image name to start the service with #F -i|--image IMAGE, the image name to start the service with
#F -I|--image-version IMAGE_VERSION, the image version to start the service with #F -I|--image-version IMAGE_VERSION, the image version to start the service with
@@ -36,6 +37,8 @@ service-upgrade-cmd() {
return return
fi fi
service_commit_config "$SERVICE"
dokku_log_info2 "Upgrading $SERVICE to $NEW_PLUGIN_IMAGE_TAG" dokku_log_info2 "Upgrading $SERVICE to $NEW_PLUGIN_IMAGE_TAG"
if [[ "$SERVICE_RESTART_APPS" == "true" ]]; then if [[ "$SERVICE_RESTART_APPS" == "true" ]]; then
dokku_log_info2 "Stopping all linked services" dokku_log_info2 "Stopping all linked services"