Merge pull request #1339 from kernelkit/container-operational

cli: use operational data in `show container [name]`
This commit is contained in:
Joachim Wiberg
2026-01-02 21:08:22 +01:00
committed by GitHub
11 changed files with 811 additions and 258 deletions
+4 -12
View File
@@ -1,16 +1,8 @@
# Virtual filesystems
devtmpfs /dev devtmpfs defaults 0 0
mkdir#-p /dev/pts helper none 0 0
devpts /dev/pts devpts mode=620,ptmxmode=0666 0 0
mkdir#-p /dev/shm helper none 0 0
tmpfs /dev/shm tmpfs mode=0777 0 0
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs mode=1777,nosuid,nodev 0 0
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
tmpfs /media tmpfs mode=1755,nosuid,nodev 0 0
sysfs /sys sysfs defaults 0 0
debugfs /sys/kernel/debug debugfs nofail 0 0
cfgfs /config configfs nofail,noauto 0 0
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
tmpfs /media tmpfs mode=1755,nosuid,nodev 0 0
debugfs /sys/kernel/debug debugfs nofail 0 0
cfgfs /config configfs nofail,noauto 0 0
# The chosen backing storage for the overlays placed on /cfg, /etc,
# /home, /root, and /var, are determined dynamically by /usr/libexec/infix/mnt
+5
View File
@@ -17,10 +17,15 @@ All notable changes to the project are documented in this file.
can now be enabled per category (bfd, packet, ism, nsm, default-information,
nssa). All debug options are disabled by default to prevent log flooding in
production environments. See the documentation for usage examples
- Add support for configurable container resource limits, memory and CPU.
Resource usage is available through the operational datastore, where the
currently active resource limits in the container runtime are also available
- Add support for "routing interfaces", issue #647. Lists interfaces with IP
forwarding. Inspect from CLI using `show interface`, look for `⇅` flag
- Add operational data journal to statd with hierarchical time-based retention
policy, keeping snapshots from every 5 minutes (recent) to yearly (historical)
- Add support data collection script, useful when troubleshooting issues on
deployed systems. Gathers system information, logs, and more. Issue #1287
### Fixes
+40
View File
@@ -488,6 +488,46 @@ time and analysis of your container application to figure out which
capabilities you need.
Resource Limits
---------------
Containers can be configured with resource limits to control their memory
and CPU usage. This helps prevent containers from consuming excessive system
resources and ensures fair resource allocation across multiple containers.
### Configuring Resource Limits
Resource limits are set per container and include:
- **Memory:** Maximum memory usage in kibibytes (KiB)
- **CPU:** Maximum CPU usage in millicores (1000 millicores = 1 CPU core)
Example configuration limiting a container to 512 MiB of memory and 1.5 CPU cores:
admin@example:/> configure
admin@example:/config/> edit container web
admin@example:/config/container/web/> edit resource-limit
admin@example:/config/container/web/resource-limit/> set memory 524288
admin@example:/config/container/web/resource-limit/> set cpu 1500
admin@example:/config/container/web/resource-limit/> leave
Common CPU limit examples:
- `500` = 0.5 cores (50% of one core)
- `1000` = 1.0 cores (one full core)
- `2000` = 2.0 cores (two full cores)
### Monitoring Resource Usage
Runtime resource usage statistics are available in the operational datastore:
admin@example:/> show container web
...
Use `show container usage` to see resource consumption across all containers,
including memory, CPU, block I/O, network I/O, and process counts.
Networking and Containers
-------------------------
+1 -1
View File
@@ -1,5 +1,5 @@
# From https://github.com/troglobit/finit/releases/
sha256 7ccbcead4e3e6734c81a8c5445f4a27738f19a4ab367d702513a201db9b618c7 finit-4.15-rc1.tar.gz
sha256 0e4774ccb8933ed92287e6c18d27cb463222dcc1f50a3607e27bbe5fd150ece0 finit-4.15.tar.gz
# Locally calculated
sha256 868cb6c5414933a48db11186042cfe65c87480d326734bc6cf0e4b19b4a2e52a LICENSE
+1 -1
View File
@@ -4,7 +4,7 @@
#
################################################################################
FINIT_VERSION = 4.15-rc1
FINIT_VERSION = 4.15
FINIT_SITE = https://github.com/troglobit/finit/releases/download/$(FINIT_VERSION)
FINIT_LICENSE = MIT
FINIT_LICENSE_FILES = LICENSE
+11 -6
View File
@@ -186,14 +186,11 @@
</COMMAND>
<COMMAND name="show" help="Show system status and configuration files" mode="switch">
<COMMAND name="container" help="Show container status">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas container show |pager
</ACTION>
<SWITCH name="optional" min="0">
<COMMAND name="container" help="Show container status">
<SWITCH name="subcommands" min="0">
<COMMAND name="all" help="Show all containers (default only running)">
<ACTION sym="script">doas container -a show</ACTION>
<ACTION sym="script">show container</ACTION>
</COMMAND>
<COMMAND name="log" help="Show container log (jumps to end), alias to 'show log container'">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
@@ -231,7 +228,15 @@
</ACTION>
</COMMAND>
</SWITCH>
<SWITCH name="optional" min="0" max="1">
<PARAM name="name" ptype="/CONTAINERS" help="Container name for detailed view" />
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
show container $KLISH_PARAM_name |pager
</ACTION>
</COMMAND>
</COMMAND>
</VIEW>
+9 -1
View File
@@ -638,10 +638,18 @@
<COMMAND name="firewall" help="Show firewall status and configuration">
<SWITCH name="optional" min="0" max="1">
<COMMAND name="log" help="Show firewall log (jumps to end), alias to 'show log firewall.log'">
<SWITCH name="optional" min="0">
<PARAM name="limit" ptype="/UINT" help="Last N lines, default: all"/>
</SWITCH>
<ACTION sym="script" in="tty" out="tty" interrupt="true">
doas -u $USER cat /log/firewall.log |pager +G
sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-log $KLISH_PARAM_limit |pager +G
</ACTION>
</COMMAND>
<COMMAND name="matrix" help="Show firewall zone matrix">
<ACTION sym="script" in="tty" out="tty" interrupt="true">
sysrepocfg -X -d operational -x /infix-firewall:firewall -f json -t 60 | /usr/libexec/statd/cli-pretty show-firewall-matrix
</ACTION>
</COMMAND>
<COMMAND name="zone" help="Show firewall zones">
<SWITCH name="optional" min="0">
<PARAM name="name" ptype="/FIREWALL_ZONES" help="Zone name"/>
+59
View File
@@ -173,6 +173,64 @@ def services(args: List[str]) -> None:
cli_pretty(data, f"show-services")
def container(args: List[str]) -> None:
"""Handle show container [name]
Arguments:
(none) - Show all containers in table format
name - Show detailed view of specific container
"""
data = run_sysrepocfg("/infix-containers:containers")
if not data:
print("No container data retrieved.")
return
# Fetch interface data for bridge resolution (both table and detailed views)
# Fetch operational interface data
iface_oper = run_sysrepocfg("/ietf-interfaces:interfaces")
# Also fetch config data for veth peer information (not in operational)
try:
result = subprocess.run([
"sysrepocfg", "-f", "json", "-X", "-d", "running", "-x", "/ietf-interfaces:interfaces"
], capture_output=True, text=True, check=True)
iface_config = json.loads(result.stdout)
# Merge config veth peer info into operational data
if iface_oper and iface_config:
oper_ifaces = iface_oper.get('ietf-interfaces:interfaces', {}).get('interface', [])
config_ifaces = iface_config.get('ietf-interfaces:interfaces', {}).get('interface', [])
# Create a map of config interfaces
config_map = {iface['name']: iface for iface in config_ifaces}
# Merge veth peer info from config into operational
for oper_iface in oper_ifaces:
name = oper_iface.get('name')
if name in config_map:
config_iface = config_map[name]
# Add veth peer if it exists in config but not in operational
if 'infix-interfaces:veth' in config_iface and 'infix-interfaces:veth' not in oper_iface:
oper_iface['infix-interfaces:veth'] = config_iface['infix-interfaces:veth']
data.update(iface_oper)
except (subprocess.CalledProcessError, json.JSONDecodeError):
# If config fetch fails, just use operational data
if iface_oper:
data.update(iface_oper)
if RAW_OUTPUT:
print(json.dumps(data, indent=2))
return
if len(args) == 0 or not args[0]:
cli_pretty(data, "show-container")
elif len(args) == 1:
name = args[0]
cli_pretty(data, "show-container-detail", name)
else:
print("Too many arguments provided. Expected: show container [name]")
def bfd(args: List[str]) -> None:
"""Handle show bfd [subcommand] [peer] [brief]
@@ -486,6 +544,7 @@ def execute_command(command: str, args: List[str]):
command_mapping = {
'bfd': bfd,
'boot-order': boot_order,
'container': container,
'dhcp': dhcp,
'hardware': hardware,
'interface': interface,
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -49,7 +49,7 @@ with infamy.Test() as test:
},
"resource-limit": {
"memory": 512, # 512 KiB
"cpu": 50000 # 50% of one CPU
"cpu": 500 # 50% of one CPU (0.5 cores)
}
}
]
@@ -70,7 +70,7 @@ with infamy.Test() as test:
limits = web.get("resource-limit", {})
assert limits.get("memory") == 512, "Memory limit not set correctly"
assert limits.get("cpu") == 50000, "CPU limit not set correctly"
assert limits.get("cpu") == 500, "CPU limit not set correctly"
rusage = web.get("resource-usage", {})
assert rusage is not None, "Resource usage data not available"
+2 -2
View File
@@ -1,4 +1,4 @@
NAME STATUS PID MEM UP RST DESCRIPTION
NAME STATUS PID MEM UP RST DESCRIPTION 
udevd running 1185 23m 0 Device event daemon (udev)
dbus running 2248 23m 0 D-Bus message bus daemon
confd running 3039 23m 0 Configuration daemon
@@ -7,7 +7,7 @@ dnsmasq running 2249 23m 0 DHCP/DNS proxy
tty:hvc0 running 3559 23m 0 Getty on hvc0
iitod running 2340 23m 0 LED daemon
klishd running 3560 23m 0 CLI backend daemon
mdns-alias running 3617 23m 0 mDNS alias advertiser
mdns-alias running 3617 23m 0 mDNS alias advertiser
mstpd stopped 0 Spanning Tree daemon
rauc running 3564 23m 0 Software update service
resolvconf done 2 Update DNS configuration