forked from retoor/devplacepy
feat: add TTLCache for get_cache_version and TEMPLATE_AUTO_RELOAD config with Makefile worker count variables
This commit is contained in:
@@ -1160,6 +1160,19 @@ ACTIONS: tuple[Action, ...] = (
|
||||
params=(path("uid", "Audit event uid."),),
|
||||
requires_admin=True,
|
||||
),
|
||||
Action(
|
||||
name="bot_monitor",
|
||||
method="GET",
|
||||
path="/admin/bots/data",
|
||||
summary="Live screenshot monitor of every running bot persona (admin only)",
|
||||
description=(
|
||||
"Returns JSON: one entry per running bot slot with its username, persona, current "
|
||||
"action and status text, last page url, frame age in seconds, whether it is active, "
|
||||
"and a frame_url to the latest low-quality screenshot. Use this to see what the bot "
|
||||
"fleet is doing right now. Frames live only in the worker running the Bots service."
|
||||
),
|
||||
requires_admin=True,
|
||||
),
|
||||
Action(
|
||||
name="admin_list_users",
|
||||
method="GET",
|
||||
|
||||
@@ -45,6 +45,22 @@ CONTAINER_ACTIONS: tuple[Action, ...] = (
|
||||
arg(
|
||||
"boot_command", "Optional command to run on boot, e.g. 'python app.py'."
|
||||
),
|
||||
arg(
|
||||
"boot_language",
|
||||
"Optional boot source language: 'none', 'python', or 'bash'. When set with boot_script, the script is materialized into /app and run on launch (takes precedence over boot_command).",
|
||||
),
|
||||
arg(
|
||||
"boot_script",
|
||||
"Optional boot source code (the body of the python or bash script) run on launch when boot_language is python or bash.",
|
||||
),
|
||||
arg(
|
||||
"run_as_uid",
|
||||
"Optional DevPlace user uid whose identity and API key are injected (PRAVDA_API_KEY, PRAVDA_USER_UID). Does NOT change the container OS user, which is always pravda (uid 1000).",
|
||||
),
|
||||
arg(
|
||||
"start_on_boot",
|
||||
"Force this instance to running whenever the container service starts ('true' or 'false', default false).",
|
||||
),
|
||||
arg("restart_policy", "never, always, on-failure, or unless-stopped."),
|
||||
arg("env", "Optional env vars as KEY=VALUE lines."),
|
||||
arg(
|
||||
@@ -90,6 +106,32 @@ CONTAINER_ACTIONS: tuple[Action, ...] = (
|
||||
),
|
||||
),
|
||||
),
|
||||
Action(
|
||||
name="container_configure_instance",
|
||||
method="LOCAL",
|
||||
path="",
|
||||
handler="container",
|
||||
requires_admin=True,
|
||||
summary="Update an instance's run-as user, boot language/script/command, restart policy, start-on-boot flag, and resource limits",
|
||||
params=(
|
||||
SLUG,
|
||||
arg("instance", "Instance name, slug, or uid.", required=True),
|
||||
arg(
|
||||
"run_as_uid",
|
||||
"DevPlace user uid whose identity and API key are injected (PRAVDA_API_KEY, PRAVDA_USER_UID); pass empty to clear. Does NOT change the container OS user (always pravda, uid 1000).",
|
||||
),
|
||||
arg("boot_language", "Boot source language: 'none', 'python', or 'bash'."),
|
||||
arg("boot_script", "Boot source code body run on launch."),
|
||||
arg("boot_command", "Fallback boot command used when no boot_script is set."),
|
||||
arg("restart_policy", "never, always, on-failure, or unless-stopped."),
|
||||
arg(
|
||||
"start_on_boot",
|
||||
"Force running on container-service start ('true' or 'false').",
|
||||
),
|
||||
arg("cpu_limit", "CPU limit, e.g. 1 or 1.5."),
|
||||
arg("mem_limit", "Memory limit, e.g. 512m or 1g."),
|
||||
),
|
||||
),
|
||||
Action(
|
||||
name="container_logs",
|
||||
method="LOCAL",
|
||||
|
||||
@@ -103,6 +103,7 @@ _DEVII_MECHANIC_EVENTS = {
|
||||
|
||||
_DEVII_CONTAINER_EVENTS = {
|
||||
"container_create_instance": "container.instance.create",
|
||||
"container_configure_instance": "container.instance.configure",
|
||||
"container_exec": "container.instance.exec",
|
||||
"container_schedule": "container.schedule.create",
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ class Action:
|
||||
"chunks",
|
||||
"rsearch",
|
||||
"container",
|
||||
"customization",
|
||||
"notification",
|
||||
"behavior",
|
||||
"virtual_tool",
|
||||
] = "http"
|
||||
freeform_body: bool = False
|
||||
ajax: bool = False
|
||||
|
||||
@@ -79,10 +79,20 @@ class ContainerController:
|
||||
"no",
|
||||
"off",
|
||||
)
|
||||
start_on_boot = str(arguments.get("start_on_boot", "false")).lower() in (
|
||||
"true",
|
||||
"1",
|
||||
"yes",
|
||||
"on",
|
||||
)
|
||||
inst = await api.create_instance(
|
||||
project,
|
||||
name=str(arguments.get("name", "")),
|
||||
boot_command=str(arguments.get("boot_command", "")),
|
||||
boot_language=str(arguments.get("boot_language", "none")),
|
||||
boot_script=str(arguments.get("boot_script", "")),
|
||||
run_as_uid=str(arguments.get("run_as_uid", "")),
|
||||
start_on_boot=start_on_boot,
|
||||
env=arguments.get("env", ""),
|
||||
cpu_limit=str(arguments.get("cpu_limit", "")),
|
||||
mem_limit=str(arguments.get("mem_limit", "")),
|
||||
@@ -105,8 +115,8 @@ class ContainerController:
|
||||
if action == "delete":
|
||||
api.mark_for_removal(inst, actor=actor)
|
||||
elif action == "sync":
|
||||
count = await api.sync_workspace(inst, self._actor_user())
|
||||
return json.dumps({"status": "synced", "imported": count})
|
||||
counts = await api.sync_workspace(inst, self._actor_user())
|
||||
return json.dumps({"status": "synced", **counts})
|
||||
elif action == "restart":
|
||||
api.request_restart(inst, actor=actor)
|
||||
elif action in ("start", "resume"):
|
||||
@@ -119,6 +129,32 @@ class ContainerController:
|
||||
raise ToolInputError(f"unknown action: {action}")
|
||||
return json.dumps({"status": "ok", "action": action, "instance": inst["uid"]})
|
||||
|
||||
async def _configure_instance(self, arguments) -> str:
|
||||
project = self._project(arguments)
|
||||
inst = self._instance(project, str(arguments.get("instance", "")))
|
||||
actor = ("user", self._actor_user()["uid"])
|
||||
kwargs: dict = {}
|
||||
for key in (
|
||||
"run_as_uid",
|
||||
"boot_language",
|
||||
"boot_script",
|
||||
"boot_command",
|
||||
"restart_policy",
|
||||
"cpu_limit",
|
||||
"mem_limit",
|
||||
):
|
||||
if key in arguments and arguments.get(key) is not None:
|
||||
kwargs[key] = str(arguments.get(key))
|
||||
if "start_on_boot" in arguments and arguments.get("start_on_boot") is not None:
|
||||
kwargs["start_on_boot"] = str(arguments.get("start_on_boot")).lower() in (
|
||||
"true",
|
||||
"1",
|
||||
"yes",
|
||||
"on",
|
||||
)
|
||||
updated = api.update_instance_config(inst, actor=actor, **kwargs)
|
||||
return json.dumps({"status": "configured", "instance": updated}, default=str)
|
||||
|
||||
async def _logs(self, arguments) -> str:
|
||||
project = self._project(arguments)
|
||||
inst = self._instance(project, str(arguments.get("instance", "")))
|
||||
|
||||
Reference in New Issue
Block a user