mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-11-04 03:42:14 +00:00
feat(claude_desktop): add opt-in cpu_limit and memory_limit options (#3180)
Supervisor exposes no CPU or memory limit for add-ons and `docker update` is lost when the container is recreated, so apply the limits to a child cgroup at every start. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d5afc983f3
commit
b2ee4ceb3b
4 files changed
+75
-1
No files matched your search
@@ -1,4 +1,7 @@
|
|||||||
|
|
||||||
|
## 07308545.23 (2026-11-01)
|
||||||
|
- Add the optional `cpu_limit` (cores) and `memory_limit` (for example `6G`) options, which cap the whole add-on and persist across restarts. Unset keeps the current unlimited behaviour
|
||||||
|
|
||||||
## 07308545.22 (2026-10-31)
|
## 07308545.22 (2026-10-31)
|
||||||
- Update to latest version from aaddrick/claude-desktop-debian (changelog : https://github.com/aaddrick/claude-desktop-debian/releases)
|
- Update to latest version from aaddrick/claude-desktop-debian (changelog : https://github.com/aaddrick/claude-desktop-debian/releases)
|
||||||
- Upstream tag : v3.3.14+claude4.29.0
|
- Upstream tag : v3.3.14+claude4.29.0
|
||||||
|
|||||||
@@ -125,9 +125,19 @@ Git synchronization hooks. A repository is indexed only when it is listed in
|
|||||||
| `enable_ha_api_helper` | `true` | Ship the `ha-cli` Core-API helper and add guidance so Claude can configure Home Assistant without a `/config` mount. |
|
| `enable_ha_api_helper` | `true` | Ship the `ha-cli` Core-API helper and add guidance so Claude can configure Home Assistant without a `/config` mount. |
|
||||||
| `additional_apps` | | Comma-separated Debian apt packages to install at startup. |
|
| `additional_apps` | | Comma-separated Debian apt packages to install at startup. |
|
||||||
| `additional_pip` | | Comma-separated pip packages installed at startup (via `uv`). |
|
| `additional_pip` | | Comma-separated pip packages installed at startup (via `uv`). |
|
||||||
|
| `cpu_limit` | | Optional cap on the whole add-on, in CPU cores (for example `2` or `1.5`). Unset means unlimited. See [Limiting CPU and memory](#limiting-cpu-and-memory). |
|
||||||
|
| `memory_limit` | | Optional memory cap on the whole add-on, for example `6G` or `4096M`. Unset means unlimited. |
|
||||||
| `data_location` | `/data/data` | Persistent home directory for Claude and tooling. |
|
| `data_location` | `/data/data` | Persistent home directory for Claude and tooling. |
|
||||||
| `env_vars` | `[]` | Additional environment variables exported inside the container. |
|
| `env_vars` | `[]` | Additional environment variables exported inside the container. |
|
||||||
|
|
||||||
|
### Limiting CPU and memory
|
||||||
|
|
||||||
|
Home Assistant has no CPU or memory setting for add-ons, and a manual `docker update` is lost when the add-on restarts. `cpu_limit` and `memory_limit` are applied at every start instead, to everything in the add-on: the desktop, the web interface and all Claude Code sessions with their builds and tests. Changing them requires an add-on restart.
|
||||||
|
|
||||||
|
- `cpu_limit` throttles without killing anything, so a low value also slows the web interface.
|
||||||
|
- `memory_limit` caps RAM, and allows the same amount again in swap (as `docker --memory` does). Beyond that, the kernel kills a process in the add-on, usually the largest, which can be a running session.
|
||||||
|
- Both need cgroup v2, which Home Assistant OS uses. If it is not available, the add-on logs a warning and starts without limits.
|
||||||
|
|
||||||
### Permission modes
|
### Permission modes
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|||||||
@@ -145,7 +145,9 @@ schema:
|
|||||||
cifsdomain: str?
|
cifsdomain: str?
|
||||||
cifspassword: str?
|
cifspassword: str?
|
||||||
cifsusername: str?
|
cifsusername: str?
|
||||||
|
cpu_limit: float(0.1,)?
|
||||||
localdisks: str?
|
localdisks: str?
|
||||||
|
memory_limit: match(^[1-9][0-9]*[MmGg]$)?
|
||||||
networkdisks: str?
|
networkdisks: str?
|
||||||
github_email: str?
|
github_email: str?
|
||||||
enable_ha_mcp: bool?
|
enable_ha_mcp: bool?
|
||||||
@@ -175,5 +177,5 @@ schema:
|
|||||||
slug: claude_desktop
|
slug: claude_desktop
|
||||||
udev: true
|
udev: true
|
||||||
url: https://github.com/alexbelgium/hassio-addons
|
url: https://github.com/alexbelgium/hassio-addons
|
||||||
version: "07308545.22"
|
version: "07308545.23"
|
||||||
video: true
|
video: true
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/with-contenv bashio
|
||||||
|
# shellcheck shell=bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Apply the optional cpu_limit / memory_limit options.
|
||||||
|
#
|
||||||
|
# Supervisor has no CPU or memory key for add-ons, and `docker update` is lost when it recreates
|
||||||
|
# the container, so the limits are set on a child cgroup at every start. nsdelegate forbids
|
||||||
|
# writing cpu.max / memory.max on the container's own cgroup, and a cgroup can only delegate
|
||||||
|
# controllers once it holds no process, hence moving everything to the child first. This runs
|
||||||
|
# early because memory already charged stays with the parent.
|
||||||
|
|
||||||
|
cpu_limit=""
|
||||||
|
memory_limit=""
|
||||||
|
if bashio::config.has_value 'cpu_limit'; then
|
||||||
|
cpu_limit="$(bashio::config 'cpu_limit')"
|
||||||
|
fi
|
||||||
|
if bashio::config.has_value 'memory_limit'; then
|
||||||
|
memory_limit="$(bashio::config 'memory_limit')"
|
||||||
|
fi
|
||||||
|
if [[ -z "$cpu_limit" && -z "$memory_limit" ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cgroup="$(mktemp -d)"
|
||||||
|
if ! mount -t cgroup2 none "$cgroup"; then
|
||||||
|
bashio::log.warning "Could not mount cgroup2: cpu_limit and memory_limit are not applied"
|
||||||
|
rmdir "$cgroup"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$cgroup/addon"
|
||||||
|
delegated=false
|
||||||
|
# Retry because processes forked during the move land in the parent and make the write fail
|
||||||
|
for _ in 1 2 3 4 5; do
|
||||||
|
xargs -rn1 < "$cgroup/cgroup.procs" > "$cgroup/addon/cgroup.procs" || true
|
||||||
|
if echo "+cpu +memory" 2> /dev/null > "$cgroup/cgroup.subtree_control"; then
|
||||||
|
delegated=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$delegated" != true ]]; then
|
||||||
|
bashio::log.warning "Could not enable the cgroup v2 controllers: cpu_limit and memory_limit are not applied"
|
||||||
|
else
|
||||||
|
if [[ -n "$cpu_limit" ]]; then
|
||||||
|
awk -v cpus="$cpu_limit" 'BEGIN { printf "%.0f 100000\n", cpus * 100000 }' > "$cgroup/addon/cpu.max"
|
||||||
|
bashio::log.info "CPU limited to $cpu_limit core(s)"
|
||||||
|
fi
|
||||||
|
if [[ -n "$memory_limit" ]]; then
|
||||||
|
echo "$memory_limit" > "$cgroup/addon/memory.max"
|
||||||
|
# As with docker --memory: as much swap again, so idle sessions can still be swapped out
|
||||||
|
echo "$memory_limit" > "$cgroup/addon/memory.swap.max"
|
||||||
|
bashio::log.info "Memory limited to $memory_limit"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
umount "$cgroup"
|
||||||
|
rmdir "$cgroup"
|
||||||
Reference in new issue
Block a user