mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-17 13:55:08 +00:00
feat(easy-docker): manage apps on existing sites
This commit is contained in:
parent
227d6652b8
commit
2c97955a07
4 changed files with 760 additions and 2 deletions
|
|
@ -1,5 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
load_easy_docker_site_apps_modules() {
|
||||
local apps_dir=""
|
||||
apps_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/apps"
|
||||
|
||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/common/site/apps/lifecycle.sh
|
||||
source "${apps_dir}/lifecycle.sh"
|
||||
}
|
||||
|
||||
append_stack_installable_app_line() {
|
||||
local result_var="${1}"
|
||||
local existing_lines="${2:-}"
|
||||
|
|
@ -74,3 +82,5 @@ get_stack_selected_installable_apps() {
|
|||
printf -v "${result_var}" "%s" "${ordered_app_lines}"
|
||||
return 0
|
||||
}
|
||||
|
||||
load_easy_docker_site_apps_modules
|
||||
|
|
|
|||
437
scripts/easy-docker/lib/app/wizard/common/site/apps/lifecycle.sh
Executable file
437
scripts/easy-docker/lib/app/wizard/common/site/apps/lifecycle.sh
Executable file
|
|
@ -0,0 +1,437 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
stack_site_app_lines_contain() {
|
||||
local app_lines="${1:-}"
|
||||
local app_name="${2:-}"
|
||||
|
||||
if [ -z "${app_name}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
printf '%s\n' "${app_lines}" | grep -F -x -- "${app_name}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
remove_stack_site_app_line() {
|
||||
local result_var="${1}"
|
||||
local existing_lines="${2:-}"
|
||||
local app_name="${3:-}"
|
||||
local existing_app=""
|
||||
local remaining_lines=""
|
||||
|
||||
while IFS= read -r existing_app; do
|
||||
if [ -z "${existing_app}" ] || [ "${existing_app}" = "${app_name}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "${remaining_lines}" ]; then
|
||||
remaining_lines="${existing_app}"
|
||||
else
|
||||
remaining_lines="${remaining_lines}"$'\n'"${existing_app}"
|
||||
fi
|
||||
done <<EOF
|
||||
${existing_lines}
|
||||
EOF
|
||||
|
||||
printf -v "${result_var}" "%s" "${remaining_lines}"
|
||||
}
|
||||
|
||||
get_stack_site_managed_runtime_app_lines() {
|
||||
local result_var="${1}"
|
||||
local stack_dir="${2}"
|
||||
local site_name="${3}"
|
||||
local runtime_app_lines=""
|
||||
local app_name=""
|
||||
local managed_app_lines=""
|
||||
local runtime_status=0
|
||||
|
||||
if ! is_safe_stack_site_cleanup_name "${site_name}"; then
|
||||
return 61
|
||||
fi
|
||||
|
||||
if runtime_app_lines="$(get_stack_site_runtime_app_names_lines "${stack_dir}" "${site_name}")"; then
|
||||
:
|
||||
runtime_status=0
|
||||
else
|
||||
runtime_status=$?
|
||||
fi
|
||||
if [ "${runtime_status}" -eq 54 ] || [ "${runtime_status}" -eq 52 ]; then
|
||||
return "${runtime_status}"
|
||||
fi
|
||||
|
||||
if [ -z "${runtime_app_lines}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
while IFS= read -r app_name; do
|
||||
if [ -z "${app_name}" ] || [ "${app_name}" = "frappe" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
append_stack_installable_app_line managed_app_lines "${managed_app_lines}" "${app_name}"
|
||||
done <<EOF
|
||||
${runtime_app_lines}
|
||||
EOF
|
||||
|
||||
printf -v "${result_var}" "%s" "${managed_app_lines}"
|
||||
return 0
|
||||
}
|
||||
|
||||
persist_stack_site_app_operation_metadata() {
|
||||
local stack_dir="${1}"
|
||||
local site_name="${2}"
|
||||
local apps_installed_lines="${3:-}"
|
||||
local last_action="${4:-manage-site-apps}"
|
||||
local last_error="${5:-}"
|
||||
local error_log_path="${6:-}"
|
||||
local created_at=""
|
||||
local updated_at=""
|
||||
|
||||
created_at="$(get_stack_site_created_at "${stack_dir}" || true)"
|
||||
updated_at="$(get_current_utc_timestamp)"
|
||||
|
||||
persist_stack_site_metadata \
|
||||
"${stack_dir}" \
|
||||
"single-site" \
|
||||
"${site_name}" \
|
||||
"${apps_installed_lines}" \
|
||||
"${last_action}" \
|
||||
"${last_error}" \
|
||||
"${error_log_path}" \
|
||||
"${created_at}" \
|
||||
"${updated_at}"
|
||||
}
|
||||
|
||||
get_configured_stack_site_installable_app_lines() {
|
||||
local result_var="${1}"
|
||||
local stack_dir="${2}"
|
||||
local site_name=""
|
||||
local backend_status=0
|
||||
local selected_app_lines=""
|
||||
local available_app_lines=""
|
||||
local installed_app_lines=""
|
||||
local candidate_app=""
|
||||
local installable_app_lines=""
|
||||
local inspect_status=0
|
||||
|
||||
if ! stack_supports_single_site_management "${stack_dir}"; then
|
||||
return 82
|
||||
fi
|
||||
|
||||
site_name="$(get_stack_site_name "${stack_dir}" || true)"
|
||||
if ! is_safe_stack_site_cleanup_name "${site_name}"; then
|
||||
return 83
|
||||
fi
|
||||
|
||||
if stack_backend_service_is_running "${stack_dir}"; then
|
||||
:
|
||||
else
|
||||
backend_status=$?
|
||||
case "${backend_status}" in
|
||||
54)
|
||||
return 84
|
||||
;;
|
||||
52)
|
||||
return 82
|
||||
;;
|
||||
*)
|
||||
return 81
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! get_stack_selected_installable_apps selected_app_lines "${stack_dir}"; then
|
||||
return 84
|
||||
fi
|
||||
|
||||
if available_app_lines="$(get_stack_runtime_available_app_lines "${stack_dir}")"; then
|
||||
:
|
||||
else
|
||||
inspect_status=$?
|
||||
case "${inspect_status}" in
|
||||
54)
|
||||
return 84
|
||||
;;
|
||||
52)
|
||||
return 82
|
||||
;;
|
||||
*)
|
||||
return 87
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if get_stack_site_managed_runtime_app_lines installed_app_lines "${stack_dir}" "${site_name}"; then
|
||||
:
|
||||
else
|
||||
inspect_status=$?
|
||||
case "${inspect_status}" in
|
||||
54)
|
||||
return 84
|
||||
;;
|
||||
52)
|
||||
return 82
|
||||
;;
|
||||
61)
|
||||
return 83
|
||||
;;
|
||||
*)
|
||||
return 87
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
while IFS= read -r candidate_app; do
|
||||
if [ -z "${candidate_app}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! stack_site_app_lines_contain "${available_app_lines}" "${candidate_app}"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if stack_site_app_lines_contain "${installed_app_lines}" "${candidate_app}"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
append_stack_installable_app_line installable_app_lines "${installable_app_lines}" "${candidate_app}"
|
||||
done <<EOF
|
||||
${selected_app_lines}
|
||||
EOF
|
||||
|
||||
printf -v "${result_var}" "%s" "${installable_app_lines}"
|
||||
return 0
|
||||
}
|
||||
|
||||
get_configured_stack_site_uninstallable_app_lines() {
|
||||
local result_var="${1}"
|
||||
local stack_dir="${2}"
|
||||
local site_name=""
|
||||
local backend_status=0
|
||||
local installed_app_lines=""
|
||||
|
||||
if ! stack_supports_single_site_management "${stack_dir}"; then
|
||||
return 92
|
||||
fi
|
||||
|
||||
site_name="$(get_stack_site_name "${stack_dir}" || true)"
|
||||
if ! is_safe_stack_site_cleanup_name "${site_name}"; then
|
||||
return 93
|
||||
fi
|
||||
|
||||
if stack_backend_service_is_running "${stack_dir}"; then
|
||||
:
|
||||
else
|
||||
backend_status=$?
|
||||
case "${backend_status}" in
|
||||
54)
|
||||
return 94
|
||||
;;
|
||||
52)
|
||||
return 92
|
||||
;;
|
||||
*)
|
||||
return 91
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if get_stack_site_managed_runtime_app_lines installed_app_lines "${stack_dir}" "${site_name}"; then
|
||||
:
|
||||
else
|
||||
backend_status=$?
|
||||
case "${backend_status}" in
|
||||
54)
|
||||
return 94
|
||||
;;
|
||||
52)
|
||||
return 92
|
||||
;;
|
||||
61)
|
||||
return 93
|
||||
;;
|
||||
*)
|
||||
return 97
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
printf -v "${result_var}" "%s" "${installed_app_lines}"
|
||||
return 0
|
||||
}
|
||||
|
||||
install_app_on_configured_stack_site() {
|
||||
local stack_dir="${1}"
|
||||
local app_name="${2:-}"
|
||||
local site_name=""
|
||||
local installable_app_lines=""
|
||||
local current_installed_app_lines=""
|
||||
local updated_installed_app_lines=""
|
||||
local install_command=""
|
||||
local install_output=""
|
||||
local command_status=0
|
||||
local installable_status=0
|
||||
|
||||
reset_easy_docker_site_error_state
|
||||
|
||||
if [ -z "${app_name}" ]; then
|
||||
return 86
|
||||
fi
|
||||
|
||||
if get_configured_stack_site_installable_app_lines installable_app_lines "${stack_dir}"; then
|
||||
:
|
||||
else
|
||||
installable_status=$?
|
||||
return "${installable_status}"
|
||||
fi
|
||||
|
||||
if [ -z "${installable_app_lines}" ]; then
|
||||
return 85
|
||||
fi
|
||||
|
||||
site_name="$(get_stack_site_name "${stack_dir}" || true)"
|
||||
if ! get_stack_site_managed_runtime_app_lines current_installed_app_lines "${stack_dir}" "${site_name}"; then
|
||||
current_installed_app_lines="$(get_stack_site_apps_installed_lines "${stack_dir}" || true)"
|
||||
fi
|
||||
|
||||
if ! stack_site_app_lines_contain "${installable_app_lines}" "${app_name}"; then
|
||||
return 86
|
||||
fi
|
||||
|
||||
install_command="$(
|
||||
printf "bench --site %s install-app %s" \
|
||||
"$(shell_quote_site_command_arg "${site_name}")" \
|
||||
"$(shell_quote_site_command_arg "${app_name}")"
|
||||
)"
|
||||
|
||||
if run_stack_backend_bash_command_capture install_output "${stack_dir}" "${install_command}"; then
|
||||
:
|
||||
else
|
||||
command_status=$?
|
||||
EASY_DOCKER_SITE_ERROR_DETAIL="$(printf "bench install-app failed for '%s'." "${app_name}")"
|
||||
capture_stack_site_error_log "${stack_dir}" "site-install-app-error" "${install_output}" >/dev/null 2>&1 || true
|
||||
if ! persist_stack_site_app_operation_metadata \
|
||||
"${stack_dir}" \
|
||||
"${site_name}" \
|
||||
"${current_installed_app_lines}" \
|
||||
"install-app" \
|
||||
"${EASY_DOCKER_SITE_ERROR_DETAIL}" \
|
||||
"${EASY_DOCKER_SITE_ERROR_LOG_PATH}"; then
|
||||
return 89
|
||||
fi
|
||||
case "${command_status}" in
|
||||
54)
|
||||
return 84
|
||||
;;
|
||||
52)
|
||||
return 82
|
||||
;;
|
||||
*)
|
||||
return 88
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! get_stack_site_managed_runtime_app_lines updated_installed_app_lines "${stack_dir}" "${site_name}"; then
|
||||
updated_installed_app_lines="${current_installed_app_lines}"
|
||||
append_stack_installable_app_line updated_installed_app_lines "${updated_installed_app_lines}" "${app_name}"
|
||||
fi
|
||||
|
||||
if ! persist_stack_site_app_operation_metadata \
|
||||
"${stack_dir}" \
|
||||
"${site_name}" \
|
||||
"${updated_installed_app_lines}" \
|
||||
"install-app" \
|
||||
"" \
|
||||
""; then
|
||||
return 89
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
uninstall_app_from_configured_stack_site() {
|
||||
local stack_dir="${1}"
|
||||
local app_name="${2:-}"
|
||||
local site_name=""
|
||||
local uninstallable_app_lines=""
|
||||
local current_installed_app_lines=""
|
||||
local updated_installed_app_lines=""
|
||||
local uninstall_command=""
|
||||
local uninstall_output=""
|
||||
local command_status=0
|
||||
local uninstallable_status=0
|
||||
|
||||
reset_easy_docker_site_error_state
|
||||
|
||||
if [ -z "${app_name}" ] || [ "${app_name}" = "frappe" ]; then
|
||||
return 96
|
||||
fi
|
||||
|
||||
if get_configured_stack_site_uninstallable_app_lines uninstallable_app_lines "${stack_dir}"; then
|
||||
:
|
||||
else
|
||||
uninstallable_status=$?
|
||||
return "${uninstallable_status}"
|
||||
fi
|
||||
|
||||
if [ -z "${uninstallable_app_lines}" ]; then
|
||||
return 95
|
||||
fi
|
||||
|
||||
site_name="$(get_stack_site_name "${stack_dir}" || true)"
|
||||
current_installed_app_lines="${uninstallable_app_lines}"
|
||||
|
||||
if ! stack_site_app_lines_contain "${uninstallable_app_lines}" "${app_name}"; then
|
||||
return 96
|
||||
fi
|
||||
|
||||
uninstall_command="$(
|
||||
printf "bench --site %s uninstall-app %s --yes" \
|
||||
"$(shell_quote_site_command_arg "${site_name}")" \
|
||||
"$(shell_quote_site_command_arg "${app_name}")"
|
||||
)"
|
||||
|
||||
if run_stack_backend_bash_command_capture uninstall_output "${stack_dir}" "${uninstall_command}"; then
|
||||
:
|
||||
else
|
||||
command_status=$?
|
||||
EASY_DOCKER_SITE_ERROR_DETAIL="$(printf "bench uninstall-app failed for '%s'." "${app_name}")"
|
||||
capture_stack_site_error_log "${stack_dir}" "site-uninstall-app-error" "${uninstall_output}" >/dev/null 2>&1 || true
|
||||
if ! persist_stack_site_app_operation_metadata \
|
||||
"${stack_dir}" \
|
||||
"${site_name}" \
|
||||
"${current_installed_app_lines}" \
|
||||
"uninstall-app" \
|
||||
"${EASY_DOCKER_SITE_ERROR_DETAIL}" \
|
||||
"${EASY_DOCKER_SITE_ERROR_LOG_PATH}"; then
|
||||
return 99
|
||||
fi
|
||||
case "${command_status}" in
|
||||
54)
|
||||
return 94
|
||||
;;
|
||||
52)
|
||||
return 92
|
||||
;;
|
||||
*)
|
||||
return 98
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if ! get_stack_site_managed_runtime_app_lines updated_installed_app_lines "${stack_dir}" "${site_name}"; then
|
||||
remove_stack_site_app_line updated_installed_app_lines "${current_installed_app_lines}" "${app_name}"
|
||||
fi
|
||||
|
||||
if ! persist_stack_site_app_operation_metadata \
|
||||
"${stack_dir}" \
|
||||
"${site_name}" \
|
||||
"${updated_installed_app_lines}" \
|
||||
"uninstall-app" \
|
||||
"" \
|
||||
""; then
|
||||
return 99
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
|
@ -14,6 +14,10 @@ handle_manage_stack_site_flow() {
|
|||
local existing_site_apps_csv=""
|
||||
local existing_site_last_backup_at=""
|
||||
local existing_site_details_action=""
|
||||
local existing_site_apps_action=""
|
||||
local existing_site_app_lines=""
|
||||
local existing_site_app_selection=""
|
||||
local existing_site_app_confirmation=""
|
||||
local site_delete_confirmation=""
|
||||
|
||||
while true; do
|
||||
|
|
@ -100,7 +104,7 @@ handle_manage_stack_site_flow() {
|
|||
existing_site_apps_lines="$(get_stack_site_apps_installed_lines "${stack_dir}" || true)"
|
||||
existing_site_last_backup_at="$(get_stack_site_last_backup_at "${stack_dir}" || true)"
|
||||
if stack_backend_service_is_running "${stack_dir}" >/dev/null 2>&1; then
|
||||
get_stack_site_runtime_selected_apps_lines existing_site_apps_lines "${stack_dir}" "${existing_site_name}" || true
|
||||
get_stack_site_managed_runtime_app_lines existing_site_apps_lines "${stack_dir}" "${existing_site_name}" || true
|
||||
fi
|
||||
if [ -n "${existing_site_apps_lines}" ]; then
|
||||
existing_site_apps_csv="$(printf '%s' "${existing_site_apps_lines}" | tr '\n' ',' | sed 's/,$//')"
|
||||
|
|
@ -118,6 +122,230 @@ handle_manage_stack_site_flow() {
|
|||
"${existing_site_last_backup_at}" || true
|
||||
)"
|
||||
case "${existing_site_details_action}" in
|
||||
"Manage apps on this site")
|
||||
while true; do
|
||||
existing_site_apps_action="$(
|
||||
show_manage_stack_site_apps_menu \
|
||||
"${stack_name}" \
|
||||
"${stack_dir}" \
|
||||
"${existing_site_name}" || true
|
||||
)"
|
||||
case "${existing_site_apps_action}" in
|
||||
"Install app on this site")
|
||||
if ! get_configured_stack_site_installable_app_lines existing_site_app_lines "${stack_dir}"; then
|
||||
site_flow_status=$?
|
||||
case "${site_flow_status}" in
|
||||
81)
|
||||
show_warning_and_wait "Cannot install app: backend service is not running yet. Start the stack first." 4
|
||||
;;
|
||||
82)
|
||||
show_warning_and_wait "Cannot install app for this topology yet. Only single-host stacks are supported." 4
|
||||
;;
|
||||
83)
|
||||
show_warning_and_wait "Cannot install app because no configured site was found in metadata.json." 4
|
||||
;;
|
||||
84)
|
||||
show_warning_and_wait "Cannot install app because stack metadata, env, or compose inputs are incomplete." 4
|
||||
;;
|
||||
87)
|
||||
show_warning_and_wait "Cannot inspect installable apps on this site right now. Check backend readiness and try again." 4
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "Could not prepare installable site apps (${site_flow_status})." 4
|
||||
;;
|
||||
esac
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "${existing_site_app_lines}" ]; then
|
||||
show_warning_and_wait "No additional selected stack apps are available to install on this site. No further apps are currently available in this stack environment." 4
|
||||
continue
|
||||
fi
|
||||
|
||||
existing_site_app_selection="$(
|
||||
show_manage_stack_site_app_selection \
|
||||
"${stack_name}" \
|
||||
"${stack_dir}" \
|
||||
"${existing_site_name}" \
|
||||
"Install app on this site" \
|
||||
"${existing_site_app_lines}" || true
|
||||
)"
|
||||
case "${existing_site_app_selection}" in
|
||||
"Back" | "")
|
||||
continue
|
||||
;;
|
||||
"Exit and close easy-docker")
|
||||
return "${FLOW_EXIT_APP}"
|
||||
;;
|
||||
*)
|
||||
show_warning_message "Installing app on site: ${existing_site_app_selection}"
|
||||
if install_app_on_configured_stack_site "${stack_dir}" "${existing_site_app_selection}"; then
|
||||
show_warning_and_wait "App installed successfully on site ${existing_site_name}: ${existing_site_app_selection}" 4
|
||||
continue
|
||||
fi
|
||||
|
||||
site_flow_status=$?
|
||||
case "${site_flow_status}" in
|
||||
81)
|
||||
show_warning_and_wait "Cannot install app: backend service is not running yet. Start the stack first." 4
|
||||
;;
|
||||
82)
|
||||
show_warning_and_wait "Cannot install app for this topology yet. Only single-host stacks are supported." 4
|
||||
;;
|
||||
83)
|
||||
show_warning_and_wait "Cannot install app because no configured site was found in metadata.json." 4
|
||||
;;
|
||||
84)
|
||||
show_warning_and_wait "Cannot install app because stack metadata, env, or compose inputs are incomplete." 4
|
||||
;;
|
||||
85)
|
||||
show_warning_and_wait "No additional selected stack apps are available to install on this site. No further apps are currently available in this stack environment." 4
|
||||
;;
|
||||
86)
|
||||
show_warning_and_wait "The selected app is not currently installable on this site." 4
|
||||
;;
|
||||
87)
|
||||
show_warning_and_wait "Cannot inspect current site apps right now. Check backend readiness and try again." 4
|
||||
;;
|
||||
88)
|
||||
show_warning_and_wait "App installation failed. ${EASY_DOCKER_SITE_ERROR_DETAIL:-Check the output above.} ${EASY_DOCKER_SITE_ERROR_LOG_PATH:+See ${stack_dir}/${EASY_DOCKER_SITE_ERROR_LOG_PATH}}" 6
|
||||
;;
|
||||
89)
|
||||
show_warning_and_wait "The app command finished, but site metadata could not be written to metadata.json." 5
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "App installation failed (${site_flow_status})." 4
|
||||
;;
|
||||
esac
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"Uninstall app from this site")
|
||||
if ! get_configured_stack_site_uninstallable_app_lines existing_site_app_lines "${stack_dir}"; then
|
||||
site_flow_status=$?
|
||||
case "${site_flow_status}" in
|
||||
91)
|
||||
show_warning_and_wait "Cannot uninstall app: backend service is not running yet. Start the stack first." 4
|
||||
;;
|
||||
92)
|
||||
show_warning_and_wait "Cannot uninstall app for this topology yet. Only single-host stacks are supported." 4
|
||||
;;
|
||||
93)
|
||||
show_warning_and_wait "Cannot uninstall app because no configured site was found in metadata.json." 4
|
||||
;;
|
||||
94)
|
||||
show_warning_and_wait "Cannot uninstall app because stack metadata, env, or compose inputs are incomplete." 4
|
||||
;;
|
||||
97)
|
||||
show_warning_and_wait "Cannot inspect uninstallable apps on this site right now. Check backend readiness and try again." 4
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "Could not prepare uninstallable site apps (${site_flow_status})." 4
|
||||
;;
|
||||
esac
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "${existing_site_app_lines}" ]; then
|
||||
show_warning_and_wait "No installed site apps are currently available for uninstall." 4
|
||||
continue
|
||||
fi
|
||||
|
||||
existing_site_app_selection="$(
|
||||
show_manage_stack_site_app_selection \
|
||||
"${stack_name}" \
|
||||
"${stack_dir}" \
|
||||
"${existing_site_name}" \
|
||||
"Uninstall app from this site" \
|
||||
"${existing_site_app_lines}" || true
|
||||
)"
|
||||
case "${existing_site_app_selection}" in
|
||||
"Back" | "")
|
||||
continue
|
||||
;;
|
||||
"Exit and close easy-docker")
|
||||
return "${FLOW_EXIT_APP}"
|
||||
;;
|
||||
*)
|
||||
existing_site_app_confirmation="$(
|
||||
show_manage_stack_site_app_uninstall_confirmation \
|
||||
"${stack_name}" \
|
||||
"${stack_dir}" \
|
||||
"${existing_site_name}" \
|
||||
"${existing_site_app_selection}" || true
|
||||
)"
|
||||
case "${existing_site_app_confirmation}" in
|
||||
"No" | "")
|
||||
continue
|
||||
;;
|
||||
"Exit and close easy-docker")
|
||||
return "${FLOW_EXIT_APP}"
|
||||
;;
|
||||
"Yes")
|
||||
show_warning_message "Uninstalling app from site: ${existing_site_app_selection}"
|
||||
if uninstall_app_from_configured_stack_site "${stack_dir}" "${existing_site_app_selection}"; then
|
||||
show_warning_and_wait "App uninstalled successfully from site ${existing_site_name}: ${existing_site_app_selection}" 4
|
||||
continue
|
||||
fi
|
||||
|
||||
site_flow_status=$?
|
||||
case "${site_flow_status}" in
|
||||
91)
|
||||
show_warning_and_wait "Cannot uninstall app: backend service is not running yet. Start the stack first." 4
|
||||
;;
|
||||
92)
|
||||
show_warning_and_wait "Cannot uninstall app for this topology yet. Only single-host stacks are supported." 4
|
||||
;;
|
||||
93)
|
||||
show_warning_and_wait "Cannot uninstall app because no configured site was found in metadata.json." 4
|
||||
;;
|
||||
94)
|
||||
show_warning_and_wait "Cannot uninstall app because stack metadata, env, or compose inputs are incomplete." 4
|
||||
;;
|
||||
95)
|
||||
show_warning_and_wait "No installed site apps are currently available for uninstall." 4
|
||||
;;
|
||||
96)
|
||||
show_warning_and_wait "The selected app cannot be uninstalled here. frappe stays blocked, but erpnext is allowed." 4
|
||||
;;
|
||||
97)
|
||||
show_warning_and_wait "Cannot inspect current site apps right now. Check backend readiness and try again." 4
|
||||
;;
|
||||
98)
|
||||
show_warning_and_wait "App uninstall failed. ${EASY_DOCKER_SITE_ERROR_DETAIL:-Check the output above.} ${EASY_DOCKER_SITE_ERROR_LOG_PATH:+See ${stack_dir}/${EASY_DOCKER_SITE_ERROR_LOG_PATH}}" 6
|
||||
;;
|
||||
99)
|
||||
show_warning_and_wait "The app command finished, but site metadata could not be written to metadata.json." 5
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "App uninstall failed (${site_flow_status})." 4
|
||||
;;
|
||||
esac
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "Unknown uninstall app confirmation action: ${existing_site_app_confirmation}" 2
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"Back" | "")
|
||||
break
|
||||
;;
|
||||
"Exit and close easy-docker")
|
||||
return "${FLOW_EXIT_APP}"
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "Unknown site apps action: ${existing_site_apps_action}" 2
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
done
|
||||
continue
|
||||
;;
|
||||
"Backup site now")
|
||||
show_warning_message "Creating backup for site: ${existing_site_name}"
|
||||
if backup_configured_stack_site "${stack_dir}"; then
|
||||
|
|
|
|||
|
|
@ -204,16 +204,99 @@ show_manage_stack_site_details() {
|
|||
render_box_message "${status_text}" "0 2" >&2
|
||||
|
||||
gum choose \
|
||||
--height 9 \
|
||||
--height 10 \
|
||||
--header "Site details" \
|
||||
--cursor.foreground 63 \
|
||||
--selected.foreground 45 \
|
||||
"Manage apps on this site" \
|
||||
"Backup site now" \
|
||||
"Delete site" \
|
||||
"Back" \
|
||||
"Exit and close easy-docker"
|
||||
}
|
||||
|
||||
show_manage_stack_site_apps_menu() {
|
||||
local stack_name="${1}"
|
||||
local stack_dir="${2}"
|
||||
local site_name="${3}"
|
||||
local status_text=""
|
||||
|
||||
render_main_screen 1 >&2
|
||||
|
||||
status_text="$(printf "Manage site apps\n\nStack: %s\nDirectory: %s\nSite: %s\n\nInstall or uninstall apps for this existing site." "${stack_name}" "${stack_dir}" "${site_name}")"
|
||||
render_box_message "${status_text}" "0 2" >&2
|
||||
|
||||
gum choose \
|
||||
--height 9 \
|
||||
--header "Site app actions" \
|
||||
--cursor.foreground 63 \
|
||||
--selected.foreground 45 \
|
||||
"Install app on this site" \
|
||||
"Uninstall app from this site" \
|
||||
"Back" \
|
||||
"Exit and close easy-docker"
|
||||
}
|
||||
|
||||
show_manage_stack_site_app_selection() {
|
||||
local stack_name="${1}"
|
||||
local stack_dir="${2}"
|
||||
local site_name="${3}"
|
||||
local action_label="${4}"
|
||||
local app_lines="${5:-}"
|
||||
local status_text=""
|
||||
local app_name=""
|
||||
local -a menu_options=()
|
||||
|
||||
render_main_screen 1 >&2
|
||||
|
||||
status_text="$(printf "%s\n\nStack: %s\nDirectory: %s\nSite: %s\n\nSelect one app." "${action_label}" "${stack_name}" "${stack_dir}" "${site_name}")"
|
||||
render_box_message "${status_text}" "0 2" >&2
|
||||
|
||||
while IFS= read -r app_name; do
|
||||
if [ -z "${app_name}" ]; then
|
||||
continue
|
||||
fi
|
||||
menu_options+=("${app_name}")
|
||||
done <<EOF
|
||||
${app_lines}
|
||||
EOF
|
||||
|
||||
if [ "${#menu_options[@]}" -eq 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
gum choose \
|
||||
--height 12 \
|
||||
--header "${action_label}" \
|
||||
--cursor.foreground 63 \
|
||||
--selected.foreground 45 \
|
||||
"${menu_options[@]}" \
|
||||
"Back" \
|
||||
"Exit and close easy-docker"
|
||||
}
|
||||
|
||||
show_manage_stack_site_app_uninstall_confirmation() {
|
||||
local stack_name="${1}"
|
||||
local stack_dir="${2}"
|
||||
local site_name="${3}"
|
||||
local app_name="${4}"
|
||||
local status_text=""
|
||||
|
||||
render_main_screen 1 >&2
|
||||
|
||||
status_text="$(printf "Uninstall app from site\n\nStack: %s\nDirectory: %s\nSite: %s\nApp: %s\n\nThis removes the app from the site. frappe itself cannot be removed here." "${stack_name}" "${stack_dir}" "${site_name}" "${app_name}")"
|
||||
render_box_message "${status_text}" "0 2" >&2
|
||||
|
||||
gum choose \
|
||||
--height 8 \
|
||||
--header "Confirm uninstall app" \
|
||||
--cursor.foreground 63 \
|
||||
--selected.foreground 45 \
|
||||
"Yes" \
|
||||
"No" \
|
||||
"Exit and close easy-docker"
|
||||
}
|
||||
|
||||
show_manage_stack_site_delete_confirmation() {
|
||||
local stack_name="${1}"
|
||||
local stack_dir="${2}"
|
||||
|
|
|
|||
Loading…
Reference in a new issue