mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
Merge pull request #1339 from kernelkit/container-operational
cli: use operational data in `show container [name]`
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[7mNAME STATUS PID MEM UP RST DESCRIPTION[0m
|
||||
[7mNAME STATUS PID MEM UP RST DESCRIPTION [0m
|
||||
udevd [32mrunning[39m 1185 23m 0 Device event daemon (udev)
|
||||
dbus [32mrunning[39m 2248 23m 0 D-Bus message bus daemon
|
||||
confd [32mrunning[39m 3039 23m 0 Configuration daemon
|
||||
@@ -7,7 +7,7 @@ dnsmasq [32mrunning[39m 2249 23m 0 DHCP/DNS proxy
|
||||
tty:hvc0 [32mrunning[39m 3559 23m 0 Getty on hvc0
|
||||
iitod [32mrunning[39m 2340 23m 0 LED daemon
|
||||
klishd [32mrunning[39m 3560 23m 0 CLI backend daemon
|
||||
mdns-alias [32mrunning[39m 3617 23m 0 mDNS alias advertiser
|
||||
mdns-alias [32mrunning[39m 3617 23m 0 mDNS alias advertiser
|
||||
mstpd [33mstopped[39m 0 Spanning Tree daemon
|
||||
rauc [32mrunning[39m 3564 23m 0 Software update service
|
||||
resolvconf [32mdone[39m 2 Update DNS configuration
|
||||
|
||||
Reference in New Issue
Block a user