Merge "Add systemd healthchecks to podman"

This commit is contained in:
Zuul 2018-12-13 23:18:35 +00:00 committed by Gerrit Code Review
commit 077a8d95c3
4 changed files with 132 additions and 1 deletions

View File

@ -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):

View File

@ -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')))

View File

@ -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']),
])

View File

@ -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'])