-
Notifications
You must be signed in to change notification settings - Fork 10
feat: migrate AKernel deployment to Python YuanRong CLI #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9b0743c
f273aa8
1505593
f59a387
000340d
a070aea
d77fdf3
7130e71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Runtime dependency lock for openyuanrong-core 0.10.1rc4 on Python 3.12. | ||
| # Regenerate and validate this file for both linux/amd64 and linux/arm64 when | ||
| # OPEN_YR_VERSION changes. | ||
| aiohappyeyeballs==2.7.1 | ||
| aiohttp==3.14.3 | ||
| aiosignal==1.4.0 | ||
| anyio==4.14.2 | ||
| attrs==26.1.0 | ||
| certifi==2026.7.22 | ||
| charset-normalizer==3.5.1 | ||
| click==8.4.2 | ||
| cloudpickle==3.1.2 | ||
| frozenlist==1.8.0 | ||
| h11==0.16.0 | ||
| httpcore==1.0.9 | ||
| httpx==0.28.1 | ||
| idna==3.19 | ||
| jinja2==3.1.6 | ||
| markupsafe==3.0.3 | ||
| msgpack==1.2.1 | ||
| multidict==6.7.1 | ||
| propcache==0.5.2 | ||
| protobuf==7.36.0 | ||
| pyyaml==6.0.3 | ||
| requests==2.34.2 | ||
| tomli-w==1.2.0 | ||
| typing-extensions==4.16.0 | ||
| urllib3==2.7.0 | ||
| websockets==17.0.1 | ||
| yarl==1.24.5 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| {# | ||
| AKernel runtime profile template. | ||
|
|
||
| Deployment values are resolved from the CLI-provided env mapping. Strings | ||
| containing Python CLI runtime expressions remain escaped for its second | ||
| rendering pass. | ||
| #} | ||
| {% macro toml_string(value) -%} | ||
| "{%- for char in value -%} | ||
| {%- set encoded = char | tojson -%} | ||
| {{- char if encoded | length == 14 else encoded[1:-1] -}} | ||
| {%- endfor -%}" | ||
| {%- endmacro %} | ||
| {% set role = env["AKERNEL_ROLE"] %} | ||
| {% set cluster_roles = ["master", "frontend"] %} | ||
| {% set node_roles = ["node", "standalone"] %} | ||
| {% if role not in cluster_roles + node_roles %} | ||
| {{ unsupported_akernel_role }} | ||
| {% endif %} | ||
| {% set is_cluster = role in cluster_roles %} | ||
| {% set is_node = role in node_roles %} | ||
| {% set is_agent = role == "node" %} | ||
| {% set is_standalone = role == "standalone" %} | ||
| {% set has_master_mode = not is_agent %} | ||
| {% set enable_metrics = env.get("ENABLE_METRICS", "false") | lower %} | ||
| {% set enable_trace = env.get("ENABLE_TRACE", "false") | lower %} | ||
| {% set traefik_enable_tls = "true" if env.get("TRAEFIK_ENABLE_TLS", "false") | lower == "true" else "false" %} | ||
| {% set configured_host_ip = env.get("YR_NODE_IP", "") | trim %} | ||
| {% set configured_local_ip = env.get("YR_LOCAL_IP", "") | trim %} | ||
| {% set enable_faas_frontend = env.get("ENABLE_FAAS_FRONTEND", "true") | lower %} | ||
| {% set enable_iam_server = env.get("ENABLE_IAM_SERVER", "true") | lower %} | ||
| {% set runtime_hostname = "{{ hostname }}" %} | ||
| {% set deploy_path_value = env["DEPLOY_PATH"] | trim %} | ||
| {% set component_log_path = env["YR_LOG_PATH"] | trim %} | ||
|
|
||
| # Generated at startup from builder/config/yr/config.toml.jinja. | ||
|
|
||
| [values] | ||
| node_id = "{{ runtime_hostname }}" | ||
| deploy_path = {{ toml_string(deploy_path_value) }} | ||
| {% if configured_host_ip %} | ||
| host_ip = {{ toml_string(configured_host_ip) }} | ||
| {% endif %} | ||
| {% if configured_local_ip %} | ||
| local_ip = {{ toml_string(configured_local_ip) }} | ||
| {% endif %} | ||
| {% if is_cluster %} | ||
| cpu_num = 1 | ||
| memory_num = 3904 | ||
| shared_memory_num = 4096 | ||
| {% endif %} | ||
|
|
||
| [values.fs.log] | ||
| path = {{ toml_string(component_log_path) }} | ||
|
|
||
| [values.fs.tls] | ||
| base_path = "/home/yuanrong/.cert" | ||
|
|
||
| {% if not is_standalone %} | ||
| [values.etcd] | ||
| enable_multi_master = true | ||
| {% endif %} | ||
|
|
||
| {% if is_cluster or is_node %} | ||
| [[values.etcd.address]] | ||
| ip = {{ toml_string(configured_host_ip if is_standalone else env["ETCD_ADDRESS"]) }} | ||
| port = {{ env.get("ETCD_PORT", "2379") }} | ||
| peer_port = {{ env.get("ETCD_PEER_PORT", "2378") }} | ||
| {% endif %} | ||
|
|
||
| [values.frontend] | ||
| ssl_enable = true | ||
| client_auth_type = "NoClientCert" | ||
| frontend_lease_bypass = true | ||
| enable_function_token_auth = true | ||
| enable_func_token_auth = true | ||
| {% if role == "frontend" %} | ||
| meta_service_address = {{ toml_string(env["META_SERVICE_ADDRESS"]) }} | ||
| {% endif %} | ||
| iam_server_address = "127.0.0.1:31113" | ||
|
|
||
| [values.meta_service] | ||
| port = 31111 | ||
|
|
||
| {% if has_master_mode %} | ||
| [mode.master] | ||
| etcd = {{ "true" if is_standalone else "false" }} | ||
| ds_master = {{ "true" if is_standalone else "false" }} | ||
| frontend = {{ enable_faas_frontend if role == "master" else "true" if role in ["frontend", "standalone"] else "false" }} | ||
| function_master = {{ "true" if role in ["master", "standalone"] else "false" }} | ||
| function_scheduler = false | ||
| meta_service = {{ "true" if role in ["master", "standalone"] else "false" }} | ||
| iam_server = {{ enable_iam_server if role == "master" else "true" if role in ["frontend", "standalone"] else "false" }} | ||
| {% endif %} | ||
|
|
||
| [ds_worker.args] | ||
| {% if is_cluster %} | ||
| rpc_thread_num = 128 | ||
| node_timeout_s = 10 | ||
| node_dead_timeout_s = 30 | ||
| heartbeat_interval_ms = 3000 | ||
| {% endif %} | ||
| {% if is_node %} | ||
| node_timeout_s = 30 | ||
| client_dead_timeout_s = 60 | ||
| heartbeat_interval_ms = 1000 | ||
| node_dead_timeout_s = 120 | ||
| log_dir = {{ toml_string(component_log_path ~ "/data_system/worker") }} | ||
| {% endif %} | ||
|
|
||
| [ds_master.args] | ||
| log_dir = {{ toml_string(component_log_path ~ "/data_system/master") }} | ||
|
|
||
| [function_master.args] | ||
| services_path = "/home/yuanrong/deploy/process/services.yaml" | ||
| metrics_config_file = "/home/yuanrong/metrics/metrics_config.json" | ||
| traefik_enable_tls = {{ traefik_enable_tls }} | ||
| traefik_http_entry_point = {{ toml_string(env.get("TRAEFIK_HTTP_ENTRYPOINT", "websecure")) }} | ||
| traefik_forward_timeout_ms = 3000 | ||
| {% if enable_metrics == "true" and (is_cluster or is_standalone) %} | ||
| enable_metrics = true | ||
| {% endif %} | ||
| {% if enable_trace == "true" and (is_cluster or is_standalone) %} | ||
| enable_trace = true | ||
| trace_config = {{ toml_string(env["YR_TRACE_CONFIG_CONTENT"]) }} | ||
| {% endif %} | ||
| {% if is_cluster or is_standalone %} | ||
| enable_traefik_provider = {{ "true" if env.get("TRAEFIK_MODE", "etcd") == "http" else "false" }} | ||
| {% endif %} | ||
| {% if is_cluster %} | ||
| system_timeout = 300000 | ||
| schedule_relaxed = 20 | ||
| {% elif is_standalone %} | ||
| system_timeout = 60000 | ||
| {% endif %} | ||
|
|
||
| [function_proxy.args] | ||
| services_path = "/home/yuanrong/deploy/process/services.yaml" | ||
| enable_inherit_env = false | ||
| npu_collection_mode = "off" | ||
| metrics_config_file = "/home/yuanrong/metrics/metrics_config.json" | ||
| enable_direct_routing = false | ||
| force_low_reliability_instance = true | ||
| traefik_enable_tls = {{ traefik_enable_tls }} | ||
| {% if enable_metrics == "true" %} | ||
| enable_metrics = true | ||
| {% endif %} | ||
| {% if enable_trace == "true" %} | ||
| enable_trace = true | ||
| trace_config = {{ toml_string(env["YR_TRACE_CONFIG_CONTENT"]) }} | ||
| {% endif %} | ||
| {% if is_node %} | ||
| enable_traefik_registry = {{ "true" if env.get("TRAEFIK_MODE", "etcd") == "etcd" else "false" }} | ||
| traefik_http_entrypoint = {{ toml_string(env.get("TRAEFIK_HTTP_ENTRYPOINT", "websecure")) }} | ||
| {% endif %} | ||
| log_expiration_enable = true | ||
| log_expiration_time_threshold = {{ 10 if is_agent else 7200 }} | ||
| log_expiration_cleanup_interval = {{ 10 if is_agent else 600 }} | ||
| log_expiration_max_file_count = {{ 50 if is_agent else 256 }} | ||
| {% if is_cluster %} | ||
| system_timeout = 300000 | ||
| pseudo_data_plane = true | ||
| {% elif is_node %} | ||
| system_timeout = 60000 | ||
| fc_agent_mgr_retry_times = 30 | ||
| fc_agent_mgr_retry_cycle = 60000 | ||
| {% endif %} | ||
| runtime_logs_dir = {{ toml_string(component_log_path) }} | ||
| {% if is_node %} | ||
| metrics_collector_type = "external" | ||
| snapshot_storage_mode = "local_only" | ||
| checkpoint_dir = "/home/akernel/checkpoints" | ||
| {% endif %} | ||
|
|
||
| # The CLI exposes the meta-service component port separately from values.meta_service. | ||
| [meta_service] | ||
| port = 31111 | ||
|
|
||
| [iam_server.args] | ||
| token_expired_time_span = 604800 | ||
| ssl_enable = true | ||
| iam_ssl_enable = true | ||
| local_listen_port = 31113 | ||
| local_ip = "127.0.0.1" | ||
| {% if enable_trace == "true" and (is_cluster or is_standalone) %} | ||
| enable_trace = true | ||
| {% endif %} | ||
|
|
||
| {% if enable_trace == "true" and (is_cluster or is_standalone) %} | ||
| [frontend.env] | ||
| ENABLE_TRACE = "true" | ||
| TRACE_CONFIG = {{ toml_string(env["YR_TRACE_CONFIG_CONTENT"]) }} | ||
| {% endif %} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -254,6 +254,7 @@ RUN apt-get update && \ | |
| procps \ | ||
| python3 \ | ||
| python3-pip \ | ||
| python3-venv \ | ||
| systemd \ | ||
| systemd-sysv \ | ||
| tzdata \ | ||
|
|
@@ -296,6 +297,11 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ | |
|
|
||
|
|
||
| ENV YR_INSTALLATION_DIR=/home/yuanrong | ||
| ENV PATH=/opt/openyuanrong/bin:${PATH} | ||
|
|
||
| COPY ./builder/config/yr/config.toml.jinja /etc/yuanrong/config.toml.jinja | ||
| COPY ./builder/config/openyuanrong-core-0.10.1rc4.constraints.txt /tmp/openyuanrong-core.constraints.txt | ||
| COPY ./builder/scripts/patch_openyuanrong_core.py /tmp/patch_openyuanrong_core.py | ||
|
|
||
| # Install the complete, language-runtime-free openYuanRong control plane from | ||
| # its checksum-pinned core wheel. A URL and checksum pair may override the | ||
|
|
@@ -325,21 +331,36 @@ RUN set -eux; \ | |
| test -z "${OPEN_YR_CORE_WHEEL_SHA256}"; \ | ||
| fi; \ | ||
| wheel="/tmp/${wheel_name}"; \ | ||
| target=/tmp/openyuanrong-core; \ | ||
| curl -fSL --retry 10 --retry-delay 2 --retry-all-errors \ | ||
| "${wheel_url}" -o "${wheel}"; \ | ||
| echo "${wheel_sha} ${wheel}" | sha256sum -c -; \ | ||
| python3 -m pip install \ | ||
| --break-system-packages \ | ||
| python3 -m venv /opt/openyuanrong; \ | ||
| /opt/openyuanrong/bin/python -m pip install \ | ||
| --no-cache-dir \ | ||
| --no-deps \ | ||
| --target "${target}" \ | ||
| --index-url "${PIP_INDEX_URL}" \ | ||
| --constraint /tmp/openyuanrong-core.constraints.txt \ | ||
| "${wheel}"; \ | ||
| test -x "${target}/yr/functionsystem/bin/yr"; \ | ||
| mkdir -p "${YR_INSTALLATION_DIR}"; \ | ||
| cp -a "${target}/yr/." "${YR_INSTALLATION_DIR}/"; \ | ||
| rm -rf "${target}" "${wheel}"; \ | ||
| ln -sfn "${YR_INSTALLATION_DIR}/functionsystem/bin/yr" /usr/bin/yr | ||
| site_packages="$(/opt/openyuanrong/bin/python -c 'import site; print(site.getsitepackages()[0])')"; \ | ||
| /opt/openyuanrong/bin/python /tmp/patch_openyuanrong_core.py "${site_packages}"; \ | ||
| base_py="${site_packages}/yr/cli/component/base.py"; \ | ||
| launcher_py="${site_packages}/yr/cli/system_launcher.py"; \ | ||
| grep -Fq 'logger.info(f"Environment: {full_env}")' "${base_py}"; \ | ||
| sed -i \ | ||
| 's/logger.info(f"Environment: {full_env}")/logger.info(f"Environment keys: {sorted(full_env)}")/' \ | ||
| "${base_py}"; \ | ||
| grep -Fq 'logger.info(f"Environment keys: {sorted(full_env)}")' "${base_py}"; \ | ||
| ! grep -Fq 'logger.info(f"Environment: {full_env}")' "${base_py}"; \ | ||
| grep -Fq '"env_vars": comp.env_vars,' "${launcher_py}"; \ | ||
| sed -i 's/"env_vars": comp.env_vars,/"env_vars": {},/' "${launcher_py}"; \ | ||
| grep -Fq '"env_vars": {},' "${launcher_py}"; \ | ||
| ! grep -Fq '"env_vars": comp.env_vars,' "${launcher_py}"; \ | ||
| test -x /opt/openyuanrong/bin/yr; \ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those changes for what needs?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Retained as a security hardening required by the earlier review in discussion_r3756876315. The 0.10.1 wheel still logs the full component environment and persists component env_vars in session JSON. The exact grep checks make the build fail if an upstream source change causes either redaction patch to stop applying, rather than silently exposing values such as LITEBUS_DATA_KEY. |
||
| /opt/openyuanrong/bin/python -m py_compile \ | ||
| "${site_packages}/yr/cli/component/ds_worker.py"; \ | ||
| rm -f \ | ||
| "${wheel}" \ | ||
| /tmp/openyuanrong-core.constraints.txt \ | ||
| /tmp/patch_openyuanrong_core.py | ||
|
|
||
| COPY --from=runtime-image /yr-runtime-rootfs.img ${YR_INSTALLATION_DIR}/yr-runtime-rootfs.img | ||
|
|
||
|
|
@@ -358,6 +379,7 @@ RUN if [ "${AKERNEL_ENABLE_KATA}" = "true" ]; then \ | |
| COPY ./builder/scripts/akernel-entrypoint.sh /usr/local/bin/akernel-entrypoint | ||
| COPY ./builder/scripts/ensure-component-cert.sh /usr/local/bin/ensure-component-cert | ||
| COPY ./builder/scripts/sandboxd_network_prepare.sh /usr/local/bin/sandboxd-network-prepare | ||
| COPY ./builder/scripts/sandboxd_network_ready.sh /usr/local/bin/sandboxd-network-ready | ||
| RUN chmod 0755 \ | ||
| /usr/local/bin/runsc \ | ||
| /usr/local/bin/sandboxd \ | ||
|
|
@@ -366,7 +388,8 @@ RUN chmod 0755 \ | |
| /usr/local/bin/distill_fs \ | ||
| /usr/local/bin/akernel-entrypoint \ | ||
| /usr/local/bin/ensure-component-cert \ | ||
| /usr/local/bin/sandboxd-network-prepare | ||
| /usr/local/bin/sandboxd-network-prepare \ | ||
| /usr/local/bin/sandboxd-network-ready | ||
| RUN if [ "${AKERNEL_ENABLE_KATA}" = "true" ]; then chmod 0755 /usr/local/bin/containerd-shim-kata-v2; fi | ||
| RUN if [ "${AKERNEL_ENABLE_RUNC}" = "true" ]; then \ | ||
| chmod 0755 /usr/local/bin/runc /usr/local/bin/runc-shim; \ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,12 +8,8 @@ set -euo pipefail | |
| role="${AKERNEL_ROLE:-}" | ||
|
|
||
| if [ -z "${role}" ] && [ "$#" -gt 0 ]; then | ||
| case "$1" in | ||
| master|frontend|node|standalone) | ||
| role="$1" | ||
| shift | ||
| ;; | ||
| esac | ||
| role="$1" | ||
| shift | ||
| fi | ||
|
|
||
| if [ -z "${role}" ]; then | ||
|
|
@@ -25,6 +21,16 @@ if [ -z "${role}" ]; then | |
| fi | ||
| fi | ||
|
|
||
| case "${role}" in | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems to be a duplicate of line 10.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated in 7485d18. The entrypoint now consumes the role argument once, validates the resulting role once, and then exports AKERNEL_ROLE; the duplicate role-selection case is gone. |
||
| master|frontend|node|standalone) | ||
| ;; | ||
| *) | ||
| echo "unsupported AKERNEL_ROLE: ${role}; expected master, frontend, node, or standalone" >&2 | ||
| exit 1 | ||
| ;; | ||
| esac | ||
| export AKERNEL_ROLE="${role}" | ||
|
|
||
| case "${role}" in | ||
| master|frontend) | ||
| /usr/local/bin/ensure-component-cert | ||
|
|
@@ -38,8 +44,4 @@ case "${role}" in | |
| /usr/local/bin/ensure-component-cert | ||
| exec /usr/sbin/init "$@" | ||
| ;; | ||
| *) | ||
| echo "unsupported AKERNEL_ROLE: ${role}" >&2 | ||
| exit 1 | ||
| ;; | ||
| esac | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we need to use venv?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The venv is retained because the Python CLI wheel now installs its complete runtime dependency set. It keeps those dependencies isolated from Ubuntu system Python and avoids mutating the externally managed system environment with --break-system-packages.