mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-21 15:25:09 +00:00
feat(easy-docker): add guided app update workflow
This commit is contained in:
parent
2c97955a07
commit
27bb816ff4
7 changed files with 430 additions and 67 deletions
|
|
@ -8,6 +8,8 @@ load_easy_docker_wizard_env_modules() {
|
||||||
source "${wizard_dir}/env/validation.sh"
|
source "${wizard_dir}/env/validation.sh"
|
||||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/env/apps.sh
|
# shellcheck source=scripts/easy-docker/lib/app/wizard/env/apps.sh
|
||||||
source "${wizard_dir}/env/apps.sh"
|
source "${wizard_dir}/env/apps.sh"
|
||||||
|
# shellcheck source=scripts/easy-docker/lib/app/wizard/env/update.sh
|
||||||
|
source "${wizard_dir}/env/update.sh"
|
||||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/env/collect.sh
|
# shellcheck source=scripts/easy-docker/lib/app/wizard/env/collect.sh
|
||||||
source "${wizard_dir}/env/collect.sh"
|
source "${wizard_dir}/env/collect.sh"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
121
scripts/easy-docker/lib/app/wizard/env/apps.sh
vendored
121
scripts/easy-docker/lib/app/wizard/env/apps.sh
vendored
|
|
@ -431,3 +431,124 @@ update_stack_custom_modular_apps() {
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prompt_selected_stack_app_branches_data() {
|
||||||
|
local result_apps_metadata_var="${1}"
|
||||||
|
local stack_dir="${2}"
|
||||||
|
local metadata_path=""
|
||||||
|
local selected_predefined_csv=""
|
||||||
|
local predefined_app_id=""
|
||||||
|
local predefined_app_label=""
|
||||||
|
local predefined_repo_url=""
|
||||||
|
local selected_branch=""
|
||||||
|
local preferred_branch=""
|
||||||
|
local available_branch_lines=""
|
||||||
|
local existing_branch_lines=""
|
||||||
|
local selected_branch_lines=""
|
||||||
|
local selected_app_count=0
|
||||||
|
local built_apps_metadata_json_object=""
|
||||||
|
local prompt_status=0
|
||||||
|
local -a selected_predefined_ids=()
|
||||||
|
|
||||||
|
metadata_path="${stack_dir}/metadata.json"
|
||||||
|
if [ ! -f "${metadata_path}" ]; then
|
||||||
|
return 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
selected_predefined_csv="$(get_metadata_apps_predefined_csv "${metadata_path}" || true)"
|
||||||
|
existing_branch_lines="$(get_metadata_apps_predefined_branch_lines "${metadata_path}" || true)"
|
||||||
|
if [ -z "${selected_predefined_csv}" ]; then
|
||||||
|
return 4
|
||||||
|
fi
|
||||||
|
|
||||||
|
selected_branch_lines=""
|
||||||
|
IFS=',' read -r -a selected_predefined_ids <<<"${selected_predefined_csv}"
|
||||||
|
for predefined_app_id in "${selected_predefined_ids[@]}"; do
|
||||||
|
if [ -z "${predefined_app_id}" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
predefined_app_label="$(get_predefined_app_label_by_id "${predefined_app_id}" || true)"
|
||||||
|
if [ -z "${predefined_app_label}" ]; then
|
||||||
|
predefined_app_label="${predefined_app_id}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
predefined_repo_url="$(get_predefined_app_repo_by_id "${predefined_app_id}" || true)"
|
||||||
|
if [ -z "${predefined_repo_url}" ]; then
|
||||||
|
show_warning_and_wait "Missing repo URL for app '${predefined_app_id}'." 3
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
preferred_branch="$(get_predefined_branch_from_lines "${existing_branch_lines}" "${predefined_app_id}" || true)"
|
||||||
|
if [ -z "${preferred_branch}" ]; then
|
||||||
|
preferred_branch="$(get_stack_frappe_branch "${stack_dir}" || true)"
|
||||||
|
fi
|
||||||
|
if [ -z "${preferred_branch}" ]; then
|
||||||
|
preferred_branch="$(get_predefined_app_default_branch_by_id "${predefined_app_id}" || true)"
|
||||||
|
fi
|
||||||
|
if [ -z "${preferred_branch}" ]; then
|
||||||
|
preferred_branch="$(get_default_frappe_branch)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
available_branch_lines=""
|
||||||
|
if get_predefined_app_branch_lines_by_id available_branch_lines "${predefined_app_id}"; then
|
||||||
|
if [ -n "${preferred_branch}" ] && ! lines_contains_line "${available_branch_lines}" "${preferred_branch}"; then
|
||||||
|
preferred_branch="$(get_predefined_app_default_branch_by_id "${predefined_app_id}" || true)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if choose_predefined_app_branch selected_branch "${stack_dir}" "${predefined_app_id}" "${predefined_app_label}" "${predefined_repo_url}" "${preferred_branch}"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
prompt_status=$?
|
||||||
|
if [ "${prompt_status}" -eq 2 ]; then
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
return "${prompt_status}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
append_line_unique selected_branch_lines "${selected_branch_lines}" "${predefined_app_id}|${selected_branch}"
|
||||||
|
selected_app_count=$((selected_app_count + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${selected_app_count}" -eq 0 ]; then
|
||||||
|
return 4
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_predefined_apps_metadata_json_object built_apps_metadata_json_object "${selected_predefined_csv}" "${selected_branch_lines}"
|
||||||
|
printf -v "${result_apps_metadata_var}" "%s" "${built_apps_metadata_json_object}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
update_stack_selected_app_branches() {
|
||||||
|
local stack_dir="${1}"
|
||||||
|
local metadata_path=""
|
||||||
|
local apps_metadata_json_object=""
|
||||||
|
local prompt_status=0
|
||||||
|
|
||||||
|
metadata_path="${stack_dir}/metadata.json"
|
||||||
|
if [ ! -f "${metadata_path}" ]; then
|
||||||
|
return 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
if prompt_selected_stack_app_branches_data apps_metadata_json_object "${stack_dir}"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
prompt_status=$?
|
||||||
|
return "${prompt_status}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${apps_metadata_json_object}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! persist_stack_metadata_apps_object "${stack_dir}" "${apps_metadata_json_object}"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! persist_stack_apps_json_from_metadata_apps "${stack_dir}"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
||||||
146
scripts/easy-docker/lib/app/wizard/env/update.sh
vendored
Executable file
146
scripts/easy-docker/lib/app/wizard/env/update.sh
vendored
Executable file
|
|
@ -0,0 +1,146 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
is_valid_docker_image_tag() {
|
||||||
|
local value="${1}"
|
||||||
|
|
||||||
|
if [ -z "${value}" ] || [ "${#value}" -gt 128 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${value}" in
|
||||||
|
.* | -*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
*[!A-Za-z0-9_.-]*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
get_stack_custom_image_name() {
|
||||||
|
local stack_dir="${1}"
|
||||||
|
local env_path=""
|
||||||
|
|
||||||
|
env_path="$(get_stack_env_path "${stack_dir}")"
|
||||||
|
get_env_file_key_value "${env_path}" "CUSTOM_IMAGE"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_stack_custom_image_tag() {
|
||||||
|
local stack_dir="${1}"
|
||||||
|
local env_path=""
|
||||||
|
|
||||||
|
env_path="$(get_stack_env_path "${stack_dir}")"
|
||||||
|
get_env_file_key_value "${env_path}" "CUSTOM_TAG"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_stack_custom_image_ref() {
|
||||||
|
local stack_dir="${1}"
|
||||||
|
local custom_image=""
|
||||||
|
local custom_tag=""
|
||||||
|
|
||||||
|
custom_image="$(get_stack_custom_image_name "${stack_dir}" || true)"
|
||||||
|
custom_tag="$(get_stack_custom_image_tag "${stack_dir}" || true)"
|
||||||
|
if [ -z "${custom_image}" ] || [ -z "${custom_tag}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s:%s\n' "${custom_image}" "${custom_tag}"
|
||||||
|
}
|
||||||
|
|
||||||
|
persist_env_file_key_value() {
|
||||||
|
local env_path="${1}"
|
||||||
|
local key="${2}"
|
||||||
|
local value="${3}"
|
||||||
|
local tmp_path=""
|
||||||
|
|
||||||
|
if [ ! -f "${env_path}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp_path="${env_path}.tmp"
|
||||||
|
if ! awk -v key="${key}" -v value="${value}" '
|
||||||
|
BEGIN {
|
||||||
|
updated = 0
|
||||||
|
}
|
||||||
|
{
|
||||||
|
line = $0
|
||||||
|
sub(/\r$/, "", line)
|
||||||
|
|
||||||
|
if (line ~ "^[[:space:]]*(export[[:space:]]+)?" key "[[:space:]]*=") {
|
||||||
|
print key "=" value
|
||||||
|
updated = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
print line
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (!updated) {
|
||||||
|
print key "=" value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "${env_path}" >"${tmp_path}"; then
|
||||||
|
rm -f -- "${tmp_path}" >/dev/null 2>&1 || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! mv -- "${tmp_path}" "${env_path}"; then
|
||||||
|
rm -f -- "${tmp_path}" >/dev/null 2>&1 || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
set_stack_custom_image_tag() {
|
||||||
|
local stack_dir="${1}"
|
||||||
|
local custom_tag="${2:-}"
|
||||||
|
local env_path=""
|
||||||
|
local custom_image=""
|
||||||
|
|
||||||
|
env_path="$(get_stack_env_path "${stack_dir}")"
|
||||||
|
if [ ! -f "${env_path}" ]; then
|
||||||
|
return 31
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! is_valid_docker_image_tag "${custom_tag}"; then
|
||||||
|
return 32
|
||||||
|
fi
|
||||||
|
|
||||||
|
custom_image="$(get_env_file_key_value "${env_path}" "CUSTOM_IMAGE" || true)"
|
||||||
|
if [ -z "${custom_image}" ]; then
|
||||||
|
return 33
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! persist_env_file_key_value "${env_path}" "CUSTOM_TAG" "${custom_tag}"; then
|
||||||
|
return 34
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_stack_custom_image_tag_with_cancel() {
|
||||||
|
local result_var="${1}"
|
||||||
|
local stack_dir="${2}"
|
||||||
|
local current_image=""
|
||||||
|
local current_tag=""
|
||||||
|
local guidance_text=""
|
||||||
|
local custom_tag=""
|
||||||
|
local prompt_status=0
|
||||||
|
|
||||||
|
current_image="$(get_stack_custom_image_name "${stack_dir}" || true)"
|
||||||
|
current_tag="$(get_stack_custom_image_tag "${stack_dir}" || true)"
|
||||||
|
guidance_text="$(printf "Current custom image: %s\nCurrent custom tag: %s\n\nEnter the next CUSTOM_TAG for the rebuilt image.\nExample: v1.4.3 or 2026-04-02-appupdate.\nType /back to return." "${current_image:-n/a}" "${current_tag:-n/a}")"
|
||||||
|
|
||||||
|
if prompt_env_value_with_validation custom_tag "${stack_dir}" "CUSTOM_TAG" "${guidance_text}" "${current_tag}" "required" "image_tag"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
prompt_status=$?
|
||||||
|
return "${prompt_status}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf -v "${result_var}" "%s" "${custom_tag}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
@ -342,6 +342,16 @@ is_valid_domains_value() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_valid_image_tag_value() {
|
||||||
|
local value="${1}"
|
||||||
|
|
||||||
|
if ! is_valid_docker_image_tag "${value}"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
prompt_env_value_with_validation() {
|
prompt_env_value_with_validation() {
|
||||||
local result_var="${1}"
|
local result_var="${1}"
|
||||||
local stack_dir="${2}"
|
local stack_dir="${2}"
|
||||||
|
|
@ -413,6 +423,12 @@ prompt_env_value_with_validation() {
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
image_tag)
|
||||||
|
if ! is_valid_image_tag_value "${normalized_value}"; then
|
||||||
|
validation_feedback="Invalid image tag for ${variable_name}. Use letters, numbers, dots, dashes, or underscores."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
;;
|
||||||
none | "") ;;
|
none | "") ;;
|
||||||
*)
|
*)
|
||||||
show_warning_message "Unknown validation rule: ${validation_kind}"
|
show_warning_message "Unknown validation rule: ${validation_kind}"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,21 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
refresh_stack_generated_compose_with_feedback() {
|
||||||
|
local stack_dir="${1}"
|
||||||
|
local generated_compose_path=""
|
||||||
|
local render_compose_status=0
|
||||||
|
|
||||||
|
generated_compose_path="$(get_stack_generated_compose_path "${stack_dir}")"
|
||||||
|
if render_stack_compose_from_metadata "${stack_dir}"; then
|
||||||
|
show_warning_and_wait "Generated compose refreshed successfully: ${generated_compose_path}" 3
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
render_compose_status=$?
|
||||||
|
show_warning_and_wait "The image build succeeded, but generated compose could not be refreshed (${render_compose_status}) for ${generated_compose_path}." 4
|
||||||
|
return "${render_compose_status}"
|
||||||
|
}
|
||||||
|
|
||||||
run_build_stack_custom_image_with_feedback() {
|
run_build_stack_custom_image_with_feedback() {
|
||||||
local stack_name="${1}"
|
local stack_name="${1}"
|
||||||
local stack_dir="${2}"
|
local stack_dir="${2}"
|
||||||
|
|
@ -8,6 +24,7 @@ run_build_stack_custom_image_with_feedback() {
|
||||||
show_warning_message "Starting docker build for stack: ${stack_name}"
|
show_warning_message "Starting docker build for stack: ${stack_name}"
|
||||||
if build_stack_custom_image "${stack_dir}"; then
|
if build_stack_custom_image "${stack_dir}"; then
|
||||||
show_warning_and_wait "Custom image build finished successfully for stack: ${stack_name}" 3
|
show_warning_and_wait "Custom image build finished successfully for stack: ${stack_name}" 3
|
||||||
|
refresh_stack_generated_compose_with_feedback "${stack_dir}" || true
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
build_image_status=$?
|
build_image_status=$?
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,18 @@ handle_manage_selected_stack_flow() {
|
||||||
local stack_dir=""
|
local stack_dir=""
|
||||||
local stack_action=""
|
local stack_action=""
|
||||||
local apps_action=""
|
local apps_action=""
|
||||||
local docker_action=""
|
local updates_action=""
|
||||||
local stack_metadata_path=""
|
local stack_metadata_path=""
|
||||||
local stack_apps_path=""
|
local stack_apps_path=""
|
||||||
|
local stack_env_path=""
|
||||||
local custom_apps_update_status=0
|
local custom_apps_update_status=0
|
||||||
local persist_apps_status=0
|
|
||||||
local render_compose_status=0
|
|
||||||
local compose_start_status=0
|
local compose_start_status=0
|
||||||
local generated_compose_path=""
|
|
||||||
local stack_runtime_status=""
|
local stack_runtime_status=""
|
||||||
|
local stack_frappe_branch=""
|
||||||
|
local stack_custom_image_ref=""
|
||||||
|
local stack_custom_tag=""
|
||||||
|
local custom_tag_prompt_status=0
|
||||||
|
local custom_tag_update_status=0
|
||||||
local missing_custom_image_action=""
|
local missing_custom_image_action=""
|
||||||
local delete_stack_confirmation_action=""
|
local delete_stack_confirmation_action=""
|
||||||
local delete_stack_keyword=""
|
local delete_stack_keyword=""
|
||||||
|
|
@ -26,30 +29,14 @@ handle_manage_selected_stack_flow() {
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
get_stack_compose_runtime_status_label stack_runtime_status "${stack_dir}"
|
get_stack_compose_runtime_status_label stack_runtime_status "${stack_dir}"
|
||||||
|
stack_frappe_branch="$(get_stack_frappe_branch "${stack_dir}" || true)"
|
||||||
|
stack_custom_image_ref="$(get_stack_custom_image_ref "${stack_dir}" || true)"
|
||||||
stack_action="$(show_manage_stack_actions_menu "${stack_name}" "${stack_dir}" "${stack_runtime_status}" || true)"
|
stack_action="$(show_manage_stack_actions_menu "${stack_name}" "${stack_dir}" "${stack_runtime_status}" || true)"
|
||||||
case "${stack_action}" in
|
case "${stack_action}" in
|
||||||
"Apps")
|
"Apps")
|
||||||
while true; do
|
while true; do
|
||||||
apps_action="$(show_manage_stack_apps_menu "${stack_name}" "${stack_dir}" || true)"
|
apps_action="$(show_manage_stack_apps_menu "${stack_name}" "${stack_dir}" "${stack_frappe_branch}" || true)"
|
||||||
case "${apps_action}" in
|
case "${apps_action}" in
|
||||||
"Regenerate apps.json from metadata")
|
|
||||||
stack_metadata_path="${stack_dir}/metadata.json"
|
|
||||||
stack_apps_path="${stack_dir}/apps.json"
|
|
||||||
if [ ! -f "${stack_metadata_path}" ]; then
|
|
||||||
show_warning_and_wait "Cannot generate apps.json because metadata is missing: ${stack_metadata_path}" 3
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if persist_stack_apps_json_from_metadata_apps "${stack_dir}"; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
persist_apps_status=$?
|
|
||||||
show_warning_and_wait "Could not generate ${stack_apps_path} (${persist_apps_status})." 3
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
show_warning_and_wait "apps.json generated successfully: ${stack_apps_path}" 3
|
|
||||||
;;
|
|
||||||
"Select apps and branches")
|
"Select apps and branches")
|
||||||
if update_stack_custom_modular_apps "${stack_dir}"; then
|
if update_stack_custom_modular_apps "${stack_dir}"; then
|
||||||
:
|
:
|
||||||
|
|
@ -86,6 +73,112 @@ handle_manage_selected_stack_flow() {
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
|
"Updates")
|
||||||
|
while true; do
|
||||||
|
stack_custom_image_ref="$(get_stack_custom_image_ref "${stack_dir}" || true)"
|
||||||
|
updates_action="$(show_manage_stack_updates_menu "${stack_name}" "${stack_dir}" "${stack_frappe_branch}" "${stack_custom_image_ref}" || true)"
|
||||||
|
case "${updates_action}" in
|
||||||
|
"Update selected app branches")
|
||||||
|
if update_stack_selected_app_branches "${stack_dir}"; then
|
||||||
|
stack_apps_path="${stack_dir}/apps.json"
|
||||||
|
show_warning_and_wait "Selected app branches updated in ${stack_dir}/metadata.json and ${stack_apps_path}. Set the next custom image tag, build the updated image, restart the stack, and migrate the site to apply the update." 6
|
||||||
|
else
|
||||||
|
custom_apps_update_status=$?
|
||||||
|
case "${custom_apps_update_status}" in
|
||||||
|
2 | 130)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
stack_metadata_path="${stack_dir}/metadata.json"
|
||||||
|
show_warning_and_wait "Cannot update selected app branches because metadata is missing: ${stack_metadata_path}" 3
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
show_warning_and_wait "No selected stack apps were found for branch updates. Select apps for the stack first." 4
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_warning_and_wait "Could not update selected app branches (${custom_apps_update_status}) for stack: ${stack_name}" 3
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"Set next custom image tag")
|
||||||
|
stack_env_path="$(get_stack_env_path "${stack_dir}")"
|
||||||
|
if [ ! -f "${stack_env_path}" ]; then
|
||||||
|
show_warning_and_wait "Cannot update CUSTOM_TAG because the stack env file is missing: ${stack_env_path}" 4
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$(get_stack_custom_image_name "${stack_dir}" || true)" ]; then
|
||||||
|
show_warning_and_wait "Cannot update CUSTOM_TAG because CUSTOM_IMAGE is missing in the stack env file." 4
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if prompt_stack_custom_image_tag_with_cancel stack_custom_tag "${stack_dir}"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
custom_tag_prompt_status=$?
|
||||||
|
case "${custom_tag_prompt_status}" in
|
||||||
|
2 | 130)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_warning_and_wait "Could not collect the next custom image tag (${custom_tag_prompt_status})." 3
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if set_stack_custom_image_tag "${stack_dir}" "${stack_custom_tag}"; then
|
||||||
|
stack_custom_image_ref="$(get_stack_custom_image_ref "${stack_dir}" || true)"
|
||||||
|
show_warning_message "Custom image tag updated successfully: ${stack_custom_image_ref:-${stack_custom_tag}}"
|
||||||
|
if run_build_stack_custom_image_with_feedback "${stack_name}" "${stack_dir}"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
custom_tag_update_status=$?
|
||||||
|
case "${custom_tag_update_status}" in
|
||||||
|
31)
|
||||||
|
show_warning_and_wait "Cannot update CUSTOM_TAG because the stack env file is missing: ${stack_env_path}" 4
|
||||||
|
;;
|
||||||
|
32)
|
||||||
|
show_warning_and_wait "Cannot update CUSTOM_TAG because the value is not a valid Docker image tag." 4
|
||||||
|
;;
|
||||||
|
33)
|
||||||
|
show_warning_and_wait "Cannot update CUSTOM_TAG because CUSTOM_IMAGE is missing in the stack env file." 4
|
||||||
|
;;
|
||||||
|
34)
|
||||||
|
show_warning_and_wait "Could not write the updated CUSTOM_TAG to ${stack_env_path}." 4
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_warning_and_wait "Could not update CUSTOM_TAG (${custom_tag_update_status})." 4
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"Build updated image")
|
||||||
|
if run_build_stack_custom_image_with_feedback "${stack_name}" "${stack_dir}"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"Back" | "")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
"Exit and close easy-docker")
|
||||||
|
return "${FLOW_EXIT_APP}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_warning_and_wait "Unknown update action: ${updates_action}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
;;
|
||||||
"Start stack in Docker Compose")
|
"Start stack in Docker Compose")
|
||||||
while true; do
|
while true; do
|
||||||
show_warning_message "Starting stack with docker compose: ${stack_name}"
|
show_warning_message "Starting stack with docker compose: ${stack_name}"
|
||||||
|
|
@ -329,41 +422,6 @@ handle_manage_selected_stack_flow() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
"Docker")
|
|
||||||
while true; do
|
|
||||||
docker_action="$(show_manage_stack_docker_menu "${stack_name}" "${stack_dir}" || true)"
|
|
||||||
case "${docker_action}" in
|
|
||||||
"Build custom image")
|
|
||||||
if run_build_stack_custom_image_with_feedback "${stack_name}" "${stack_dir}"; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"Generate docker compose from env")
|
|
||||||
generated_compose_path="$(get_stack_generated_compose_path "${stack_dir}")"
|
|
||||||
if render_stack_compose_from_metadata "${stack_dir}"; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
render_compose_status=$?
|
|
||||||
show_warning_and_wait "Could not generate docker compose (${render_compose_status}) for ${generated_compose_path}." 3
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
show_warning_and_wait "Docker compose generated successfully: ${generated_compose_path}" 3
|
|
||||||
;;
|
|
||||||
"Back" | "")
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
"Exit and close easy-docker")
|
|
||||||
return "${FLOW_EXIT_APP}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
show_warning_and_wait "Unknown docker action: ${docker_action}"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
"Site")
|
"Site")
|
||||||
if handle_manage_stack_site_flow "${stack_name}" "${stack_dir}"; then
|
if handle_manage_stack_site_flow "${stack_name}" "${stack_dir}"; then
|
||||||
:
|
:
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ show_manage_stack_actions_menu() {
|
||||||
--cursor.foreground 63 \
|
--cursor.foreground 63 \
|
||||||
--selected.foreground 45 \
|
--selected.foreground 45 \
|
||||||
"Apps" \
|
"Apps" \
|
||||||
"Docker" \
|
"Updates" \
|
||||||
"Site" \
|
"Site" \
|
||||||
"Start stack in Docker Compose" \
|
"Start stack in Docker Compose" \
|
||||||
"Restart stack in Docker Compose" \
|
"Restart stack in Docker Compose" \
|
||||||
|
|
@ -83,11 +83,12 @@ show_manage_stack_actions_menu() {
|
||||||
show_manage_stack_apps_menu() {
|
show_manage_stack_apps_menu() {
|
||||||
local stack_name="${1}"
|
local stack_name="${1}"
|
||||||
local stack_dir="${2}"
|
local stack_dir="${2}"
|
||||||
|
local frappe_branch="${3:-n/a}"
|
||||||
local status_text=""
|
local status_text=""
|
||||||
|
|
||||||
render_main_screen 1 >&2
|
render_main_screen 1 >&2
|
||||||
|
|
||||||
status_text="$(printf "Manage stack apps\n\nStack: %s\nDirectory: %s\n\nChoose an app-related action for this stack." "${stack_name}" "${stack_dir}")"
|
status_text="$(printf "Manage stack apps\n\nStack: %s\nDirectory: %s\nFrappe branch: %s\n\nChoose an app-related action for this stack." "${stack_name}" "${stack_dir}" "${frappe_branch}")"
|
||||||
|
|
||||||
render_box_message "${status_text}" "0 2" >&2
|
render_box_message "${status_text}" "0 2" >&2
|
||||||
|
|
||||||
|
|
@ -96,30 +97,32 @@ show_manage_stack_apps_menu() {
|
||||||
--header "Stack apps actions" \
|
--header "Stack apps actions" \
|
||||||
--cursor.foreground 63 \
|
--cursor.foreground 63 \
|
||||||
--selected.foreground 45 \
|
--selected.foreground 45 \
|
||||||
"Regenerate apps.json from metadata" \
|
|
||||||
"Select apps and branches" \
|
"Select apps and branches" \
|
||||||
"Back" \
|
"Back" \
|
||||||
"Exit and close easy-docker"
|
"Exit and close easy-docker"
|
||||||
}
|
}
|
||||||
|
|
||||||
show_manage_stack_docker_menu() {
|
show_manage_stack_updates_menu() {
|
||||||
local stack_name="${1}"
|
local stack_name="${1}"
|
||||||
local stack_dir="${2}"
|
local stack_dir="${2}"
|
||||||
|
local frappe_branch="${3:-n/a}"
|
||||||
|
local custom_image_ref="${4:-n/a}"
|
||||||
local status_text=""
|
local status_text=""
|
||||||
|
|
||||||
render_main_screen 1 >&2
|
render_main_screen 1 >&2
|
||||||
|
|
||||||
status_text="$(printf "Manage stack docker\n\nStack: %s\nDirectory: %s\n\nChoose a docker-related action for this stack." "${stack_name}" "${stack_dir}")"
|
status_text="$(printf "Manage stack updates\n\nStack: %s\nDirectory: %s\nFrappe branch: %s\nCustom image: %s\n\nChoose an update-related action for this stack." "${stack_name}" "${stack_dir}" "${frappe_branch}" "${custom_image_ref}")"
|
||||||
|
|
||||||
render_box_message "${status_text}" "0 2" >&2
|
render_box_message "${status_text}" "0 2" >&2
|
||||||
|
|
||||||
gum choose \
|
gum choose \
|
||||||
--height 8 \
|
--height 9 \
|
||||||
--header "Stack docker actions" \
|
--header "Stack update actions" \
|
||||||
--cursor.foreground 63 \
|
--cursor.foreground 63 \
|
||||||
--selected.foreground 45 \
|
--selected.foreground 45 \
|
||||||
"Build custom image" \
|
"Update selected app branches" \
|
||||||
"Generate docker compose from env" \
|
"Set next custom image tag" \
|
||||||
|
"Build updated image" \
|
||||||
"Back" \
|
"Back" \
|
||||||
"Exit and close easy-docker"
|
"Exit and close easy-docker"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue