summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2025-10-30 14:41:53 +0000
committerGitHub <noreply@github.com>2025-10-30 14:41:53 +0000
commit524a91424b9bc4e4b3963c049422fe689b60ec38 (patch)
treef515cbb80f6909c570ede69025e6dcfcbcfe37e7
parent449f3d4dbf1f55a7cfcd8ecf450f9ebc93188d97 (diff)
parentbd3070477804ed03e356d95e8c619fe7580b9231 (diff)
downloadvyos-1x-524a91424b9bc4e4b3963c049422fe689b60ec38.tar.gz
vyos-1x-524a91424b9bc4e4b3963c049422fe689b60ec38.zip
Merge pull request #4702 from nvollmar/T6686
T6686: adds container health checks
-rw-r--r--interface-definitions/container.xml.in60
-rwxr-xr-xsmoketest/scripts/cli/test_container.py20
-rwxr-xr-xsrc/conf_mode/container.py22
3 files changed, 100 insertions, 2 deletions
diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in
index c0afde48f..f19beedb9 100644
--- a/interface-definitions/container.xml.in
+++ b/interface-definitions/container.xml.in
@@ -574,6 +574,66 @@
</properties>
<defaultValue>journald</defaultValue>
</leafNode>
+ <node name="health-check">
+ <properties>
+ <help>Configure container health checks</help>
+ </properties>
+ <children>
+ <leafNode name="command">
+ <properties>
+ <help>Health check command to run for the container</help>
+ </properties>
+ </leafNode>
+ <leafNode name="interval">
+ <properties>
+ <help>Overwrite related health check configuration from the image</help>
+ <completionHelp>
+ <list>disable</list>
+ </completionHelp>
+ <valueHelp>
+ <format>disable</format>
+ <description>No automatic timer setup</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:1-16384</format>
+ <description>Time in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-16384"/>
+ <regex>(disable)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="timeout">
+ <properties>
+ <help>Timeout for the health check to complete</help>
+ <valueHelp>
+ <format>u32:1-16384</format>
+ <description>Time in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-16384"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="retry">
+ <properties>
+ <help>The number of retries before container is consider unhealthy</help>
+ <valueHelp>
+ <format>0</format>
+ <description>No retry</description>
+ </valueHelp>
+ <valueHelp>
+ <format>u32:1-255</format>
+ <description>Number of retries</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
</children>
</tagNode>
<tagNode name="network">
diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py
index 2317d7a4b..b41a7dd53 100755
--- a/smoketest/scripts/cli/test_container.py
+++ b/smoketest/scripts/cli/test_container.py
@@ -112,6 +112,26 @@ class TestContainer(VyOSUnitTestSHIM.TestCase):
l = cmd_to_json(f'sudo podman container inspect {cont_name}')
self.assertEqual(l['HostConfig']['LogConfig']['Type'], 'journald')
+ self.assertEqual(l['Config']['Healthcheck']['Test'], ['NONE'])
+
+ def test_healthcheck(self):
+ cont_name = 'health-test'
+
+ self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])
+ self.cli_set(base_path + ['name', cont_name, 'image', busybox_image])
+
+ self.cli_set(base_path + ['name', cont_name, 'health-check', 'command', 'true'])
+ self.cli_set(base_path + ['name', cont_name, 'health-check', 'interval', '10'])
+ self.cli_set(base_path + ['name', cont_name, 'health-check', 'timeout', '1'])
+ self.cli_set(base_path + ['name', cont_name, 'health-check', 'retry', '2'])
+ self.cli_commit()
+
+ l = cmd_to_json(f'sudo podman container inspect {cont_name}')
+ self.assertEqual(l['HostConfig']['LogConfig']['Type'], 'journald')
+ self.assertEqual(l['Config']['Healthcheck']['Test'], ['CMD-SHELL', 'true'])
+ self.assertEqual(l['Config']['Healthcheck']['Interval'], 10000000000)
+ self.assertEqual(l['Config']['Healthcheck']['Timeout'], 1000000000)
+ self.assertEqual(l['Config']['Healthcheck']['Retries'], 2)
def test_name_server(self):
diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py
index b8c3d3d0c..a57a9d054 100755
--- a/src/conf_mode/container.py
+++ b/src/conf_mode/container.py
@@ -479,6 +479,24 @@ def generate_run_arguments(name, container_config, host_ident):
entrypoint = json_write(container_config['entrypoint'].split()).replace('"', "&quot;")
entrypoint = f'--entrypoint &apos;{entrypoint}&apos;'
+ healthcheck = ' --no-healthcheck'
+ if 'health_check' in container_config:
+ healthcheck = ''
+ if 'command' in container_config['health_check']:
+ health_cmd = container_config['health_check']['command']
+ healthcheck += f' --health-cmd="{health_cmd}"'
+ if 'interval' in container_config['health_check']:
+ health_int = container_config['health_check']['interval']
+ if health_int != 'disable':
+ health_int = f'{health_int}s'
+ healthcheck += f' --health-interval={health_int}'
+ if 'timeout' in container_config['health_check']:
+ health_to = container_config['health_check']['timeout']
+ healthcheck += f' --health-timeout={health_to}s'
+ if 'retry' in container_config['health_check']:
+ health_rt = container_config['health_check']['retry']
+ healthcheck += f' --health-retries={health_rt}'
+
command = ''
if 'command' in container_config:
command = container_config['command'].strip()
@@ -488,7 +506,7 @@ def generate_run_arguments(name, container_config, host_ident):
command_arguments = container_config['arguments'].strip()
if 'allow_host_networks' in container_config:
- return f'{container_base_cmd} --net host {entrypoint} {image} {command} {command_arguments}'.strip()
+ return f'{container_base_cmd} {healthcheck} --net host {entrypoint} {image} {command} {command_arguments}'.strip()
ip_param = ''
addr_info = ''
@@ -520,7 +538,7 @@ def generate_run_arguments(name, container_config, host_ident):
delete_cli_node(mac_config_path)
add_cli_node(mac_config_path, value=mac_add)
- return f'{container_base_cmd} --no-healthcheck --net {networks} {ip_param} {mac_address} {entrypoint} {image} {command} {command_arguments}'.strip()
+ return f'{container_base_cmd} {healthcheck} --net {networks} {ip_param} {mac_address} {entrypoint} {image} {command} {command_arguments}'.strip()
def generate(container):