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 38bfaea286
commit 1afdffef8d
9 changed files with 89 additions and 36 deletions

View File

@@ -65,6 +65,7 @@ dokku postgres:create <service> [--create-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
- `-i|--image IMAGE`: the image name to start the service with
- `-I|--image-version IMAGE_VERSION`: the image version to start the service with
@@ -386,6 +387,7 @@ dokku postgres:upgrade <service> [--upgrade-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
- `-i|--image IMAGE`: the image name to start the service with
- `-I|--image-version IMAGE_VERSION`: the image version to start the service with
@@ -423,6 +425,7 @@ dokku postgres:clone <service> <new-service> [--clone-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
- `-i|--image IMAGE`: the image name 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
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([
header(service),
description(service, image, version),
@@ -22,7 +22,7 @@ def compile(service, version, variable, alias, image, scheme, ports, sponsors, u
requirements_section(dokku_version),
installation_section(service, dokku_version),
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")
@@ -115,31 +115,31 @@ def commands_section(service, variable, alias, image, scheme, ports, unimplement
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(
[
"## 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.",
usage_intro(service, variable, alias, image, scheme, ports, unimplemented),
usage_lifecycle(service, variable, alias, image, scheme, ports, unimplemented),
usage_automation(service, variable, alias, image, scheme, ports, unimplemented),
usage_data_management(service, variable, alias, image, scheme, ports, unimplemented),
usage_backup(service, variable, alias, image, scheme, ports, unimplemented),
usage_docker_pull(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, options, unimplemented),
usage_automation(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_data_management(service, variable, alias, image, scheme, ports, options, unimplemented),
usage_backup(service, variable, alias, image, scheme, ports, options, 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"]
content = ["### Basic Usage"]
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 = [
"connect",
"enter",
@@ -159,11 +159,11 @@ def usage_lifecycle(service, variable, alias, image, scheme, ports, unimplemente
]
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"]
content = [
"### Service Automation",
@@ -173,11 +173,11 @@ def usage_automation(service, variable, alias, image, scheme, ports, unimplement
]
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"]
content = [
"### Data Management",
@@ -187,11 +187,11 @@ def usage_data_management(service, variable, alias, image, scheme, ports, unimpl
]
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 = [
"backup-auth",
"backup-deauth",
@@ -214,11 +214,11 @@ def usage_backup(service, variable, alias, image, scheme, ports, unimplemented):
]
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()
return "\n".join(
[
@@ -232,11 +232,11 @@ def usage_docker_pull(service, variable, alias, image, scheme, ports, unimplemen
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
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 == "":
continue
content.append(output)
@@ -274,7 +274,7 @@ def parse_args(line):
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:
return ""
@@ -300,6 +300,8 @@ def command_help(command, service, variable, alias, image, scheme, ports, unimpl
content.append("flags:")
content.append("")
for flag in data["flags"]:
if "--config-options" in flag and options != "":
flag = f"{flag} (default: `{options}`)"
content.append(f"- {flag}")
if len(data["examples"]) > 0:
@@ -477,6 +479,7 @@ def main():
variable = None
image = None
alias = None
options = None
unimplemented = []
with open("Dockerfile") as f:
@@ -503,6 +506,15 @@ def main():
if match is not None:
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 = []
with open("plugin.toml") as f:
for line in f.readlines():
@@ -510,7 +522,7 @@ def main():
sponsors = re.search("\[([\"\w\s,_-]+)\]", line).group(1)
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__)))
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"
}
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() {
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"
@@ -384,6 +412,7 @@ service_info() {
local flag_map=(
"--config-dir: ${SERVICE_ROOT}/${PLUGIN_CONFIG_SUFFIX}"
"--config-options: $(cat "$SERVICE_ROOT/CONFIG_OPTIONS")"
"--data-dir: ${SERVICE_ROOT}/data"
"--dsn: ${SERVICE_URL}"
"--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_S3BACKUP_IMAGE="dokku/s3backup:0.10.3"
export PLUGIN_WAIT_IMAGE="dokku/wait:0.4.3"
export POSTGRES_CONFIG_OPTIONS=${POSTGRES_CONFIG_OPTIONS:=""}

View File

@@ -53,17 +53,7 @@ service_create() {
echo "$PASSWORD" >"$SERVICE_ROOT/PASSWORD"
chmod 640 "$SERVICE_ROOT/PASSWORD"
[[ -n "$SERVICE_CUSTOM_ENV" ]] && POSTGRES_CUSTOM_ENV="$SERVICE_CUSTOM_ENV"
if [[ -n $POSTGRES_CUSTOM_ENV ]]; then
echo "$POSTGRES_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
service_commit_config "$SERVICE"
write_database_name "$SERVICE"
plugn trigger service-action post-create "$SERVICE"
service_create_container "$SERVICE"
@@ -79,13 +69,17 @@ service_create_container() {
local DATABASE_NAME="$(get_database_name "$SERVICE")"
local PREVIOUS_ID
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")"
if [[ -n "$SERVICE_MEMORY" ]]; then
MEMORY_LIMIT="--memory=${SERVICE_MEMORY}m"
fi
# shellcheck disable=SC2086
ID=$(docker run --name "$SERVICE_NAME" $MEMORY_LIMIT -v "$SERVICE_HOST_ROOT/data:/var/lib/postgresql/data" -e "POSTGRES_PASSWORD=$PASSWORD" --env-file="$SERVICE_ROOT/ENV" -d --restart always --label dokku=service --label dokku.service=postgres "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION")
ID=$(docker run --name "$SERVICE_NAME" $MEMORY_LIMIT -v "$SERVICE_HOST_ROOT/data:/var/lib/postgresql/data" -e "POSTGRES_PASSWORD=$PASSWORD" --env-file="$SERVICE_ROOT/ENV" -d --restart always --label dokku=service --label dokku.service=postgres "$PLUGIN_IMAGE:$PLUGIN_IMAGE_VERSION" $CONFIG_OPTIONS)
echo "$ID" >"$SERVICE_ROOT/ID"
dokku_log_verbose_quiet "Waiting for container to be ready"

View File

@@ -42,6 +42,14 @@ plugin-install() {
EOL
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 "$@"

View File

@@ -10,6 +10,7 @@ service-clone-cmd() {
#E dokku $PLUGIN_COMMAND_PREFIX:clone lolipop lolipop-2
#A service, service to run command against
#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 -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

View File

@@ -18,6 +18,7 @@ service-create-cmd() {
#E export ${PLUGIN_DEFAULT_ALIAS}_CUSTOM_ENV="USER=alpha;HOST=beta"
#E dokku $PLUGIN_COMMAND_PREFIX:create lolipop
#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 -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

View File

@@ -10,6 +10,7 @@ service-upgrade-cmd() {
#E you can upgrade an existing service to a new image or image-version
#E dokku $PLUGIN_COMMAND_PREFIX:upgrade lolipop
#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 -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
@@ -36,6 +37,8 @@ service-upgrade-cmd() {
return
fi
service_commit_config "$SERVICE"
dokku_log_info2 "Upgrading $SERVICE to $NEW_PLUGIN_IMAGE_TAG"
if [[ "$SERVICE_RESTART_APPS" == "true" ]]; then
dokku_log_info2 "Stopping all linked services"