From 720ddea579a069ff55e89e66dd8c6ebfb0303b24 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 12 Sep 2021 22:16:14 -0400 Subject: [PATCH] feat: add ability to set container config options during create/clone/upgrade actions Also add to documentation where possible. Closes dokku/dokku-mongo#131 --- README.md | 3 +++ bin/generate | 60 +++++++++++++++++++++++++++------------------ common-functions | 29 ++++++++++++++++++++++ config | 2 ++ functions | 18 +++++--------- install | 8 ++++++ subcommands/clone | 1 + subcommands/create | 1 + subcommands/upgrade | 3 +++ 9 files changed, 89 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 2b3ba92..0f97308 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ dokku redis:create [--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 redis:upgrade [--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 redis:clone [--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 diff --git a/bin/generate b/bin/generate index e38a931..d9da838 100755 --- a/bin/generate +++ b/bin/generate @@ -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") diff --git a/common-functions b/common-functions index 9d365a8..8eca6a5 100755 --- a/common-functions +++ b/common-functions @@ -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")" diff --git a/config b/config index d39d036..59efa7e 100755 --- a/config +++ b/config @@ -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 REDIS_CONFIG_OPTIONS=${REDIS_CONFIG_OPTIONS:=""} diff --git a/functions b/functions index a642413..454186c 100755 --- a/functions +++ b/functions @@ -60,17 +60,7 @@ service_create() { 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" - [[ -n "$SERVICE_CUSTOM_ENV" ]] && REDIS_CUSTOM_ENV="$SERVICE_CUSTOM_ENV" - 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 - + service_commit_config "$SERVICE" write_database_name "$SERVICE" plugn trigger service-action post-create "$SERVICE" service_create_container "$SERVICE" @@ -83,13 +73,17 @@ service_create_container() { local SERVICE_HOST_ROOT="$PLUGIN_DATA_HOST_ROOT/$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")" 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:/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" dokku_log_verbose_quiet "Waiting for container to be ready" diff --git a/install b/install index 6521cc3..d2be802 100755 --- a/install +++ b/install @@ -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 "$@" diff --git a/subcommands/clone b/subcommands/clone index 647aa19..04fe330 100755 --- a/subcommands/clone +++ b/subcommands/clone @@ -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 diff --git a/subcommands/create b/subcommands/create index 62a4df9..187f6ad 100755 --- a/subcommands/create +++ b/subcommands/create @@ -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 diff --git a/subcommands/upgrade b/subcommands/upgrade index cd05888..755db2f 100755 --- a/subcommands/upgrade +++ b/subcommands/upgrade @@ -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"