mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-17 13:55:08 +00:00
fix(easy-docker): preserve custom apps and simplify manage flows
This commit is contained in:
parent
c754d05544
commit
6fdd9a3b84
6 changed files with 95 additions and 317 deletions
|
|
@ -253,126 +253,3 @@ persist_stack_apps_json_from_metadata_apps() {
|
|||
|
||||
return 0
|
||||
}
|
||||
|
||||
persist_stack_metadata_top_level_object() {
|
||||
local stack_dir="${1}"
|
||||
local object_key="${2}"
|
||||
local object_json="${3}"
|
||||
local insert_before_key="${4:-}"
|
||||
local metadata_path=""
|
||||
local metadata_tmp_path=""
|
||||
|
||||
metadata_path="${stack_dir}/metadata.json"
|
||||
metadata_tmp_path="${metadata_path}.tmp"
|
||||
if [ ! -f "${metadata_path}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${object_json}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! awk -v object_key="${object_key}" -v object_json="${object_json}" -v insert_before_key="${insert_before_key}" '
|
||||
BEGIN {
|
||||
target_regex = "^ \"" object_key "\"[[:space:]]*:"
|
||||
before_regex = ""
|
||||
if (insert_before_key != "") {
|
||||
before_regex = "^ \"" insert_before_key "\"[[:space:]]*:"
|
||||
}
|
||||
in_target = 0
|
||||
target_depth = 0
|
||||
inserted = 0
|
||||
prev = ""
|
||||
}
|
||||
function flush_prev() {
|
||||
if (prev != "") {
|
||||
print prev
|
||||
prev = ""
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!in_target && $0 ~ target_regex) {
|
||||
flush_prev()
|
||||
if (object_key == "wizard") {
|
||||
print " \"" object_key "\": " object_json
|
||||
} else {
|
||||
print " \"" object_key "\": " object_json ","
|
||||
}
|
||||
in_target = 1
|
||||
inserted = 1
|
||||
if ($0 ~ /{/) {
|
||||
target_depth += gsub(/{/, "{", $0)
|
||||
target_depth -= gsub(/}/, "}", $0)
|
||||
} else {
|
||||
target_depth = 0
|
||||
}
|
||||
if (target_depth <= 0) {
|
||||
in_target = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if (in_target) {
|
||||
target_depth += gsub(/{/, "{", $0)
|
||||
target_depth -= gsub(/}/, "}", $0)
|
||||
if (target_depth <= 0) {
|
||||
in_target = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if (!inserted && before_regex != "" && $0 ~ before_regex) {
|
||||
flush_prev()
|
||||
print " \"" object_key "\": " object_json ","
|
||||
inserted = 1
|
||||
}
|
||||
|
||||
if (!inserted && $0 ~ /^}/) {
|
||||
if (prev != "") {
|
||||
if (prev !~ /,[[:space:]]*$/) {
|
||||
prev = prev ","
|
||||
}
|
||||
print prev
|
||||
prev = ""
|
||||
}
|
||||
print " \"" object_key "\": " object_json
|
||||
inserted = 1
|
||||
print $0
|
||||
next
|
||||
}
|
||||
|
||||
flush_prev()
|
||||
prev = $0
|
||||
}
|
||||
END {
|
||||
flush_prev()
|
||||
if (!inserted) {
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
' "${metadata_path}" >"${metadata_tmp_path}"; then
|
||||
rm -f -- "${metadata_tmp_path}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! mv -- "${metadata_tmp_path}" "${metadata_path}"; then
|
||||
rm -f -- "${metadata_tmp_path}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
persist_stack_metadata_apps_object() {
|
||||
local stack_dir="${1}"
|
||||
local apps_json_object="${2}"
|
||||
|
||||
persist_stack_metadata_top_level_object "${stack_dir}" "apps" "${apps_json_object}" "wizard"
|
||||
}
|
||||
|
||||
persist_stack_metadata_wizard_object() {
|
||||
local stack_dir="${1}"
|
||||
local wizard_json_object="${2}"
|
||||
|
||||
persist_stack_metadata_top_level_object "${stack_dir}" "wizard" "${wizard_json_object}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
persist_stack_metadata_apps_object() {
|
||||
persist_stack_metadata_top_level_object() {
|
||||
local stack_dir="${1}"
|
||||
local apps_json_object="${2}"
|
||||
local object_key="${2}"
|
||||
local object_json="${3}"
|
||||
local insert_before_key="${4:-}"
|
||||
local metadata_path=""
|
||||
local metadata_tmp_path=""
|
||||
|
||||
|
|
@ -12,14 +14,19 @@ persist_stack_metadata_apps_object() {
|
|||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${apps_json_object}" ]; then
|
||||
if [ -z "${object_json}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! awk -v apps_object="${apps_json_object}" '
|
||||
if ! awk -v object_key="${object_key}" -v object_json="${object_json}" -v insert_before_key="${insert_before_key}" '
|
||||
BEGIN {
|
||||
in_top_level_apps = 0
|
||||
apps_depth = 0
|
||||
target_regex = "^ \"" object_key "\"[[:space:]]*:"
|
||||
before_regex = ""
|
||||
if (insert_before_key != "") {
|
||||
before_regex = "^ \"" insert_before_key "\"[[:space:]]*:"
|
||||
}
|
||||
in_target = 0
|
||||
target_depth = 0
|
||||
inserted = 0
|
||||
prev = ""
|
||||
}
|
||||
|
|
@ -30,35 +37,39 @@ persist_stack_metadata_apps_object() {
|
|||
}
|
||||
}
|
||||
{
|
||||
if (!in_top_level_apps && $0 ~ /^ "apps"[[:space:]]*:/) {
|
||||
if (!in_target && $0 ~ target_regex) {
|
||||
flush_prev()
|
||||
print " \"apps\": " apps_object ","
|
||||
in_top_level_apps = 1
|
||||
if (object_key == "wizard") {
|
||||
print " \"" object_key "\": " object_json
|
||||
} else {
|
||||
print " \"" object_key "\": " object_json ","
|
||||
}
|
||||
in_target = 1
|
||||
inserted = 1
|
||||
if ($0 ~ /{/) {
|
||||
apps_depth += gsub(/{/, "{", $0)
|
||||
apps_depth -= gsub(/}/, "}", $0)
|
||||
target_depth += gsub(/{/, "{", $0)
|
||||
target_depth -= gsub(/}/, "}", $0)
|
||||
} else {
|
||||
apps_depth = 0
|
||||
target_depth = 0
|
||||
}
|
||||
if (apps_depth <= 0) {
|
||||
in_top_level_apps = 0
|
||||
if (target_depth <= 0) {
|
||||
in_target = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if (in_top_level_apps) {
|
||||
apps_depth += gsub(/{/, "{", $0)
|
||||
apps_depth -= gsub(/}/, "}", $0)
|
||||
if (apps_depth <= 0) {
|
||||
in_top_level_apps = 0
|
||||
if (in_target) {
|
||||
target_depth += gsub(/{/, "{", $0)
|
||||
target_depth -= gsub(/}/, "}", $0)
|
||||
if (target_depth <= 0) {
|
||||
in_target = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if (!inserted && $0 ~ /^ "wizard"[[:space:]]*:/) {
|
||||
if (!inserted && before_regex != "" && $0 ~ before_regex) {
|
||||
flush_prev()
|
||||
print " \"apps\": " apps_object ","
|
||||
print " \"" object_key "\": " object_json ","
|
||||
inserted = 1
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +81,7 @@ persist_stack_metadata_apps_object() {
|
|||
print prev
|
||||
prev = ""
|
||||
}
|
||||
print " \"apps\": " apps_object
|
||||
print " \"" object_key "\": " object_json
|
||||
inserted = 1
|
||||
print $0
|
||||
next
|
||||
|
|
@ -98,94 +109,16 @@ persist_stack_metadata_apps_object() {
|
|||
return 0
|
||||
}
|
||||
|
||||
persist_stack_metadata_apps_object() {
|
||||
local stack_dir="${1}"
|
||||
local apps_json_object="${2}"
|
||||
|
||||
persist_stack_metadata_top_level_object "${stack_dir}" "apps" "${apps_json_object}" "wizard"
|
||||
}
|
||||
|
||||
persist_stack_metadata_wizard_object() {
|
||||
local stack_dir="${1}"
|
||||
local wizard_json_object="${2}"
|
||||
local metadata_path=""
|
||||
local metadata_tmp_path=""
|
||||
|
||||
metadata_path="${stack_dir}/metadata.json"
|
||||
metadata_tmp_path="${metadata_path}.tmp"
|
||||
if [ ! -f "${metadata_path}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${wizard_json_object}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! awk -v wizard_object="${wizard_json_object}" '
|
||||
BEGIN {
|
||||
in_top_level_wizard = 0
|
||||
wizard_depth = 0
|
||||
inserted = 0
|
||||
prev = ""
|
||||
}
|
||||
function flush_prev() {
|
||||
if (prev != "") {
|
||||
print prev
|
||||
prev = ""
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!in_top_level_wizard && $0 ~ /^ "wizard"[[:space:]]*:/) {
|
||||
flush_prev()
|
||||
print " \"wizard\": " wizard_object
|
||||
in_top_level_wizard = 1
|
||||
inserted = 1
|
||||
if ($0 ~ /{/) {
|
||||
wizard_depth += gsub(/{/, "{", $0)
|
||||
wizard_depth -= gsub(/}/, "}", $0)
|
||||
} else {
|
||||
wizard_depth = 0
|
||||
}
|
||||
if (wizard_depth <= 0) {
|
||||
in_top_level_wizard = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if (in_top_level_wizard) {
|
||||
wizard_depth += gsub(/{/, "{", $0)
|
||||
wizard_depth -= gsub(/}/, "}", $0)
|
||||
if (wizard_depth <= 0) {
|
||||
in_top_level_wizard = 0
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
if (!inserted && $0 ~ /^}/) {
|
||||
if (prev != "") {
|
||||
if (prev !~ /,[[:space:]]*$/) {
|
||||
prev = prev ","
|
||||
}
|
||||
print prev
|
||||
prev = ""
|
||||
}
|
||||
print " \"wizard\": " wizard_object
|
||||
inserted = 1
|
||||
print $0
|
||||
next
|
||||
}
|
||||
|
||||
flush_prev()
|
||||
prev = $0
|
||||
}
|
||||
END {
|
||||
flush_prev()
|
||||
if (!inserted) {
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
' "${metadata_path}" >"${metadata_tmp_path}"; then
|
||||
rm -f -- "${metadata_tmp_path}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! mv -- "${metadata_tmp_path}" "${metadata_path}"; then
|
||||
rm -f -- "${metadata_tmp_path}" >/dev/null 2>&1 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
persist_stack_metadata_top_level_object "${stack_dir}" "wizard" "${wizard_json_object}"
|
||||
}
|
||||
|
|
|
|||
38
scripts/easy-docker/lib/app/wizard/env/apps.sh
vendored
38
scripts/easy-docker/lib/app/wizard/env/apps.sh
vendored
|
|
@ -84,12 +84,17 @@ build_predefined_apps_metadata_json_object() {
|
|||
local result_var="${1}"
|
||||
local predefined_csv="${2}"
|
||||
local branch_lines="${3}"
|
||||
local custom_apps_lines="${4:-}"
|
||||
local app_id=""
|
||||
local app_branch=""
|
||||
local custom_repo=""
|
||||
local custom_branch=""
|
||||
local predefined_json_entries=""
|
||||
local branch_json_entries=""
|
||||
local custom_json_entries=""
|
||||
local escaped_app_id=""
|
||||
local escaped_branch=""
|
||||
local escaped_repo=""
|
||||
local entry_json=""
|
||||
local line=""
|
||||
local -a predefined_ids=()
|
||||
|
|
@ -134,7 +139,30 @@ build_predefined_apps_metadata_json_object() {
|
|||
${branch_lines}
|
||||
EOF
|
||||
|
||||
printf -v "${result_var}" '{\n "predefined": [\n%s\n ],\n "predefined_branches": {\n%s\n },\n "custom": [\n ]\n }' "${predefined_json_entries}" "${branch_json_entries}"
|
||||
while IFS= read -r line; do
|
||||
if [ -z "${line}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
custom_repo="${line%%|*}"
|
||||
custom_branch="${line#*|}"
|
||||
if [ -z "${custom_repo}" ] || [ -z "${custom_branch}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
escaped_repo="$(json_escape_string "${custom_repo}")"
|
||||
escaped_branch="$(json_escape_string "${custom_branch}")"
|
||||
entry_json="$(printf ' {\n "repo": "%s",\n "branch": "%s"\n }' "${escaped_repo}" "${escaped_branch}")"
|
||||
if [ -z "${custom_json_entries}" ]; then
|
||||
custom_json_entries="${entry_json}"
|
||||
else
|
||||
custom_json_entries="${custom_json_entries}"$',\n'"${entry_json}"
|
||||
fi
|
||||
done <<EOF
|
||||
${custom_apps_lines}
|
||||
EOF
|
||||
|
||||
printf -v "${result_var}" '{\n "predefined": [\n%s\n ],\n "predefined_branches": {\n%s\n },\n "custom": [\n%s\n ]\n }' "${predefined_json_entries}" "${branch_json_entries}" "${custom_json_entries}"
|
||||
}
|
||||
|
||||
get_predefined_branch_from_lines() {
|
||||
|
|
@ -247,6 +275,7 @@ prompt_custom_modular_apps_data() {
|
|||
local preferred_branch=""
|
||||
local available_branch_lines=""
|
||||
local existing_branch_lines=""
|
||||
local existing_custom_lines=""
|
||||
local selected_branch_lines=""
|
||||
local selected_app_count=0
|
||||
local assembled_apps_metadata_json_object=""
|
||||
|
|
@ -257,6 +286,7 @@ prompt_custom_modular_apps_data() {
|
|||
if [ -f "${metadata_path}" ]; then
|
||||
selected_predefined_csv="$(get_metadata_apps_predefined_csv "${metadata_path}" || true)"
|
||||
existing_branch_lines="$(get_metadata_apps_predefined_branch_lines "${metadata_path}" || true)"
|
||||
existing_custom_lines="$(get_metadata_apps_custom_lines "${metadata_path}" || true)"
|
||||
fi
|
||||
|
||||
while true; do
|
||||
|
|
@ -393,7 +423,7 @@ EOF
|
|||
continue
|
||||
fi
|
||||
|
||||
build_predefined_apps_metadata_json_object assembled_apps_metadata_json_object "${selected_predefined_csv}" "${selected_branch_lines}"
|
||||
build_predefined_apps_metadata_json_object assembled_apps_metadata_json_object "${selected_predefined_csv}" "${selected_branch_lines}" "${existing_custom_lines}"
|
||||
printf -v "${result_apps_metadata_var}" "%s" "${assembled_apps_metadata_json_object}"
|
||||
return 0
|
||||
done
|
||||
|
|
@ -444,6 +474,7 @@ prompt_selected_stack_app_branches_data() {
|
|||
local preferred_branch=""
|
||||
local available_branch_lines=""
|
||||
local existing_branch_lines=""
|
||||
local existing_custom_lines=""
|
||||
local selected_branch_lines=""
|
||||
local selected_app_count=0
|
||||
local assembled_apps_metadata_json_object=""
|
||||
|
|
@ -457,6 +488,7 @@ prompt_selected_stack_app_branches_data() {
|
|||
|
||||
selected_predefined_csv="$(get_metadata_apps_predefined_csv "${metadata_path}" || true)"
|
||||
existing_branch_lines="$(get_metadata_apps_predefined_branch_lines "${metadata_path}" || true)"
|
||||
existing_custom_lines="$(get_metadata_apps_custom_lines "${metadata_path}" || true)"
|
||||
if [ -z "${selected_predefined_csv}" ]; then
|
||||
return 4
|
||||
fi
|
||||
|
|
@ -515,7 +547,7 @@ prompt_selected_stack_app_branches_data() {
|
|||
return 4
|
||||
fi
|
||||
|
||||
build_predefined_apps_metadata_json_object assembled_apps_metadata_json_object "${selected_predefined_csv}" "${selected_branch_lines}"
|
||||
build_predefined_apps_metadata_json_object assembled_apps_metadata_json_object "${selected_predefined_csv}" "${selected_branch_lines}" "${existing_custom_lines}"
|
||||
printf -v "${result_apps_metadata_var}" "%s" "${assembled_apps_metadata_json_object}"
|
||||
return 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ load_easy_docker_manage_flow_modules() {
|
|||
local manage_dir=""
|
||||
manage_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/manage"
|
||||
|
||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/flows/manage/docker.sh
|
||||
source "${manage_dir}/docker.sh"
|
||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/flows/manage/build.sh
|
||||
source "${manage_dir}/build.sh"
|
||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/flows/manage/prompts.sh
|
||||
source "${manage_dir}/prompts.sh"
|
||||
# shellcheck source=scripts/easy-docker/lib/app/wizard/flows/manage/site.sh
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
#!/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() {
|
||||
local stack_name="${1}"
|
||||
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}"
|
||||
if build_stack_custom_image "${stack_dir}"; then
|
||||
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
|
||||
else
|
||||
build_image_status=$?
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
#!/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() {
|
||||
local stack_name="${1}"
|
||||
local stack_dir="${2}"
|
||||
local build_image_status=0
|
||||
|
||||
show_warning_message "Starting docker build for stack: ${stack_name}"
|
||||
if build_stack_custom_image "${stack_dir}"; then
|
||||
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
|
||||
else
|
||||
build_image_status=$?
|
||||
fi
|
||||
case "${build_image_status}" in
|
||||
11)
|
||||
show_warning_and_wait "Custom image build failed: missing metadata.json in ${stack_dir}." 4
|
||||
;;
|
||||
12)
|
||||
show_warning_and_wait "Custom image build failed: stack env file not found in ${stack_dir}." 4
|
||||
;;
|
||||
13)
|
||||
show_warning_and_wait "Custom image build failed: CUSTOM_IMAGE is missing in stack env file." 4
|
||||
;;
|
||||
14)
|
||||
show_warning_and_wait "Custom image build failed: CUSTOM_TAG is missing in stack env file." 4
|
||||
;;
|
||||
15)
|
||||
show_warning_and_wait "Custom image build failed: frappe_branch missing in metadata.json." 4
|
||||
;;
|
||||
16)
|
||||
show_warning_and_wait "Custom image build failed: could not generate apps.json from metadata app selection." 4
|
||||
;;
|
||||
17)
|
||||
show_warning_and_wait "Custom image build failed: apps.json not found after generation." 4
|
||||
;;
|
||||
18)
|
||||
show_warning_and_wait "Custom image build failed: base64 command is not available in this environment." 4
|
||||
;;
|
||||
19)
|
||||
show_warning_and_wait "Custom image build failed: apps.json could not be base64-encoded." 4
|
||||
;;
|
||||
20)
|
||||
show_warning_and_wait "Custom image build failed: images/layered/Containerfile not found." 4
|
||||
;;
|
||||
21)
|
||||
show_warning_and_wait "Custom image build failed: docker build returned an error. Check the output above." 4
|
||||
;;
|
||||
22)
|
||||
show_warning_and_wait "Custom image build failed: git is required for app branch precheck (git ls-remote)." 4
|
||||
;;
|
||||
23)
|
||||
show_warning_and_wait "Custom image build failed: could not parse app entries from apps.json." 4
|
||||
;;
|
||||
24)
|
||||
show_warning_and_wait "Custom image build failed: app branch precheck failed -> ${EASY_DOCKER_BUILD_ERROR_DETAIL}" 6
|
||||
;;
|
||||
*)
|
||||
show_warning_and_wait "Custom image build failed (${build_image_status})." 4
|
||||
;;
|
||||
esac
|
||||
|
||||
return "${build_image_status}"
|
||||
}
|
||||
Loading…
Reference in a new issue