Add systemd init support for deploy from source

systemd is used instead of upstart by default since Ubuntu 15.10
(Wily).  This adds systemd init file support for cinder services
that are deployed from source.

Change-Id: I476074659c03d44a78dd607e7a91c87de0734562
This commit is contained in:
Corey Bryant 2016-05-24 10:18:52 -04:00
parent 1f419323bf
commit 9803fbc934
7 changed files with 253 additions and 66 deletions

View File

@ -25,6 +25,7 @@ import sys
import re
import itertools
import functools
import shutil
import six
import tempfile
@ -858,6 +859,47 @@ def git_yaml_value(projects_yaml, key):
return None
def git_generate_systemd_init_files(templates_dir):
"""
Generate systemd init files.
Generates and installs systemd init units and script files based on the
*.init.in files contained in the templates_dir directory.
This code is based on the openstack-pkg-tools package and its init
script generation, which is used by the OpenStack packages.
"""
for f in os.listdir(templates_dir):
if f.endswith(".init.in"):
init_in_file = f
init_file = f[:-8]
service_file = "{}.service".format(init_file)
init_in_source = os.path.join(templates_dir, init_in_file)
init_source = os.path.join(templates_dir, init_file)
service_source = os.path.join(templates_dir, service_file)
init_dest = os.path.join('/etc/init.d', init_file)
service_dest = os.path.join('/lib/systemd/system', service_file)
shutil.copyfile(init_in_source, init_source)
with open(init_source, 'a') as outfile:
template = '/usr/share/openstack-pkg-tools/init-script-template'
with open(template) as infile:
outfile.write('\n\n{}'.format(infile.read()))
cmd = ['pkgos-gen-systemd-unit', init_in_source]
subprocess.check_call(cmd)
if os.path.exists(init_dest):
os.remove(init_dest)
if os.path.exists(service_dest):
os.remove(service_dest)
shutil.move(init_source, init_dest)
shutil.move(service_source, service_dest)
os.chmod(init_dest, 0o755)
def os_workload_status(configs, required_interfaces, charm_func=None):
"""
Decorator to set workload status based on complete contexts

View File

@ -78,11 +78,12 @@ from charmhelpers.contrib.openstack import (
from charmhelpers.contrib.openstack.utils import (
configure_installation_source,
get_os_codename_install_source,
git_install_requested,
git_clone_and_install,
git_generate_systemd_init_files,
git_install_requested,
git_pip_venv_dir,
git_src_dir,
git_yaml_value,
git_pip_venv_dir,
os_release,
set_os_workload_status,
make_assess_status_func,
@ -123,6 +124,7 @@ BASE_GIT_PACKAGES = [
'libxslt1-dev',
'libyaml-dev',
'lvm2',
'openstack-pkg-tools',
'python-dev',
'python-pip',
'python-setuptools',
@ -783,61 +785,79 @@ def git_post_install(projects_yaml):
os.chmod('/etc/sudoers.d', 0o750)
bin_dir = os.path.join(git_pip_venv_dir(projects_yaml), 'bin')
cinder_api_context = {
'service_description': 'Cinder API server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-api',
'executable_name': os.path.join(bin_dir, 'cinder-api'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-api.log',
}
# Use systemd init units/scripts from ubuntu wily onward
if lsb_release()['DISTRIB_RELEASE'] >= '15.10':
templates_dir = os.path.join(charm_dir(), 'templates/git')
daemons = ['cinder-api', 'cinder-backup', 'cinder-scheduler',
'cinder-volume']
for daemon in daemons:
cinder_context = {
'daemon_path': os.path.join(bin_dir, daemon),
}
template_file = 'git/{}.init.in.template'.format(daemon)
init_in_file = '{}.init.in'.format(daemon)
render(template_file, os.path.join(templates_dir, init_in_file),
cinder_context, perms=0o644)
git_generate_systemd_init_files(templates_dir)
else:
cinder_api_context = {
'service_description': 'Cinder API server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-api',
'executable_name': os.path.join(bin_dir, 'cinder-api'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-api.log',
}
cinder_backup_context = {
'service_description': 'Cinder backup server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-backup',
'executable_name': os.path.join(bin_dir, 'cinder-backup'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-backup.log',
}
cinder_backup_context = {
'service_description': 'Cinder backup server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-backup',
'executable_name': os.path.join(bin_dir, 'cinder-backup'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-backup.log',
}
cinder_scheduler_context = {
'service_description': 'Cinder scheduler server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-scheduler',
'executable_name': os.path.join(bin_dir, 'cinder-scheduler'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-scheduler.log',
}
cinder_scheduler_context = {
'service_description': 'Cinder scheduler server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-scheduler',
'executable_name': os.path.join(bin_dir, 'cinder-scheduler'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-scheduler.log',
}
cinder_volume_context = {
'service_description': 'Cinder volume server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-volume',
'executable_name': os.path.join(bin_dir, 'cinder-volume'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-volume.log',
}
cinder_volume_context = {
'service_description': 'Cinder volume server',
'service_name': 'Cinder',
'user_name': 'cinder',
'start_dir': '/var/lib/cinder',
'process_name': 'cinder-volume',
'executable_name': os.path.join(bin_dir, 'cinder-volume'),
'config_files': ['/etc/cinder/cinder.conf'],
'log_file': '/var/log/cinder/cinder-volume.log',
}
# NOTE(coreycb): Needs systemd support
templates_dir = 'hooks/charmhelpers/contrib/openstack/templates'
templates_dir = os.path.join(charm_dir(), templates_dir)
render('git.upstart', '/etc/init/cinder-api.conf',
cinder_api_context, perms=0o644, templates_dir=templates_dir)
render('git.upstart', '/etc/init/cinder-backup.conf',
cinder_backup_context, perms=0o644, templates_dir=templates_dir)
render('git.upstart', '/etc/init/cinder-scheduler.conf',
cinder_scheduler_context, perms=0o644, templates_dir=templates_dir)
render('git.upstart', '/etc/init/cinder-volume.conf',
cinder_volume_context, perms=0o644, templates_dir=templates_dir)
templates_dir = 'hooks/charmhelpers/contrib/openstack/templates'
templates_dir = os.path.join(charm_dir(), templates_dir)
render('git.upstart', '/etc/init/cinder-api.conf',
cinder_api_context, perms=0o644,
templates_dir=templates_dir)
render('git.upstart', '/etc/init/cinder-backup.conf',
cinder_backup_context, perms=0o644,
templates_dir=templates_dir)
render('git.upstart', '/etc/init/cinder-scheduler.conf',
cinder_scheduler_context, perms=0o644,
templates_dir=templates_dir)
render('git.upstart', '/etc/init/cinder-volume.conf',
cinder_volume_context, perms=0o644,
templates_dir=templates_dir)
if not is_unit_paused_set():
service_restart('tgtd')

View File

@ -0,0 +1,22 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: cinder-api
# Required-Start: $network $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs
# Should-Start: postgresql mysql keystone rabbitmq-server ntp
# Should-Stop: postgresql mysql keystone rabbitmq-server ntp
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Cinder Api
# Description: Provides EBS like storage for your
# virtual machine instances
### END INIT INFO
# Author: Julien Danjou <acid@debian.org>, Thomas Goirand <zigo@debian.org>
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OpenStack Cinder Api"
PROJECT_NAME=cinder
NAME=${PROJECT_NAME}-api
DAEMON={{ daemon_path }}

View File

@ -0,0 +1,21 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: cinder-backup
# Required-Start: $network $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs
# Should-Start: postgresql mysql keystone rabbitmq-server ntp
# Should-Stop: postgresql mysql keystone rabbitmq-server ntp
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Cinder Backup
# Description: Provides Cinder Backup
### END INIT INFO
# Author: Thomas Goirand <zigo@debian.org>
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OpenStack Cinder Backup"
PROJECT_NAME=cinder
NAME=${PROJECT_NAME}-backup
DAEMON={{ daemon_path }}

View File

@ -0,0 +1,22 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: cinder-scheduler
# Required-Start: $network $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs
# Should-Start: postgresql mysql keystone rabbitmq-server ntp
# Should-Stop: postgresql mysql keystone rabbitmq-server ntp
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Cinder Scheduler
# Description: Provides EBS like storage for your
# virtual machine instances
### END INIT INFO
# Author: Julien Danjou <acid@debian.org>, Thomas Goirand <zigo@debian.org>
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OpenStack Cinder Scheduler"
PROJECT_NAME=cinder
NAME=${PROJECT_NAME}-scheduler
DAEMON={{ daemon_path }}

View File

@ -0,0 +1,22 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: cinder-volume
# Required-Start: $network $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs
# Should-Start: postgresql mysql keystone rabbitmq-server ntp
# Should-Stop: postgresql mysql keystone rabbitmq-server ntp
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Cinder Volume
# Description: Provides EBS like storage for your
# virtual machine instances
### END INIT INFO
# Author: Julien Danjou <acid@debian.org>
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OpenStack Cinder Volume"
PROJECT_NAME=cinder
NAME=${PROJECT_NAME}-volume
DAEMON={{ daemon_path }}

View File

@ -18,10 +18,18 @@ TO_PATCH = [
'relation_set',
'local_unit',
# helpers.core.host
'lsb_release',
'mounts',
'umount',
'mkdir',
'service_restart',
# helpers.core.templating
'render',
# helpers.contrib.openstack.utils
'git_generate_systemd_init_files',
'git_src_dir',
# helpers.contrib.python.packages
'pip_install',
# ceph utils
# storage_utils
'create_lvm_physical_volume',
@ -48,7 +56,7 @@ TO_PATCH = [
'service_stop',
'service_start',
# cinder
'ceph_config_file'
'ceph_config_file',
]
@ -723,27 +731,21 @@ class TestCinderUtils(CharmTestCase):
self.assertEquals(write_file.call_args_list, expected)
@patch.object(cinder_utils, 'services')
@patch.object(cinder_utils, 'git_src_dir')
@patch.object(cinder_utils, 'service_restart')
@patch.object(cinder_utils, 'render')
@patch.object(cinder_utils, 'pip_install')
@patch('os.path.join')
@patch('os.path.exists')
@patch('shutil.copytree')
@patch('shutil.rmtree')
@patch('pwd.getpwnam')
@patch('grp.getgrnam')
@patch('os.chown')
@patch('os.chmod')
@patch('os.symlink')
def test_git_post_install(self, symlink, chmod, chown, grp, pwd, rmtree,
copytree, exists, join, pip_install, render,
service_restart, git_src_dir, services):
def test_git_post_install_upstart(self, symlink, chmod, chown, rmtree,
copytree, exists, join, services):
services.return_value = ['svc1']
projects_yaml = openstack_origin_git
join.return_value = 'joined-string'
self.lsb_release.return_value = {'DISTRIB_RELEASE': '15.04'}
cinder_utils.git_post_install(projects_yaml)
pip_install('mysql-python', venv='joined-string')
self.pip_install('mysql-python', venv='joined-string')
expected = [
call('joined-string', '/etc/cinder'),
]
@ -821,9 +823,45 @@ class TestCinderUtils(CharmTestCase):
cinder_volume_context, perms=0o644,
templates_dir='joined-string'),
]
self.assertEquals(render.call_args_list, expected)
self.assertEquals(self.render.call_args_list, expected)
expected = [call('tgtd'), call('svc1')]
self.assertEquals(service_restart.call_args_list, expected)
self.assertEquals(self.service_restart.call_args_list, expected)
@patch.object(cinder_utils, 'services')
@patch('os.path.join')
@patch('shutil.copytree')
@patch('shutil.rmtree')
@patch('pwd.getpwnam')
@patch('grp.getgrnam')
@patch('os.chown')
@patch('os.chmod')
@patch('os.symlink')
def test_git_post_install_systemd(self, symlink, chmod, chown, grp, pwd,
rmtree, copytree, join, services):
projects_yaml = openstack_origin_git
join.return_value = 'joined-string'
self.lsb_release.return_value = {'DISTRIB_RELEASE': '15.10'}
cinder_utils.git_post_install(projects_yaml)
expected = [
call('cinder.conf', '/etc/cinder/cinder.conf', {},
group='cinder', owner='cinder', perms=420),
call('git/cinder_tgt.conf', '/etc/tgt/conf.d', {},
group='cinder', owner='cinder', perms=420),
call('git/logging.conf', '/etc/cinder/logging.conf', {},
group='cinder', owner='cinder', perms=420),
call('git/cinder_sudoers', '/etc/sudoers.d/cinder_sudoers', {},
group='root', owner='root', perms=288),
call('git/cinder-api.init.in.template', 'joined-string',
{'daemon_path': 'joined-string'}, perms=420),
call('git/cinder-backup.init.in.template', 'joined-string',
{'daemon_path': 'joined-string'}, perms=420),
call('git/cinder-scheduler.init.in.template', 'joined-string',
{'daemon_path': 'joined-string'}, perms=420),
call('git/cinder-volume.init.in.template', 'joined-string',
{'daemon_path': 'joined-string'}, perms=420),
]
self.assertEquals(self.render.call_args_list, expected)
@patch.object(cinder_utils, 'local_unit', lambda *args: 'unit/0')
def test_check_db_initialised_by_self(self):