mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-21 23:35:09 +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
|
#!/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() {
|
append_stack_installable_app_line() {
|
||||||
local result_var="${1}"
|
local result_var="${1}"
|
||||||
local existing_lines="${2:-}"
|
local existing_lines="${2:-}"
|
||||||
|
|
@ -74,3 +82,5 @@ get_stack_selected_installable_apps() {
|
||||||
printf -v "${result_var}" "%s" "${ordered_app_lines}"
|
printf -v "${result_var}" "%s" "${ordered_app_lines}"
|
||||||
return 0
|
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_apps_csv=""
|
||||||
local existing_site_last_backup_at=""
|
local existing_site_last_backup_at=""
|
||||||
local existing_site_details_action=""
|
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=""
|
local site_delete_confirmation=""
|
||||||
|
|
||||||
while true; do
|
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_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)"
|
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
|
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
|
fi
|
||||||
if [ -n "${existing_site_apps_lines}" ]; then
|
if [ -n "${existing_site_apps_lines}" ]; then
|
||||||
existing_site_apps_csv="$(printf '%s' "${existing_site_apps_lines}" | tr '\n' ',' | sed 's/,$//')"
|
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
|
"${existing_site_last_backup_at}" || true
|
||||||
)"
|
)"
|
||||||
case "${existing_site_details_action}" in
|
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")
|
"Backup site now")
|
||||||
show_warning_message "Creating backup for site: ${existing_site_name}"
|
show_warning_message "Creating backup for site: ${existing_site_name}"
|
||||||
if backup_configured_stack_site "${stack_dir}"; then
|
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
|
render_box_message "${status_text}" "0 2" >&2
|
||||||
|
|
||||||
gum choose \
|
gum choose \
|
||||||
--height 9 \
|
--height 10 \
|
||||||
--header "Site details" \
|
--header "Site details" \
|
||||||
--cursor.foreground 63 \
|
--cursor.foreground 63 \
|
||||||
--selected.foreground 45 \
|
--selected.foreground 45 \
|
||||||
|
"Manage apps on this site" \
|
||||||
"Backup site now" \
|
"Backup site now" \
|
||||||
"Delete site" \
|
"Delete site" \
|
||||||
"Back" \
|
"Back" \
|
||||||
"Exit and close easy-docker"
|
"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() {
|
show_manage_stack_site_delete_confirmation() {
|
||||||
local stack_name="${1}"
|
local stack_name="${1}"
|
||||||
local stack_dir="${2}"
|
local stack_dir="${2}"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue