Merge "Add systemd healthchecks to podman"
This commit is contained in:
commit
077a8d95c3
|
@ -104,6 +104,13 @@ class BaseBuilder(object):
|
|||
systemd.service_create(container=container_name,
|
||||
cconfig=cconfig,
|
||||
log=self.log)
|
||||
if 'healthcheck' in cconfig:
|
||||
systemd.healthcheck_create(container=container_name,
|
||||
log=self.log)
|
||||
systemd.healthcheck_timer_create(
|
||||
container=container_name,
|
||||
cconfig=cconfig,
|
||||
log=self.log)
|
||||
return stdout, stderr, deploy_status_code
|
||||
|
||||
def delete_missing_and_updated(self):
|
||||
|
|
|
@ -63,6 +63,7 @@ class PodmanBuilder(base.BaseBuilder):
|
|||
|
||||
self.list_arg(cconfig, cmd, 'cap_add', '--cap-add')
|
||||
self.list_arg(cconfig, cmd, 'cap_drop', '--cap-drop')
|
||||
self.string_arg(cconfig, cmd, 'check_interval', '--check-interval')
|
||||
|
||||
cmd.append(cconfig.get('image', ''))
|
||||
cmd.extend(self.command_argument(cconfig.get('command')))
|
||||
|
|
|
@ -60,3 +60,45 @@ class TestUtilsSystemd(base.TestCase):
|
|||
mock.call(['systemctl', 'disable', service]),
|
||||
mock.call(['systemctl', 'daemon-reload']),
|
||||
])
|
||||
|
||||
@mock.patch('subprocess.call', autospec=True)
|
||||
@mock.patch('os.chmod')
|
||||
def test_healthcheck_create(self, mock_chmod, mock_subprocess_call):
|
||||
container = 'my_app'
|
||||
service = 'tripleo_' + container
|
||||
tempdir = tempfile.mkdtemp()
|
||||
healthcheck = service + '_healthcheck.service'
|
||||
sysd_unit_f = tempdir + healthcheck
|
||||
|
||||
systemd.healthcheck_create(container, tempdir)
|
||||
unit = open(sysd_unit_f, 'rt').read()
|
||||
|
||||
self.assertIn('ExecStart=/usr/bin/podman exec my_app '
|
||||
'/openstack/healthcheck', unit)
|
||||
mock_chmod.assert_has_calls([mock.call(sysd_unit_f, 420)])
|
||||
mock_subprocess_call.assert_has_calls([
|
||||
mock.call(['systemctl', 'enable', '--now',
|
||||
healthcheck]),
|
||||
mock.call(['systemctl', 'daemon-reload']),
|
||||
])
|
||||
|
||||
@mock.patch('subprocess.call', autospec=True)
|
||||
@mock.patch('os.chmod')
|
||||
def test_healthcheck_timer_create(self, mock_chmod, mock_subprocess_call):
|
||||
container = 'my_app'
|
||||
service = 'tripleo_' + container
|
||||
cconfig = {'check_interval': '15'}
|
||||
tempdir = tempfile.mkdtemp()
|
||||
healthcheck_timer = service + '_healthcheck.timer'
|
||||
sysd_unit_f = tempdir + healthcheck_timer
|
||||
|
||||
systemd.healthcheck_timer_create(container, cconfig, tempdir)
|
||||
unit = open(sysd_unit_f, 'rt').read()
|
||||
|
||||
self.assertIn('Requires=my_app_healthcheck.service', unit)
|
||||
self.assertIn('OnCalendar=*-*-* *:*:00/15', unit)
|
||||
mock_chmod.assert_has_calls([mock.call(sysd_unit_f, 420)])
|
||||
mock_subprocess_call.assert_has_calls([
|
||||
mock.call(['systemctl', 'enable', '--now', healthcheck_timer]),
|
||||
mock.call(['systemctl', 'daemon-reload']),
|
||||
])
|
||||
|
|
|
@ -31,7 +31,7 @@ def service_create(container, cconfig, sysdir=constants.SYSTEMD_DIR,
|
|||
:type cconfig: Dictionary
|
||||
|
||||
:param sysdir: systemd unit files directory
|
||||
:type sysdir: string
|
||||
:type sysdir: String
|
||||
|
||||
:param log: optional pre-defined logger for messages
|
||||
:type log: logging.RootLogger
|
||||
|
@ -109,3 +109,84 @@ def service_delete(container, sysdir=constants.SYSTEMD_DIR, log=None):
|
|||
subprocess.call(['systemctl', 'daemon-reload'])
|
||||
else:
|
||||
log.warning('No systemd unit file was found for %s' % service)
|
||||
|
||||
|
||||
def healthcheck_create(container, sysdir='/etc/systemd/system/', log=None):
|
||||
"""Create a healthcheck for a service in systemd
|
||||
|
||||
:param container: container name
|
||||
:type container: String
|
||||
|
||||
:param sysdir: systemd unit files directory
|
||||
:type sysdir: String
|
||||
|
||||
:param log: optional pre-defined logger for messages
|
||||
:type log: logging.RootLogger
|
||||
"""
|
||||
|
||||
log = log or common.configure_logging(__name__)
|
||||
|
||||
service = 'tripleo_' + container
|
||||
healthcheck = service + '_healthcheck.service'
|
||||
sysd_unit_f = sysdir + healthcheck
|
||||
log.debug('Creating systemd unit file: %s' % sysd_unit_f)
|
||||
s_config = {
|
||||
'name': container,
|
||||
'restart': 'restart',
|
||||
}
|
||||
with open(sysd_unit_f, 'w') as unit_file:
|
||||
os.chmod(unit_file.name, 0o644)
|
||||
unit_file.write("""[Unit]
|
||||
Description=%(name)s healthcheck
|
||||
After=paunch-container-shutdown.service
|
||||
Requisite=%(name)s.service
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/podman exec %(name)s /openstack/healthcheck
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
""" % s_config)
|
||||
subprocess.call(['systemctl', 'enable', '--now', healthcheck])
|
||||
subprocess.call(['systemctl', 'daemon-reload'])
|
||||
|
||||
|
||||
def healthcheck_timer_create(container, cconfig, sysdir='/etc/systemd/system/',
|
||||
log=None):
|
||||
"""Create a systemd timer for a healthcheck
|
||||
|
||||
:param container: container name
|
||||
:type container: String
|
||||
|
||||
:param cconfig: container configuration
|
||||
:type cconfig: Dictionary
|
||||
|
||||
:param sysdir: systemd unit files directory
|
||||
:type sysdir: string
|
||||
|
||||
:param log: optional pre-defined logger for messages
|
||||
:type log: logging.RootLogger
|
||||
"""
|
||||
|
||||
log = log or common.configure_logging(__name__)
|
||||
|
||||
service = 'tripleo_' + container
|
||||
healthcheck_timer = service + '_healthcheck.timer'
|
||||
sysd_timer_f = sysdir + healthcheck_timer
|
||||
log.debug('Creating systemd timer file: %s' % sysd_timer_f)
|
||||
interval = cconfig.get('check_interval', 30)
|
||||
s_config = {
|
||||
'name': container,
|
||||
'interval': interval
|
||||
}
|
||||
with open(sysd_timer_f, 'w') as timer_file:
|
||||
os.chmod(timer_file.name, 0o644)
|
||||
timer_file.write("""[Unit]
|
||||
Description=%(name)s container healthcheck
|
||||
Requires=%(name)s_healthcheck.service
|
||||
[Timer]
|
||||
OnUnitActiveSec=90
|
||||
OnCalendar=*-*-* *:*:00/%(interval)s
|
||||
[Install]
|
||||
WantedBy=timers.target""" % s_config)
|
||||
subprocess.call(['systemctl', 'enable', '--now', healthcheck_timer])
|
||||
subprocess.call(['systemctl', 'daemon-reload'])
|
||||
|
|
Loading…
Reference in New Issue