mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-01 10:22:08 +00:00
fix(oci): services show their address instead of a web link, and applications are not asked for their own
This commit is contained in:
@@ -2060,6 +2060,60 @@ CONSOLE_STATE=$(python3 "${SCRIPT_DIR}/oci_console.py" configure "$VMID") \
|
||||
|| die "$(translate "The console of the container could not be configured")"
|
||||
RUNTIME_CONSOLE_LOG=$(jq -r '.log' <<<"$CONSOLE_STATE")
|
||||
|
||||
# A variable that holds the application's own address takes the one of the
|
||||
# container: the fixed one, or the one DHCP gives it. That one is asked for
|
||||
# with the application not started yet, so that its first start already has it.
|
||||
OWN_ADDRESS_MARK='@CONTAINER_ADDRESS@'
|
||||
OWN_ADDRESS=""
|
||||
apply_own_address() {
|
||||
local names name value original inert="" candidate attempt
|
||||
names=$(jq -r --arg mark "$OWN_ADDRESS_MARK" \
|
||||
'.environment[]? | select(.value | contains($mark)) | .name' "$DEPLOYMENT_FILE")
|
||||
[[ -n $names ]] || return 0
|
||||
msg_info "$(translate "Waiting for the network address...")"
|
||||
if [[ -n ${HOST_MONITOR:-} ]]; then
|
||||
OWN_ADDRESS=$HOST_MONITOR_IP
|
||||
elif [[ $IPV4 != dhcp ]]; then
|
||||
OWN_ADDRESS=${IPV4%%/*}
|
||||
else
|
||||
mount_ct_rootfs
|
||||
for candidate in /bin/sleep /usr/bin/sleep; do
|
||||
if [[ -e /var/lib/lxc/${VMID}/rootfs${candidate} || -L /var/lib/lxc/${VMID}/rootfs${candidate} ]]; then
|
||||
inert=$candidate
|
||||
break
|
||||
fi
|
||||
done
|
||||
oci_quiet pct unmount "$VMID" || true
|
||||
if [[ -z $inert ]]; then
|
||||
oci_log "The image has no sleep command to wait for the DHCP address with"
|
||||
die "$(translate "No LAN address was obtained")"
|
||||
fi
|
||||
original=$(pct config "$VMID" | sed -n 's/^entrypoint: //p')
|
||||
oci_quiet pct set "$VMID" --entrypoint "$inert 120" \
|
||||
|| die "$(translate "Could not set the container entrypoint")"
|
||||
oci_quiet pct start "$VMID" || die "$(translate "The container could not be started:") CT $VMID"
|
||||
for attempt in $(seq 1 60); do
|
||||
OWN_ADDRESS=$(own_ipv4 2>/dev/null) \
|
||||
|| OWN_ADDRESS=$(lxc-info -n "$VMID" -iH 2>/dev/null | grep -m1 -E '^[0-9]+\.' || true)
|
||||
[[ -n $OWN_ADDRESS ]] && break
|
||||
sleep 0.5
|
||||
done
|
||||
oci_quiet pct stop "$VMID" || die "$(translate "The container could not be started:") CT $VMID"
|
||||
if [[ -n $original ]]; then
|
||||
oci_quiet pct set "$VMID" --entrypoint "$original" || die "$(translate "Could not set the container entrypoint")"
|
||||
else
|
||||
oci_quiet pct set "$VMID" --delete entrypoint || die "$(translate "Could not set the container entrypoint")"
|
||||
fi
|
||||
fi
|
||||
[[ $OWN_ADDRESS =~ ^[0-9]+(\.[0-9]+){3}$ ]] || die "$(translate "No LAN address was obtained")"
|
||||
while IFS= read -r name; do
|
||||
value=$(jq -r --arg name "$name" '[.environment[] | select(.name == $name) | .value] | last' "$DEPLOYMENT_FILE")
|
||||
set_runtime_environment "$name" "${value//$OWN_ADDRESS_MARK/$OWN_ADDRESS}"
|
||||
done <<<"$names"
|
||||
msg_ok "$(translate "IP address:") $OWN_ADDRESS"
|
||||
}
|
||||
apply_own_address
|
||||
|
||||
oci_log "Configuration created for CT $VMID"
|
||||
PASSWORD_STATE=""
|
||||
if [[ $START_AFTER == 1 ]]; then
|
||||
@@ -2279,6 +2333,13 @@ URLS=$(jq -c --arg ip "$IP" '
|
||||
}]
|
||||
else [] end
|
||||
' "$TEMPLATE_FILE")
|
||||
# An application with no web address is reached on the ports of its container.
|
||||
SERVICE_ADDRESSES=$(jq -c --arg ip "$IP" '
|
||||
if $ip == "" or ((.first_run.endpoints? // []) | length) > 0 or .catalog_ui.launch.port != null then []
|
||||
else [.container_contract.ports[]?
|
||||
| $ip + ":" + (.container_port | tostring) + (if .protocol == "udp" then "/udp" else "" end)]
|
||||
end
|
||||
' "$TEMPLATE_FILE")
|
||||
if [[ -n $HAOS_URLS ]]; then
|
||||
URLS=$HAOS_URLS
|
||||
elif [[ $HAOS_HEALTHCHECK != 0 ]]; then
|
||||
@@ -2293,7 +2354,7 @@ elif [[ $START_AFTER == 1 ]]; then
|
||||
check_native_device_permissions
|
||||
fi
|
||||
if [[ -z ${PROXMENUX_OCI_TRANSACTION:-} ]] && ! oci_quiet python3 "${SCRIPT_DIR}/oci_instances.py" complete "$VMID" \
|
||||
--archive "$ARCHIVE_PATH" --digest "$DIGEST"; then
|
||||
--archive "$ARCHIVE_PATH" --digest "$DIGEST" ${OWN_ADDRESS:+--address "$OWN_ADDRESS"}; then
|
||||
msg_warn "$(translate "Container installed, but without a verifiable record for future updates.")"
|
||||
fi
|
||||
# The template's notes, then those of this installation's choices, such as the
|
||||
@@ -2309,9 +2370,10 @@ RESULT=$(jq -cn \
|
||||
--arg image_created "$CREATED" \
|
||||
--arg ip "$IP" \
|
||||
--argjson urls "$URLS" \
|
||||
--argjson service_addresses "$SERVICE_ADDRESSES" \
|
||||
--argjson credentials "$CREDENTIALS" \
|
||||
--argjson completion_notes "$COMPLETION_NOTES" \
|
||||
--argjson vmid "$VMID" \
|
||||
--arg log "${OCI_LOG:-}" \
|
||||
'{app_id:$app_id,vmid:$vmid,image:$image,digest:$digest,architecture:$architecture,image_version:$image_version,image_created:$image_created,ip:$ip,urls:$urls,credentials:$credentials,completion_notes:$completion_notes,log:$log}')
|
||||
'{app_id:$app_id,vmid:$vmid,image:$image,digest:$digest,architecture:$architecture,image_version:$image_version,image_created:$image_created,ip:$ip,urls:$urls,service_addresses:$service_addresses,credentials:$credentials,completion_notes:$completion_notes,log:$log}')
|
||||
printf 'PROXMENUX_RESULT=%s\n' "$(printf '%s' "$RESULT" | base64 | tr -d '\n')"
|
||||
|
||||
@@ -87,6 +87,13 @@ def render(template, digest, instance_id, ip=''):
|
||||
item = f'🌐 {link(str(endpoint.get("label") or "Web UI"), url)}: {link(url, url)}'
|
||||
if item:
|
||||
access.append(item)
|
||||
if not access:
|
||||
# With no web address, the application is reached on its ports.
|
||||
for item in (template.get('container_contract') or {}).get('ports') or []:
|
||||
port = item.get('container_port')
|
||||
if isinstance(port, int) and 1 <= port <= 65535:
|
||||
protocol = '/udp' if item.get('protocol') == 'udp' else ''
|
||||
access.append(f'🔌 <code>{address}:{port}{protocol}</code>')
|
||||
badges = (
|
||||
('Docs', DOCS, 'https://img.shields.io/badge/%F0%9F%93%9A_Docs-blue'),
|
||||
('Code', CODE, 'https://img.shields.io/badge/%F0%9F%92%BB_Code-green'),
|
||||
|
||||
@@ -24,6 +24,8 @@ from oci_ui import translate, msg_error, msg_ok
|
||||
|
||||
ROOT = Path('/usr/local/share/proxmenux/oci/instances')
|
||||
MARKER = 'proxmenux-instance='
|
||||
# Stands for the address of the container until the installation knows it.
|
||||
ADDRESS_MARK = '@CONTAINER_ADDRESS@'
|
||||
ACTIVE = {'installing', 'assembling', 'updating', 'recovering'}
|
||||
|
||||
|
||||
@@ -160,8 +162,13 @@ def observe(vmid, installation_id, archive, digest, image=None):
|
||||
return observed
|
||||
|
||||
|
||||
def finish(root, vmid, archive, digest):
|
||||
def finish(root, vmid, archive, digest, address=None):
|
||||
value = read(root, vmid)
|
||||
if address:
|
||||
# The address the installation gave the application is recorded as the
|
||||
# value it is, the way one typed by the user would be.
|
||||
for item in value['deployment'].get('environment', []):
|
||||
item['value'] = item['value'].replace(ADDRESS_MARK, address)
|
||||
observed = observe(vmid, value['installation_id'], archive, digest)
|
||||
value.update(status='assembling' if value['deployment'].get('stack_managed') else 'installed',
|
||||
completed_at=now(), observed=observed)
|
||||
@@ -356,6 +363,7 @@ def main():
|
||||
if action == 'complete':
|
||||
p.add_argument('--archive', required=True)
|
||||
p.add_argument('--digest', required=True)
|
||||
p.add_argument('--address')
|
||||
sub.add_parser('reconcile')
|
||||
resume = sub.add_parser('resume-stack-recording')
|
||||
resume.add_argument('vmid', type=int)
|
||||
@@ -372,7 +380,7 @@ def main():
|
||||
json.loads(Path(args.deployment).read_text()))
|
||||
print(value['installation_id'])
|
||||
elif args.action == 'complete':
|
||||
finish(args.root, args.vmid, args.archive, args.digest)
|
||||
finish(args.root, args.vmid, args.archive, args.digest, args.address)
|
||||
elif args.action == 'failed':
|
||||
value = read(args.root, args.vmid)
|
||||
value.update(status='failed', failed_at=now())
|
||||
|
||||
Reference in New Issue
Block a user