Remove sysvinit/upstart support

Recent modern operating systems commonly use systemd. Octavia no longer
supports very old version of Ubuntu/CentOS/Debian which use sysvinit or
upstart so supporting only systemd should be enough.

The remaining usage of the service command is replaced by the ones with
the systemctl command.

Change-Id: Ifc3f85bf280527c0f76b2c0e0db2be813249dafa
This commit is contained in:
Takashi Kajinami 2024-05-30 15:02:29 +09:00
parent 85c12eb7eb
commit 991e0da01e
25 changed files with 208 additions and 1100 deletions

View File

@ -41,18 +41,10 @@ mkdir -p /var/lib/octavia
install -D -g root -o root -m 0644 ${SCRIPTDIR}/amphora-agent.logrotate /etc/logrotate.d/amphora-agent install -D -g root -o root -m 0644 ${SCRIPTDIR}/amphora-agent.logrotate /etc/logrotate.d/amphora-agent
case "$DIB_INIT_SYSTEM" in case "$DIB_INIT_SYSTEM" in
upstart)
install -D -g root -o root -m 0644 ${SCRIPTDIR}/amphora-agent.conf /etc/init/amphora-agent.conf
install -D -g root -o root -m 0644 ${SCRIPTDIR}/prometheus-proxy.conf /etc/init/prometheus-proxy.conf
;;
systemd) systemd)
install -D -g root -o root -m 0644 ${SCRIPTDIR}/amphora-agent.service /usr/lib/systemd/system/amphora-agent.service install -D -g root -o root -m 0644 ${SCRIPTDIR}/amphora-agent.service /usr/lib/systemd/system/amphora-agent.service
install -D -g root -o root -m 0644 ${SCRIPTDIR}/prometheus-proxy.service /usr/lib/systemd/system/prometheus-proxy.service install -D -g root -o root -m 0644 ${SCRIPTDIR}/prometheus-proxy.service /usr/lib/systemd/system/prometheus-proxy.service
;; ;;
sysv)
install -D -g root -o root -m 0644 ${SCRIPTDIR}/amphora-agent.init /etc/init.d/amphora-agent.init
install -D -g root -o root -m 0644 ${SCRIPTDIR}/prometheus-proxy.init /etc/init.d/prometheus-proxy.init
;;
*) *)
echo "Unsupported init system" echo "Unsupported init system"
exit 1 exit 1

View File

@ -1,39 +0,0 @@
### BEGIN INIT INFO
# Provides: certs-ramfs
# Required-Start: $remote_fs $syslog $network cloud-config
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Creates an encrypted ramfs for Octavia certs
# Description: Creates an encrypted ramfs for Octavia TLS
# certificates and key storage.
### END INIT INFO
# Using the lsb functions to perform the operations.
. /lib/lsb/init-functions
# Process name ( For display )
NAME=certs-ramfs
case $1 in
start)
log_daemon_msg "Starting the process" "$NAME"
/usr/local/bin/certfs-ramfs
log_end_msg 0
;;
stop)
log_daemon_msg "Stopping the process" "$NAME"
certs_path=$(awk "/base_cert_dir / {printf \$3}" /etc/octavia/amphora-agent.conf)
umount "${certs_path}"
cryptsetup luksClose /dev/mapper/certfs-ramfs
log_end_msg 0
;;
restart)
# Restart the daemon.
$0 stop && sleep 2 && $0 start
;;
*)
# For invalid arguments, print the usage message.
echo "Usage: $0 {start|stop|restart|reload|status}"
exit 2
;;
esac

View File

@ -1,14 +0,0 @@
description "Creates an encrypted ramfs for Octavia certs"
start on started cloud-config
stop on runlevel [!2345]
pre-start script
/usr/local/bin/certfs-ramfs
end script
post-stop script
certs_path=$(awk "/base_cert_dir / {printf \$3}" /etc/octavia/amphora-agent.conf)
umount "${certs_path}"
cryptsetup luksClose /dev/mapper/certfs-ramfs
end script

View File

@ -7,10 +7,6 @@ set -eu
set -o pipefail set -o pipefail
case "$DIB_INIT_SYSTEM" in case "$DIB_INIT_SYSTEM" in
upstart|sysv)
# nothing to do
exit 0
;;
systemd) systemd)
systemctl enable certs-ramfs.service systemctl enable certs-ramfs.service
;; ;;

View File

@ -52,8 +52,6 @@ class AgentJinjaTemplater:
'haproxy_cmd': CONF.haproxy_amphora.haproxy_cmd, 'haproxy_cmd': CONF.haproxy_amphora.haproxy_cmd,
'heartbeat_interval': CONF.health_manager.heartbeat_interval, 'heartbeat_interval': CONF.health_manager.heartbeat_interval,
'heartbeat_key': CONF.health_manager.heartbeat_key, 'heartbeat_key': CONF.health_manager.heartbeat_key,
'respawn_count': CONF.haproxy_amphora.respawn_count,
'respawn_interval': CONF.haproxy_amphora.respawn_interval,
'amphora_udp_driver': CONF.amphora_agent.amphora_udp_driver, 'amphora_udp_driver': CONF.amphora_agent.amphora_udp_driver,
'agent_tls_protocol': CONF.amphora_agent.agent_tls_protocol, 'agent_tls_protocol': CONF.amphora_agent.agent_tls_protocol,
'topology': topology, 'topology': topology,

View File

@ -34,8 +34,6 @@ LOG = logging.getLogger(__name__)
j2_env = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader( j2_env = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader(
os.path.dirname(os.path.realpath(__file__)) + consts.AGENT_API_TEMPLATES)) os.path.dirname(os.path.realpath(__file__)) + consts.AGENT_API_TEMPLATES))
UPSTART_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_UPSTART)
SYSVINIT_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_SYSVINIT)
SYSTEMD_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_SYSTEMD) SYSTEMD_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_SYSTEMD)
check_script_template = j2_env.get_template(consts.CHECK_SCRIPT_CONF) check_script_template = j2_env.get_template(consts.CHECK_SCRIPT_CONF)
@ -60,34 +58,17 @@ class Keepalived:
f.write(b) f.write(b)
b = stream.read(BUFFER) b = stream.read(BUFFER)
init_system = util.get_os_init_system() file_path = util.keepalived_init_path()
file_path = util.keepalived_init_path(init_system)
init_enable_cmd = None
if init_system == consts.INIT_SYSTEMD:
template = SYSTEMD_TEMPLATE template = SYSTEMD_TEMPLATE
init_enable_cmd = "systemctl enable octavia-keepalived"
# Render and install the network namespace systemd service # Render and install the network namespace systemd service
util.install_netns_systemd_service() util.install_netns_systemd_service()
util.run_systemctl_command( util.run_systemctl_command(
consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX) consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX, False)
elif init_system == consts.INIT_UPSTART:
template = UPSTART_TEMPLATE
elif init_system == consts.INIT_SYSVINIT:
template = SYSVINIT_TEMPLATE
init_enable_cmd = f"insserv {file_path}"
else:
raise util.UnknownInitError()
if init_system == consts.INIT_SYSTEMD:
# mode 00644 # mode 00644
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
else:
# mode 00755
mode = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH)
if not os.path.exists(file_path): if not os.path.exists(file_path):
with os.fdopen(os.open(file_path, flags, mode), 'w') as text_file: with os.fdopen(os.open(file_path, flags, mode), 'w') as text_file:
text = template.render( text = template.render(
@ -118,14 +99,10 @@ class Keepalived:
util.vrrp_check_script_update(None, consts.AMP_ACTION_START) util.vrrp_check_script_update(None, consts.AMP_ACTION_START)
# Make sure the new service is enabled on boot # Make sure the new service is enabled on boot
if init_enable_cmd is not None:
try: try:
subprocess.check_output(init_enable_cmd.split(), util.run_systemctl_command(consts.ENABLE,
stderr=subprocess.STDOUT, consts.KEEPALIVED_SYSTEMD)
encoding='utf-8')
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.debug('Failed to enable octavia-keepalived service: '
'%(err)s %(output)s', {'err': e, 'output': e.output})
return webob.Response(json={ return webob.Response(json={
'message': "Error enabling octavia-keepalived service", 'message': "Error enabling octavia-keepalived service",
'details': e.output}, status=500) 'details': e.output}, status=500)
@ -158,14 +135,10 @@ class Keepalived:
except OSError: except OSError:
pass pass
cmd = f"/usr/sbin/service octavia-keepalived {action}"
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, util.run_systemctl_command(action,
encoding='utf-8') consts.KEEPALIVED_SYSTEMD)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.debug('Failed to %s octavia-keepalived service: %s %s',
action, e, e.output)
return webob.Response(json={ return webob.Response(json={
'message': f"Failed to {action} octavia-keepalived service", 'message': f"Failed to {action} octavia-keepalived service",
'details': e.output}, status=500) 'details': e.output}, status=500)

View File

@ -38,8 +38,6 @@ LOG = logging.getLogger(__name__)
j2_env = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader( j2_env = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader(
os.path.dirname(os.path.realpath(__file__)) + consts.AGENT_API_TEMPLATES)) os.path.dirname(os.path.realpath(__file__)) + consts.AGENT_API_TEMPLATES))
UPSTART_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_UPSTART)
SYSVINIT_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_SYSVINIT)
SYSTEMD_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_SYSTEMD) SYSTEMD_TEMPLATE = j2_env.get_template(consts.KEEPALIVED_JINJA2_SYSTEMD)
check_script_file_template = j2_env.get_template( check_script_file_template = j2_env.get_template(
consts.KEEPALIVED_CHECK_SCRIPT) consts.KEEPALIVED_CHECK_SCRIPT)
@ -92,32 +90,18 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
f.write(b) f.write(b)
b = stream.read(BUFFER) b = stream.read(BUFFER)
init_system = util.get_os_init_system() file_path = util.keepalived_lvs_init_path(listener_id)
file_path = util.keepalived_lvs_init_path(init_system, listener_id)
if init_system == consts.INIT_SYSTEMD:
template = SYSTEMD_TEMPLATE template = SYSTEMD_TEMPLATE
# Render and install the network namespace systemd service # Render and install the network namespace systemd service
util.install_netns_systemd_service() util.install_netns_systemd_service()
util.run_systemctl_command( util.run_systemctl_command(
consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX) consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX, False)
elif init_system == consts.INIT_UPSTART:
template = UPSTART_TEMPLATE
elif init_system == consts.INIT_SYSVINIT:
template = SYSVINIT_TEMPLATE
else:
raise util.UnknownInitError()
# Render and install the keepalivedlvs init script # Render and install the keepalivedlvs init script
if init_system == consts.INIT_SYSTEMD:
# mode 00644 # mode 00644
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
else:
# mode 00755
mode = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH)
keepalived_pid, vrrp_pid, check_pid = util.keepalived_lvs_pids_path( keepalived_pid, vrrp_pid, check_pid = util.keepalived_lvs_pids_path(
listener_id) listener_id)
if not os.path.exists(file_path): if not os.path.exists(file_path):
@ -136,19 +120,11 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
text_file.write(text) text_file.write(text)
# Make sure the keepalivedlvs service is enabled on boot # Make sure the keepalivedlvs service is enabled on boot
if init_system == consts.INIT_SYSTEMD:
util.run_systemctl_command(
consts.ENABLE, f"octavia-keepalivedlvs-{str(listener_id)}")
elif init_system == consts.INIT_SYSVINIT:
init_enable_cmd = f"insserv {file_path}"
try: try:
subprocess.check_output(init_enable_cmd.split(), util.run_systemctl_command(
stderr=subprocess.STDOUT, consts.ENABLE,
encoding='utf-8') consts.KEEPALIVEDLVS_SYSTEMD % listener_id)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.debug('Failed to enable '
'octavia-keepalivedlvs service: '
'%(err)s', {'err': str(e)})
return webob.Response(json={ return webob.Response(json={
'message': ("Error enabling " 'message': ("Error enabling "
"octavia-keepalivedlvs service"), "octavia-keepalivedlvs service"),
@ -166,7 +142,6 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
'w') as script_file: 'w') as script_file:
text = check_script_file_template.render( text = check_script_file_template.render(
consts=consts, consts=consts,
init_system=init_system,
keepalived_lvs_pid_dir=util.keepalived_lvs_dir() keepalived_lvs_pid_dir=util.keepalived_lvs_dir()
) )
script_file.write(text) script_file.write(text)
@ -217,15 +192,10 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
if consts.OFFLINE == self._check_lvs_listener_status(listener_id): if consts.OFFLINE == self._check_lvs_listener_status(listener_id):
action = consts.AMP_ACTION_START action = consts.AMP_ACTION_START
cmd = ("/usr/sbin/service "
f"octavia-keepalivedlvs-{listener_id} {action}")
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, util.run_systemctl_command(
encoding='utf-8') action, consts.KEEPALIVEDLVS_SYSTEMD % listener_id)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.debug('Failed to %s keepalivedlvs listener %s',
listener_id + ' : ' + action, e)
return webob.Response(json={ return webob.Response(json={
'message': (f"Failed to {action} keepalivedlvs listener " 'message': (f"Failed to {action} keepalivedlvs listener "
f"{listener_id}"), f"{listener_id}"),
@ -280,11 +250,10 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
if os.path.exists(keepalived_pid) and os.path.exists( if os.path.exists(keepalived_pid) and os.path.exists(
os.path.join('/proc', os.path.join('/proc',
util.get_keepalivedlvs_pid(listener_id))): util.get_keepalivedlvs_pid(listener_id))):
cmd = (f"/usr/sbin/service "
f"octavia-keepalivedlvs-{listener_id} stop")
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, util.run_systemctl_command(
encoding='utf-8') consts.STOP,
consts.KEEPALIVEDLVS_SYSTEMD % listener_id)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.error("Failed to stop keepalivedlvs service: %s", e) LOG.error("Failed to stop keepalivedlvs service: %s", e)
return webob.Response(json={ return webob.Response(json={
@ -301,19 +270,12 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
os.remove(pid) os.remove(pid)
# disable the service # disable the service
init_system = util.get_os_init_system() init_path = util.keepalived_lvs_init_path(listener_id)
init_path = util.keepalived_lvs_init_path(init_system, listener_id)
if init_system == consts.INIT_SYSTEMD:
util.run_systemctl_command(
consts.DISABLE, f"octavia-keepalivedlvs-{listener_id}")
elif init_system == consts.INIT_SYSVINIT:
init_disable_cmd = f"insserv -r {init_path}"
try: try:
subprocess.check_output(init_disable_cmd.split(), util.run_systemctl_command(
stderr=subprocess.STDOUT, consts.DISABLE,
encoding='utf-8') consts.KEEPALIVEDLVS_SYSTEMD % listener_id)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.error("Failed to disable " LOG.error("Failed to disable "
"octavia-keepalivedlvs-%(list)s service: " "octavia-keepalivedlvs-%(list)s service: "
@ -321,12 +283,9 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase):
return webob.Response(json={ return webob.Response(json={
'message': ( 'message': (
f"Error disabling octavia-keepalivedlvs-{listener_id} " f"Error disabling octavia-keepalivedlvs-{listener_id} "
f"service"), "service"),
'details': e.output}, status=500) 'details': e.output}, status=500)
elif init_system != consts.INIT_UPSTART:
raise util.UnknownInitError()
# delete init script ,config file and log file for that listener # delete init script ,config file and log file for that listener
if os.path.exists(init_path): if os.path.exists(init_path):
os.remove(init_path) os.remove(init_path)

View File

@ -41,8 +41,6 @@ HAPROXY_QUERY_RETRIES = 5
CONF = cfg.CONF CONF = cfg.CONF
UPSTART_CONF = 'upstart.conf.j2'
SYSVINIT_CONF = 'sysvinit.conf.j2'
SYSTEMD_CONF = 'systemd.conf.j2' SYSTEMD_CONF = 'systemd.conf.j2'
JINJA_ENV = jinja2.Environment( JINJA_ENV = jinja2.Environment(
@ -50,8 +48,6 @@ JINJA_ENV = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname( loader=jinja2.FileSystemLoader(os.path.dirname(
os.path.realpath(__file__) os.path.realpath(__file__)
) + consts.AGENT_API_TEMPLATES)) ) + consts.AGENT_API_TEMPLATES))
UPSTART_TEMPLATE = JINJA_ENV.get_template(UPSTART_CONF)
SYSVINIT_TEMPLATE = JINJA_ENV.get_template(SYSVINIT_CONF)
SYSTEMD_TEMPLATE = JINJA_ENV.get_template(SYSTEMD_CONF) SYSTEMD_TEMPLATE = JINJA_ENV.get_template(SYSTEMD_CONF)
@ -146,43 +142,16 @@ class Loadbalancer:
# file ok - move it # file ok - move it
os.rename(name, util.config_path(lb_id)) os.rename(name, util.config_path(lb_id))
try: init_path = util.init_path(lb_id)
init_system = util.get_os_init_system()
LOG.debug('Found init system: %s', init_system)
init_path = util.init_path(lb_id, init_system)
if init_system == consts.INIT_SYSTEMD:
template = SYSTEMD_TEMPLATE template = SYSTEMD_TEMPLATE
# Render and install the network namespace systemd service # Render and install the network namespace systemd service
util.install_netns_systemd_service() util.install_netns_systemd_service()
util.run_systemctl_command( util.run_systemctl_command(
consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX + '.service') consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX + '.service', False)
elif init_system == consts.INIT_UPSTART:
template = UPSTART_TEMPLATE
elif init_system == consts.INIT_SYSVINIT:
template = SYSVINIT_TEMPLATE
init_enable_cmd = f"insserv {init_path}"
else:
raise util.UnknownInitError()
except util.UnknownInitError:
LOG.error("Unknown init system found.")
return webob.Response(json={
'message': "Unknown init system in amphora",
'details': "The amphora image is running an unknown init "
"system. We can't create the init configuration "
"file for the load balancing process."}, status=500)
if init_system == consts.INIT_SYSTEMD:
# mode 00644 # mode 00644
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
else:
# mode 00755
mode = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH)
hap_major, hap_minor = haproxy_compatibility.get_haproxy_versions() hap_major, hap_minor = haproxy_compatibility.get_haproxy_versions()
if not os.path.exists(init_path): if not os.path.exists(init_path):
@ -196,9 +165,6 @@ class Loadbalancer:
haproxy_state_file=util.state_file_path(lb_id), haproxy_state_file=util.state_file_path(lb_id),
haproxy_socket=util.haproxy_sock_path(lb_id), haproxy_socket=util.haproxy_sock_path(lb_id),
haproxy_user_group_cfg=consts.HAPROXY_USER_GROUP_CFG, haproxy_user_group_cfg=consts.HAPROXY_USER_GROUP_CFG,
respawn_count=util.CONF.haproxy_amphora.respawn_count,
respawn_interval=(util.CONF.haproxy_amphora.
respawn_interval),
amphora_netns=consts.AMP_NETNS_SVC_PREFIX, amphora_netns=consts.AMP_NETNS_SVC_PREFIX,
amphora_nsname=consts.AMPHORA_NAMESPACE, amphora_nsname=consts.AMPHORA_NAMESPACE,
haproxy_major_version=hap_major, haproxy_major_version=hap_major,
@ -207,21 +173,13 @@ class Loadbalancer:
text_file.write(text) text_file.write(text)
# Make sure the new service is enabled on boot # Make sure the new service is enabled on boot
if init_system == consts.INIT_SYSTEMD:
util.run_systemctl_command(
consts.ENABLE, f"haproxy-{lb_id}")
elif init_system == consts.INIT_SYSVINIT:
try: try:
subprocess.check_output(init_enable_cmd.split(), util.run_systemctl_command(
stderr=subprocess.STDOUT, consts.ENABLE, consts.LOADBALANCER_SYSTEMD % lb_id)
encoding='utf-8')
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.error("Failed to enable haproxy-%(lb_id)s service: "
"%(err)s %(out)s", {'lb_id': lb_id, 'err': e,
'out': e.output})
return webob.Response(json={ return webob.Response(json={
'message': "Error enabling haproxy-{} service".format( 'message': "Error enabling octavia-keepalived service",
lb_id), 'details': e.output}, status=500) 'details': e.output}, status=500)
res = webob.Response(json={'message': 'OK'}, status=202) res = webob.Response(json={'message': 'OK'}, status=202)
res.headers['ETag'] = stream.get_md5() res.headers['ETag'] = stream.get_md5()
@ -283,11 +241,9 @@ class Loadbalancer:
else 1) else 1)
saved_exc = None saved_exc = None
for idx in range(retries): for idx in range(retries):
cmd = f"/usr/sbin/service haproxy-{lb_id} {action}"
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, util.run_systemctl_command(
encoding='utf-8') action, consts.LOADBALANCER_SYSTEMD % lb_id)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
# Mitigation for # Mitigation for
# https://bugs.launchpad.net/octavia/+bug/2054666 # https://bugs.launchpad.net/octavia/+bug/2054666
@ -296,11 +252,6 @@ class Loadbalancer:
saved_exc = e saved_exc = e
LOG.debug(
"Failed to %(action)s haproxy-%(lb_id)s service: "
"%(err)s %(out)s", {'action': action, 'lb_id': lb_id,
'err': e, 'out': e.output})
# Wait a few seconds and check that haproxy was restarted # Wait a few seconds and check that haproxy was restarted
uptime = self._check_haproxy_uptime(lb_id) uptime = self._check_haproxy_uptime(lb_id)
# If haproxy is not reachable or was restarted more than 15 # If haproxy is not reachable or was restarted more than 15
@ -314,10 +265,6 @@ class Loadbalancer:
"more details.") "more details.")
break break
if 'Job is already running' not in e.output: if 'Job is already running' not in e.output:
LOG.debug(
"Failed to %(action)s haproxy-%(lb_id)s service: "
"%(err)s %(out)s", {'action': action, 'lb_id': lb_id,
'err': e, 'out': e.output})
return webob.Response(json={ return webob.Response(json={
'message': f"Error {action}ing haproxy", 'message': f"Error {action}ing haproxy",
'details': e.output 'details': e.output
@ -358,10 +305,9 @@ class Loadbalancer:
# check if that haproxy is still running and if stop it # check if that haproxy is still running and if stop it
if os.path.exists(util.pid_path(lb_id)) and os.path.exists( if os.path.exists(util.pid_path(lb_id)) and os.path.exists(
os.path.join('/proc', util.get_haproxy_pid(lb_id))): os.path.join('/proc', util.get_haproxy_pid(lb_id))):
cmd = f"/usr/sbin/service haproxy-{lb_id} stop"
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, util.run_systemctl_command(
encoding='utf-8') consts.STOP, consts.LOADBALANCER_SYSTEMD % lb_id)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.error("Failed to stop haproxy-%s service: %s %s", LOG.error("Failed to stop haproxy-%s service: %s %s",
lb_id, e, e.output) lb_id, e, e.output)
@ -390,28 +336,10 @@ class Loadbalancer:
pass pass
# disable the service # disable the service
init_system = util.get_os_init_system() init_path = util.init_path(lb_id)
init_path = util.init_path(lb_id, init_system)
if init_system == consts.INIT_SYSTEMD:
util.run_systemctl_command( util.run_systemctl_command(
consts.DISABLE, f"haproxy-{lb_id}") consts.DISABLE, consts.LOADBALANCER_SYSTEMD % lb_id, False)
elif init_system == consts.INIT_SYSVINIT:
init_disable_cmd = f"insserv -r {init_path}"
try:
subprocess.check_output(init_disable_cmd.split(),
stderr=subprocess.STDOUT,
encoding='utf-8')
except subprocess.CalledProcessError as e:
LOG.error("Failed to disable haproxy-%(lb_id)s service: "
"%(err)s %(out)s", {'lb_id': lb_id, 'err': e,
'out': e.output})
return webob.Response(json={
'message': "Error disabling haproxy-{} service".format(
lb_id), 'details': e.output}, status=500)
elif init_system != consts.INIT_UPSTART:
raise util.UnknownInitError()
# delete the directory + init script for that listener # delete the directory + init script for that listener
shutil.rmtree(util.haproxy_dir(lb_id)) shutil.rmtree(util.haproxy_dir(lb_id))

View File

@ -1,87 +0,0 @@
#!/bin/sh
#
# keepalived LVS cluster monitor daemon.
#
# Written by Andres Salomon <dilinger@voxel.net>
#
### BEGIN INIT INFO
# Provides: keepalived
# Required-Start: $syslog $network $remote_fs
# Required-Stop: $syslog $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts keepalived
# Description: Starts keepalived lvs loadbalancer
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON="ip netns exec {{ amphora_nsname }} {{ keepalived_cmd }}"
NAME=octavia-keepalived
DESC=octavia-keepalived
TMPFILES="/tmp/.vrrp /tmp/.healthcheckers"
{% if vrrp_pid and check_pid %}
DAEMON_ARGS="--log-facility={{ administrative_log_facility }} -f {{ keepalived_cfg }} -p {{ keepalived_pid }} -r {{ vrrp_pid }} -c {{ check_pid }}"
{% else %}
DAEMON_ARGS="-log-facility={{ administrative_log_facility }} -f {{ keepalived_cfg }} -p {{ keepalived_pid }}"
{% endif %}
#includes lsb functions
. /lib/lsb/init-functions
test -f $DAEMON || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
for file in $TMPFILES
do
test -e $file && test ! -L $file && rm $file
done
if start-stop-daemon --start --quiet --pidfile {{ keepalived_pid }} \
--exec $DAEMON -- $DAEMON_ARGS; then
log_end_msg 0
else
log_end_msg 1
fi
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
if start-stop-daemon --oknodo --stop --quiet --pidfile {{ keepalived_pid }} \
--exec $DAEMON; then
log_end_msg 0
else
log_end_msg 1
fi
;;
reload|force-reload)
log_action_begin_msg "Reloading $DESC configuration..."
if start-stop-daemon --stop --quiet --signal 1 --pidfile \
{{ keepalived_pid }} --exec $DAEMON; then
log_end_msg 0
else
log_action_end_msg 1
fi
;;
restart)
log_action_begin_msg "Restarting $DESC" "$NAME"
start-stop-daemon --stop --quiet --pidfile \
{{ keepalived_pid }} --exec $DAEMON || true
sleep 1
if start-stop-daemon --start --quiet --pidfile \
{{ keepalived_pid }} --exec $DAEMON -- $DAEMON_ARGS; then
log_end_msg 0
else
log_end_msg 1
fi
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart|reload|force-reload}" >&2
exit 1
;;
esac
exit 0

View File

@ -1,29 +0,0 @@
{#
# Copyright 2015 Hewlett-Packard Development Company, L.P.
# Copyright 2016 Rackspace
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
#}
description "Octavia keepalived"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
{% if vrrp_pid and check_pid %}
exec /sbin/ip netns exec {{ amphora_nsname }} {{ keepalived_cmd }} -n --log-facility={{ administrative_log_facility }} -f {{ keepalived_cfg }} -p {{ keepalived_pid }} -r {{ vrrp_pid }} -c {{ check_pid }}
{% else %}
exec /sbin/ip netns exec {{ amphora_nsname }} {{ keepalived_cmd }} -n --log-facility={{ administrative_log_facility }} -f {{ keepalived_cfg }} -p {{ keepalived_pid }}
{% endif %}

View File

@ -11,11 +11,7 @@ do
pid) echo "Check keepalived pid file: " $file;; pid) echo "Check keepalived pid file: " $file;;
*) continue;; *) continue;;
esac esac
{% if init_system == consts.INIT_SYSTEMD %}
systemctl status $(basename $file .pid) > /dev/null systemctl status $(basename $file .pid) > /dev/null
{% elif init_system in (consts.INIT_UPSTART, consts.INIT_SYSVINIT) %}
kill -0 `cat $file`
{% endif %}
status=$(( $status + $? )) status=$(( $status + $? ))
done done
exit $status exit $status

View File

@ -1,232 +0,0 @@
#!/bin/sh
{#-
# Copyright 2015 Rackspace.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# Inspired by https://gist.github.com/gfrey/8472007
#}
### BEGIN INIT INFO
# Provides: octavia-amp-{{ haproxy_pid }}
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: fast and reliable load balancing reverse proxy
# Description: This file should be used to start and stop haproxy.
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
PIDFILE={{ haproxy_pid }}
CONFIG={{ haproxy_cfg }}
PEER_NAME={{ peer_name }}
HAPROXY={{ haproxy_cmd }}
USER_GROUP_CONF_PATH={{ haproxy_user_group_cfg }}
EXTRAOPTS=
ENABLED=1
test -x $HAPROXY || exit 0
test -f "$CONFIG" -f "$USER_GROUP_CONF_PATH" || exit 0
if [ -e /etc/default/haproxy ]; then
. /etc/default/haproxy
fi
test "$ENABLED" != "0" || exit 0
[ -f /etc/default/rcS ] && . /etc/default/rcS
. /lib/lsb/init-functions
HAPROXY="ip netns exec {{ amphora_nsname }} $HAPROXY"
haproxy_start()
{
# Re-add the namespace
ip netns add {{ amphora_nsname }} || true
# Load the system sysctl into the new namespace
ip netns exec {{ amphora_nsname }} sysctl --system || true
# We need the plugged_interfaces file sorted to join the host interfaces
sort -k 1 /var/lib/octavia/plugged_interfaces > /var/lib/octavia/plugged_interfaces.sorted || true
# Assign the interfaces into the namespace with the appropriate name
ip link | awk '{getline n; print $0,n}' | awk '{sub(":","",$2)} { for(i=1;i<=NF;i++) if ($i == "link/ether") {print $(i+1) " " $2} }' | sort -k 1 | join -j 1 - /var/lib/octavia/plugged_interfaces.sorted | awk '{system("ip link set "$2" netns {{ amphora_nsname }} name "$3"")}' || true
# Bring up all of the namespace interfaces
ip netns exec {{ amphora_nsname }} amphora-interface up all || true
start-stop-daemon --start --pidfile "$PIDFILE" \
--exec $HAPROXY -- -f "$CONFIG" -f "$USER_GROUP_CONF_PATH" -L "$PEER_NAME" -D -p "$PIDFILE" \
$EXTRAOPTS || return 2
return 0
}
haproxy_stop()
{
if [ ! -f $PIDFILE ] ; then
# This is a success according to LSB
return 0
fi
for pid in $(cat $PIDFILE) ; do
/bin/kill $pid || return 4
done
rm -f $PIDFILE
return 0
}
haproxy_reload()
{
$HAPROXY -f "$CONFIG" -f "$USER_GROUP_CONF_PATH" -L "$PEER_NAME" -p $PIDFILE -D $EXTRAOPTS -sf $(cat $PIDFILE) \
|| return 2
return 0
}
haproxy_checkconf()
{
rcode=0
$HAPROXY -c -f "$CONFIG" -f "$USER_GROUP_CONF_PATH" -L "$PEER_NAME"
if [ $? -ne 0 ]; then
rcode=1
fi
return $rcode
}
haproxy_status()
{
if [ ! -f $PIDFILE ] ; then
# program not running
return 3
fi
for pid in $(cat $PIDFILE) ; do
if ! ps --no-headers p "$pid" | grep haproxy > /dev/null ; then
# program running, bogus pidfile
return 1
fi
done
return 0
}
case "$1" in
checkconf)
haproxy_checkconf
exit $?
;;
start)
log_daemon_msg "Starting haproxy" "haproxy"
haproxy_start
ret=$?
case "$ret" in
0)
log_end_msg 0
;;
1)
log_end_msg 1
echo "pid file '$PIDFILE' found, haproxy not started."
;;
2)
log_end_msg 1
;;
esac
exit $ret
;;
stop)
log_daemon_msg "Stopping haproxy" "haproxy"
haproxy_stop
ret=$?
case "$ret" in
0|1)
log_end_msg 0
;;
2)
log_end_msg 1
;;
esac
exit $ret
;;
reload|force-reload)
echo "Checking HAProxy configuration first"
haproxy_checkconf
case "$?" in
0)
echo "Everything looks fine"
;;
1)
echo "Errors..."
exit 1
;;
esac
log_daemon_msg "Reloading haproxy" "haproxy"
haproxy_reload
case "$?" in
0|1)
log_end_msg 0
;;
2)
log_end_msg 1
;;
esac
;;
restart)
echo "Checking HAProxy configuration first"
haproxy_checkconf
case "$?" in
0)
echo "Everything looks fine"
;;
1)
echo "Errors..."
exit 1
;;
esac
log_daemon_msg "Restarting haproxy" "haproxy"
haproxy_stop
haproxy_start
case "$?" in
0)
log_end_msg 0
;;
1)
log_end_msg 1
;;
2)
log_end_msg 1
;;
esac
;;
status)
haproxy_status
ret=$?
case "$ret" in
0)
echo "haproxy is running."
;;
1)
echo "haproxy dead, but $PIDFILE exists."
;;
*)
echo "haproxy not running."
;;
esac
exit $ret
;;
*)
echo "Usage: /etc/init.d/haproxy {start|stop|reload|restart|status|checkconf}"
exit 2
;;
esac
:

View File

@ -1,71 +0,0 @@
{#
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# Inspired by https://gist.github.com/gfrey/8472007
#}
description "Properly handle haproxy"
start on runlevel [2345]
stop on runlevel [!2345]
env PID_PATH={{ haproxy_pid }}
env BIN_PATH={{ haproxy_cmd }}
env CONF_PATH={{ haproxy_cfg }}
env USER_GROUP_CONF_PATH={{ haproxy_user_group_cfg }}
env PEER_NAME={{ peer_name }}
respawn
respawn limit {{ respawn_count }} {{respawn_interval}}
pre-start script
[ -r $CONF_PATH ]
# Re-add the namespace
ip netns add {{ amphora_nsname }} || true
# Load the system sysctl into the new namespace
ip netns exec {{ amphora_nsname }} sysctl --system || true
# We need the plugged_interfaces file sorted to join with the host
# interfaces
sort -k 1 /var/lib/octavia/plugged_interfaces > /var/lib/octavia/plugged_interfaces.sorted || true
# Assign the interfaces into the namespace with the appropriate name
ip link | awk '{getline n; print $0,n}' | awk '{sub(":","",$2)} { for(i=1;i<=NF;i++) if ($i == "link/ether") {print $(i+1) " " $2} }' | sort -k 1 | join -j 1 - /var/lib/octavia/plugged_interfaces.sorted | awk '{system("ip link set "$2" netns {{ amphora_nsname }} name "$3"")}' || true
# Bring up all of the namespace interfaces
ip netns exec {{ amphora_nsname }} amphora-interface up all || true
end script
script
exec /bin/bash <<EOF
echo \$(date) Starting HAProxy
# The -L trick fixes the HAProxy limitation to have long peer names
ip netns exec {{ amphora_nsname }} $BIN_PATH -f $CONF_PATH -f $USER_GROUP_CONF_PATH -L $PEER_NAME -D -p $PID_PATH
trap "ip netns exec {{ amphora_nsname }} $BIN_PATH -f $CONF_PATH -f $USER_GROUP_CONF_PATH -L $PEER_NAME -p $PID_PATH -sf \\\$(cat $PID_PATH)" SIGHUP
trap "kill -TERM \\\$(cat $PID_PATH) && rm $PID_PATH;echo \\\$(date) Exiting HAProxy; exit 0" SIGTERM SIGINT
while true; do # Iterate to keep job running.
# Check if HAProxy has failed and re-spawn
kill -0 \$(cat $PID_PATH)
if [ \$? -ne 0 ]; then
echo \$(date) HAProxy failed. Respawning
exit 1
fi
sleep 1 # Don't sleep to long as signals will not be handled during sleep.
done
EOF
end script

View File

@ -41,41 +41,18 @@ class ParsingError(Exception):
pass pass
class UnknownInitError(Exception): def init_path(lb_id):
pass return os.path.join(consts.SYSTEMD_DIR, f'haproxy-{lb_id}.service')
def init_path(lb_id, init_system):
if init_system == consts.INIT_SYSTEMD:
return os.path.join(consts.SYSTEMD_DIR,
f'haproxy-{lb_id}.service')
if init_system == consts.INIT_UPSTART:
return os.path.join(consts.UPSTART_DIR,
f'haproxy-{lb_id}.conf')
if init_system == consts.INIT_SYSVINIT:
return os.path.join(consts.SYSVINIT_DIR,
f'haproxy-{lb_id}')
raise UnknownInitError()
def keepalived_lvs_dir(): def keepalived_lvs_dir():
return os.path.join(CONF.haproxy_amphora.base_path, 'lvs') return os.path.join(CONF.haproxy_amphora.base_path, 'lvs')
def keepalived_lvs_init_path(init_system, listener_id): def keepalived_lvs_init_path(listener_id):
if init_system == consts.INIT_SYSTEMD:
return os.path.join(consts.SYSTEMD_DIR, return os.path.join(consts.SYSTEMD_DIR,
consts.KEEPALIVED_SYSTEMD_PREFIX % consts.KEEPALIVEDLVS_SYSTEMD %
str(listener_id)) str(listener_id))
if init_system == consts.INIT_UPSTART:
return os.path.join(consts.UPSTART_DIR,
consts.KEEPALIVED_UPSTART_PREFIX %
str(listener_id))
if init_system == consts.INIT_SYSVINIT:
return os.path.join(consts.SYSVINIT_DIR,
consts.KEEPALIVED_SYSVINIT_PREFIX %
str(listener_id))
raise UnknownInitError()
def keepalived_backend_check_script_dir(): def keepalived_backend_check_script_dir():
@ -142,14 +119,8 @@ def keepalived_dir():
return os.path.join(CONF.haproxy_amphora.base_path, 'vrrp') return os.path.join(CONF.haproxy_amphora.base_path, 'vrrp')
def keepalived_init_path(init_system): def keepalived_init_path():
if init_system == consts.INIT_SYSTEMD:
return os.path.join(consts.SYSTEMD_DIR, consts.KEEPALIVED_SYSTEMD) return os.path.join(consts.SYSTEMD_DIR, consts.KEEPALIVED_SYSTEMD)
if init_system == consts.INIT_UPSTART:
return os.path.join(consts.UPSTART_DIR, consts.KEEPALIVED_UPSTART)
if init_system == consts.INIT_SYSVINIT:
return os.path.join(consts.SYSVINIT_DIR, consts.KEEPALIVED_SYSVINIT)
raise UnknownInitError()
def keepalived_pid_path(): def keepalived_pid_path():
@ -225,23 +196,6 @@ def is_lvs_listener_running(listener_id):
os.path.join('/proc', get_keepalivedlvs_pid(listener_id))) os.path.join('/proc', get_keepalivedlvs_pid(listener_id)))
def get_os_init_system():
if os.path.exists(consts.INIT_PROC_COMM_PATH):
with open(consts.INIT_PROC_COMM_PATH, encoding='utf-8') as init_comm:
init_proc_name = init_comm.read().rstrip('\n')
if init_proc_name == consts.INIT_SYSTEMD:
return consts.INIT_SYSTEMD
if init_proc_name == 'init':
init_path = consts.INIT_PATH
if os.path.exists(init_path):
args = [init_path, '--version']
init_version = subprocess.check_output(args, shell=False)
if consts.INIT_UPSTART in str(init_version, 'utf-8'):
return consts.INIT_UPSTART
return consts.INIT_SYSVINIT
return consts.INIT_UNKOWN
def install_netns_systemd_service(): def install_netns_systemd_service():
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
# mode 00644 # mode 00644
@ -265,15 +219,17 @@ def install_netns_systemd_service():
text_file.write(text) text_file.write(text)
def run_systemctl_command(command, service): def run_systemctl_command(command, service, raise_error=True):
cmd = f"systemctl {command} {service}" cmd = f"systemctl {command} {service}"
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.error("Failed to %(cmd)s %(srvc)s service: " LOG.debug("Failed to %(cmd)s %(srvc)s service: "
"%(err)s %(out)s", {'cmd': command, 'srvc': service, "%(err)s %(out)s", {'cmd': command, 'srvc': service,
'err': e, 'out': e.output}) 'err': e, 'out': e.output})
if raise_error:
raise
def get_backend_for_lb_object(object_id): def get_backend_for_lb_object(object_id):

View File

@ -23,8 +23,6 @@ base_path = {{ base_path }}
bind_host = {{ bind_host }} bind_host = {{ bind_host }}
bind_port = {{ bind_port }} bind_port = {{ bind_port }}
haproxy_cmd = {{ haproxy_cmd }} haproxy_cmd = {{ haproxy_cmd }}
respawn_count = {{ respawn_count }}
respawn_interval = {{ respawn_interval }}
user_log_facility = {{ user_log_facility }} user_log_facility = {{ user_log_facility }}
administrative_log_facility = {{ administrative_log_facility }} administrative_log_facility = {{ administrative_log_facility }}

View File

@ -381,8 +381,14 @@ haproxy_amphora_opts = [
cfg.StrOpt('haproxy_cmd', default='/usr/sbin/haproxy', cfg.StrOpt('haproxy_cmd', default='/usr/sbin/haproxy',
help=_("The full path to haproxy")), help=_("The full path to haproxy")),
cfg.IntOpt('respawn_count', default=2, cfg.IntOpt('respawn_count', default=2,
deprecated_for_removal=True,
deprecated_reason='upstart support has been removed and this '
'option is no longer used.',
help=_("The respawn count for haproxy's upstart script")), help=_("The respawn count for haproxy's upstart script")),
cfg.IntOpt('respawn_interval', default=2, cfg.IntOpt('respawn_interval', default=2,
deprecated_for_removal=True,
deprecated_reason='upstart support has been removed and this '
'option is no longer used.',
help=_("The respawn interval for haproxy's upstart script")), help=_("The respawn interval for haproxy's upstart script")),
cfg.FloatOpt('rest_request_conn_timeout', default=10, cfg.FloatOpt('rest_request_conn_timeout', default=10,
help=_("The time in seconds to wait for a REST API " help=_("The time in seconds to wait for a REST API "

View File

@ -694,9 +694,7 @@ MIN_QUOTA = QUOTA_UNLIMITED
MAX_QUOTA = 2000000000 MAX_QUOTA = 2000000000
HAPROXY_BASE_PEER_PORT = 1025 HAPROXY_BASE_PEER_PORT = 1025
KEEPALIVED_JINJA2_UPSTART = 'keepalived.upstart.j2'
KEEPALIVED_JINJA2_SYSTEMD = 'keepalived.systemd.j2' KEEPALIVED_JINJA2_SYSTEMD = 'keepalived.systemd.j2'
KEEPALIVED_JINJA2_SYSVINIT = 'keepalived.sysvinit.j2'
CHECK_SCRIPT_CONF = 'keepalived_check_script.conf.j2' CHECK_SCRIPT_CONF = 'keepalived_check_script.conf.j2'
KEEPALIVED_CHECK_SCRIPT = 'keepalived_lvs_check_script.sh.j2' KEEPALIVED_CHECK_SCRIPT = 'keepalived_lvs_check_script.sh.j2'
@ -722,26 +720,17 @@ AMP_ACTION_RELOAD = 'reload'
AMP_ACTION_RESTART = 'restart' AMP_ACTION_RESTART = 'restart'
GLANCE_IMAGE_ACTIVE = 'active' GLANCE_IMAGE_ACTIVE = 'active'
INIT_SYSTEMD = 'systemd'
INIT_UPSTART = 'upstart'
INIT_SYSVINIT = 'sysvinit'
INIT_UNKOWN = 'unknown'
VALID_INIT_SYSTEMS = (INIT_SYSTEMD, INIT_SYSVINIT, INIT_UPSTART)
INIT_PATH = '/sbin/init' INIT_PATH = '/sbin/init'
SYSTEMD_DIR = '/usr/lib/systemd/system' SYSTEMD_DIR = '/usr/lib/systemd/system'
SYSVINIT_DIR = '/etc/init.d'
UPSTART_DIR = '/etc/init'
INIT_PROC_COMM_PATH = '/proc/1/comm' INIT_PROC_COMM_PATH = '/proc/1/comm'
KEEPALIVED_SYSTEMD = 'octavia-keepalived.service' LOADBALANCER_SYSTEMD = 'haproxy-%s.service'
KEEPALIVED_SYSVINIT = 'octavia-keepalived'
KEEPALIVED_UPSTART = 'octavia-keepalived.conf'
KEEPALIVED_SYSTEMD_PREFIX = 'octavia-keepalivedlvs-%s.service' KEEPALIVED_SYSTEMD = 'octavia-keepalived.service'
KEEPALIVED_SYSVINIT_PREFIX = 'octavia-keepalivedlvs-%s'
KEEPALIVED_UPSTART_PREFIX = 'octavia-keepalivedlvs-%s.conf' KEEPALIVEDLVS_SYSTEMD = 'octavia-keepalivedlvs-%s.service'
# Authentication # Authentication
KEYSTONE = 'keystone' KEYSTONE = 'keystone'
@ -821,6 +810,10 @@ AMPHORAV2 = 'amphorav2'
# systemctl commands # systemctl commands
DISABLE = 'disable' DISABLE = 'disable'
ENABLE = 'enable' ENABLE = 'enable'
STOP = 'stop'
START = 'start'
RESTART = 'restart'
RELOAD = 'reload'
# systemd amphora netns service prefix # systemd amphora netns service prefix
AMP_NETNS_SVC_PREFIX = 'amphora-netns' AMP_NETNS_SVC_PREFIX = 'amphora-netns'

View File

@ -116,8 +116,6 @@ class KeepalivedLvsTestCase(base.TestCase):
'install_netns_systemd_service') 'install_netns_systemd_service')
@mock.patch('pyroute2.NetNS', create=True) @mock.patch('pyroute2.NetNS', create=True)
@mock.patch('shutil.copy2') @mock.patch('shutil.copy2')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSTEMD)
@mock.patch('os.chmod') @mock.patch('os.chmod')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
@mock.patch('os.makedirs') @mock.patch('os.makedirs')
@ -125,8 +123,7 @@ class KeepalivedLvsTestCase(base.TestCase):
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
def test_upload_lvs_listener_config_no_vrrp_check_dir( def test_upload_lvs_listener_config_no_vrrp_check_dir(
self, m_check_output, m_os_rm, m_os_mkdir, m_exists, m_os_chmod, self, m_check_output, m_os_rm, m_os_mkdir, m_exists, m_os_chmod,
m_os_sysinit, m_copy2, mock_netns, mock_install_netns, m_copy2, mock_netns, mock_install_netns, mock_systemctl):
mock_systemctl):
m_exists.side_effect = [False, False, True, True, False, False] m_exists.side_effect = [False, False, True, True, False, False]
cfg_path = util.keepalived_lvs_cfg_path(self.FAKE_ID) cfg_path = util.keepalived_lvs_cfg_path(self.FAKE_ID)
m = self.useFixture(test_utils.OpenFixture(cfg_path)).mock_open m = self.useFixture(test_utils.OpenFixture(cfg_path)).mock_open
@ -143,9 +140,10 @@ class KeepalivedLvsTestCase(base.TestCase):
mock_install_netns.assert_called_once() mock_install_netns.assert_called_once()
systemctl_calls = [ systemctl_calls = [
mock.call(consts.ENABLE, mock.call(consts.ENABLE,
consts.AMP_NETNS_SVC_PREFIX), consts.AMP_NETNS_SVC_PREFIX, False),
mock.call(consts.ENABLE, mock.call(
f'octavia-keepalivedlvs-{str(self.FAKE_ID)}'), consts.ENABLE,
'octavia-keepalivedlvs-%s.service' % self.FAKE_ID),
] ]
mock_systemctl.assert_has_calls(systemctl_calls) mock_systemctl.assert_has_calls(systemctl_calls)
os_mkdir_calls = [ os_mkdir_calls = [
@ -159,8 +157,7 @@ class KeepalivedLvsTestCase(base.TestCase):
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
systemd_cfg_path = util.keepalived_lvs_init_path( systemd_cfg_path = util.keepalived_lvs_init_path(self.FAKE_ID)
consts.INIT_SYSTEMD, self.FAKE_ID)
m_open_calls = [ m_open_calls = [
mock.call(cfg_path, flags, mode), mock.call(cfg_path, flags, mode),
@ -181,8 +178,6 @@ class KeepalivedLvsTestCase(base.TestCase):
'install_netns_systemd_service') 'install_netns_systemd_service')
@mock.patch('pyroute2.NetNS', create=True) @mock.patch('pyroute2.NetNS', create=True)
@mock.patch('shutil.copy2') @mock.patch('shutil.copy2')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSTEMD)
@mock.patch('os.chmod') @mock.patch('os.chmod')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
@mock.patch('os.makedirs') @mock.patch('os.makedirs')
@ -190,8 +185,8 @@ class KeepalivedLvsTestCase(base.TestCase):
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
def test_upload_lvs_listener_config_with_vrrp_check_dir( def test_upload_lvs_listener_config_with_vrrp_check_dir(
self, m_check_output, m_os_rm, m_os_mkdir, m_exists, m_os_chmod, self, m_check_output, m_os_rm, m_os_mkdir, m_exists, m_os_chmod,
m_os_sysinit, m_copy2, mock_netns, mock_install_netns, m_copy2, mock_netns, mock_install_netns, mock_systemctl,
mock_systemctl, mock_get_lbs, mock_get_lvs_listeners): mock_get_lbs, mock_get_lvs_listeners):
m_exists.side_effect = [False, False, True, True, False, False, False] m_exists.side_effect = [False, False, True, True, False, False, False]
mock_get_lbs.return_value = [] mock_get_lbs.return_value = []
mock_get_lvs_listeners.return_value = [self.FAKE_ID] mock_get_lvs_listeners.return_value = [self.FAKE_ID]
@ -219,9 +214,10 @@ class KeepalivedLvsTestCase(base.TestCase):
mock_install_netns.assert_called_once() mock_install_netns.assert_called_once()
systemctl_calls = [ systemctl_calls = [
mock.call(consts.ENABLE, mock.call(consts.ENABLE,
consts.AMP_NETNS_SVC_PREFIX), consts.AMP_NETNS_SVC_PREFIX, False),
mock.call(consts.ENABLE, mock.call(
f'octavia-keepalivedlvs-{str(self.FAKE_ID)}'), consts.ENABLE,
'octavia-keepalivedlvs-%s.service' % self.FAKE_ID)
] ]
mock_systemctl.assert_has_calls(systemctl_calls) mock_systemctl.assert_has_calls(systemctl_calls)
@ -229,8 +225,7 @@ class KeepalivedLvsTestCase(base.TestCase):
util.keepalived_backend_check_script_path(), stat.S_IEXEC) util.keepalived_backend_check_script_path(), stat.S_IEXEC)
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
systemd_cfg_path = util.keepalived_lvs_init_path( systemd_cfg_path = util.keepalived_lvs_init_path(self.FAKE_ID)
consts.INIT_SYSTEMD, self.FAKE_ID)
script_path = os.path.join( script_path = os.path.join(
util.keepalived_check_scripts_dir(), util.keepalived_check_scripts_dir(),
keepalivedlvs.KEEPALIVED_CHECK_SCRIPT_NAME) keepalivedlvs.KEEPALIVED_CHECK_SCRIPT_NAME)
@ -252,8 +247,6 @@ class KeepalivedLvsTestCase(base.TestCase):
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'install_netns_systemd_service') 'install_netns_systemd_service')
@mock.patch('shutil.copy2') @mock.patch('shutil.copy2')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSTEMD)
@mock.patch('os.chmod') @mock.patch('os.chmod')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
@mock.patch('os.makedirs') @mock.patch('os.makedirs')
@ -261,7 +254,7 @@ class KeepalivedLvsTestCase(base.TestCase):
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
def test_upload_lvs_listener_config_start_service_failure( def test_upload_lvs_listener_config_start_service_failure(
self, m_check_output, m_os_rm, m_os_mkdir, m_exists, m_os_chmod, self, m_check_output, m_os_rm, m_os_mkdir, m_exists, m_os_chmod,
m_os_sysinit, m_copy2, mock_install_netns, mock_systemctl): m_copy2, mock_install_netns, mock_systemctl):
m_exists.side_effect = [False, False, True, True, False] m_exists.side_effect = [False, False, True, True, False]
cfg_path = util.keepalived_lvs_cfg_path(self.FAKE_ID) cfg_path = util.keepalived_lvs_cfg_path(self.FAKE_ID)
m = self.useFixture(test_utils.OpenFixture(cfg_path)).mock_open m = self.useFixture(test_utils.OpenFixture(cfg_path)).mock_open
@ -283,9 +276,10 @@ class KeepalivedLvsTestCase(base.TestCase):
mock_install_netns.assert_called_once() mock_install_netns.assert_called_once()
systemctl_calls = [ systemctl_calls = [
mock.call(consts.ENABLE, mock.call(consts.ENABLE,
consts.AMP_NETNS_SVC_PREFIX), consts.AMP_NETNS_SVC_PREFIX, False),
mock.call(consts.ENABLE, mock.call(
f'octavia-keepalivedlvs-{str(self.FAKE_ID)}'), consts.ENABLE,
'octavia-keepalivedlvs-%s.service' % self.FAKE_ID)
] ]
mock_systemctl.assert_has_calls(systemctl_calls) mock_systemctl.assert_has_calls(systemctl_calls)
@ -293,8 +287,7 @@ class KeepalivedLvsTestCase(base.TestCase):
util.keepalived_backend_check_script_path(), stat.S_IEXEC) util.keepalived_backend_check_script_path(), stat.S_IEXEC)
flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
systemd_cfg_path = util.keepalived_lvs_init_path( systemd_cfg_path = util.keepalived_lvs_init_path(self.FAKE_ID)
consts.INIT_SYSTEMD, self.FAKE_ID)
m_open_calls = [ m_open_calls = [
mock.call(cfg_path, flags, mode), mock.call(cfg_path, flags, mode),
mock.call(systemd_cfg_path, flags, mode) mock.call(systemd_cfg_path, flags, mode)
@ -311,7 +304,7 @@ class KeepalivedLvsTestCase(base.TestCase):
def test_manage_lvs_listener(self, mock_lvs_exist, mock_check_output): def test_manage_lvs_listener(self, mock_lvs_exist, mock_check_output):
res = self.test_keepalivedlvs.manage_lvs_listener(self.FAKE_ID, res = self.test_keepalivedlvs.manage_lvs_listener(self.FAKE_ID,
'start') 'start')
cmd = f"/usr/sbin/service octavia-keepalivedlvs-{self.FAKE_ID} start" cmd = f"systemctl start octavia-keepalivedlvs-{self.FAKE_ID}.service"
mock_check_output.assert_called_once_with(cmd.split(), mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
@ -330,20 +323,19 @@ class KeepalivedLvsTestCase(base.TestCase):
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_lvs_listeners', return_value=[LISTENER_ID]) 'get_lvs_listeners', return_value=[LISTENER_ID])
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSTEMD)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_keepalivedlvs_pid', return_value="12345") 'get_keepalivedlvs_pid', return_value="12345")
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
@mock.patch('os.remove') @mock.patch('os.remove')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
def test_delete_lvs_listener(self, m_exist, m_remove, m_check_output, def test_delete_lvs_listener(self, m_exist, m_remove, m_check_output,
mget_pid, m_init_sys, mget_lvs_listeners): mget_pid, mget_lvs_listeners):
m_exist.return_value = True m_exist.return_value = True
res = self.test_keepalivedlvs.delete_lvs_listener(self.FAKE_ID) res = self.test_keepalivedlvs.delete_lvs_listener(self.FAKE_ID)
cmd1 = f"/usr/sbin/service octavia-keepalivedlvs-{self.FAKE_ID} stop" cmd1 = f"systemctl stop octavia-keepalivedlvs-{self.FAKE_ID}.service"
cmd2 = f"systemctl disable octavia-keepalivedlvs-{self.FAKE_ID}" cmd2 = ("systemctl disable "
f"octavia-keepalivedlvs-{self.FAKE_ID}.service")
calls = [ calls = [
mock.call(cmd1.split(), stderr=subprocess.STDOUT, mock.call(cmd1.split(), stderr=subprocess.STDOUT,
encoding='utf-8'), encoding='utf-8'),
@ -360,9 +352,10 @@ class KeepalivedLvsTestCase(base.TestCase):
self.test_keepalivedlvs.delete_lvs_listener(self.FAKE_ID) self.test_keepalivedlvs.delete_lvs_listener(self.FAKE_ID)
calls = [ calls = [
mock.call( mock.call(
json=dict(message='UDP Listener Not Found', json=dict(
details="No UDP listener with UUID: " message='UDP Listener Not Found',
"{}".format(self.FAKE_ID)), status=404), details=f"No UDP listener with UUID: {self.FAKE_ID}"
), status=404),
mock.call(json={'message': 'OK'}) mock.call(json={'message': 'OK'})
] ]
m_webob.Response.assert_has_calls(calls) m_webob.Response.assert_has_calls(calls)
@ -381,8 +374,6 @@ class KeepalivedLvsTestCase(base.TestCase):
self.assertEqual({'message': 'Error stopping keepalivedlvs', self.assertEqual({'message': 'Error stopping keepalivedlvs',
'details': None}, res.json) 'details': None}, res.json)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSVINIT)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_keepalivedlvs_pid', return_value="12345") 'get_keepalivedlvs_pid', return_value="12345")
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
@ -390,8 +381,7 @@ class KeepalivedLvsTestCase(base.TestCase):
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
def test_delete_lvs_listener_disable_service_fail(self, m_exist, m_remove, def test_delete_lvs_listener_disable_service_fail(self, m_exist, m_remove,
m_check_output, m_check_output,
mget_pid, mget_pid):
m_init_sys):
m_exist.return_value = True m_exist.return_value = True
m_check_output.side_effect = [True, m_check_output.side_effect = [True,
subprocess.CalledProcessError( subprocess.CalledProcessError(
@ -402,19 +392,3 @@ class KeepalivedLvsTestCase(base.TestCase):
'message': f'Error disabling octavia-keepalivedlvs-{self.FAKE_ID} ' 'message': f'Error disabling octavia-keepalivedlvs-{self.FAKE_ID} '
f'service', f'service',
'details': None}, res.json) 'details': None}, res.json)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_keepalivedlvs_pid', return_value="12345")
@mock.patch('subprocess.check_output')
@mock.patch('os.remove')
@mock.patch('os.path.exists')
def test_delete_lvs_listener_unsupported_sysinit(self, m_exist, m_remove,
m_check_output, mget_pid,
m_init_sys):
m_exist.return_value = True
self.assertRaises(
util.UnknownInitError,
self.test_keepalivedlvs.delete_lvs_listener,
self.FAKE_ID)

View File

@ -69,29 +69,11 @@ class TestServerTestCase(base.TestCase):
self.centos_test_server = server.Server() self.centos_test_server = server.Server()
self.centos_app = self.centos_test_server.app.test_client() self.centos_app = self.centos_test_server.app.test_client()
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' def test_ubuntu_haproxy(self):
'get_os_init_system', return_value=consts.INIT_SYSTEMD) self._test_haproxy(consts.UBUNTU)
def test_ubuntu_haproxy_systemd(self, mock_init_system):
self._test_haproxy(consts.INIT_SYSTEMD, consts.UBUNTU,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' def test_centos_haproxy(self):
'get_os_init_system', return_value=consts.INIT_SYSTEMD) self._test_haproxy(consts.CENTOS)
def test_centos_haproxy_systemd(self, mock_init_system):
self._test_haproxy(consts.INIT_SYSTEMD, consts.CENTOS,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSVINIT)
def test_ubuntu_haproxy_sysvinit(self, mock_init_system):
self._test_haproxy(consts.INIT_SYSVINIT, consts.UBUNTU,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_UPSTART)
def test_ubuntu_haproxy_upstart(self, mock_init_system):
self._test_haproxy(consts.INIT_UPSTART, consts.UBUNTU,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.' @mock.patch('octavia.amphorae.backends.agent.api_server.'
'haproxy_compatibility.get_haproxy_versions') 'haproxy_compatibility.get_haproxy_versions')
@ -99,7 +81,7 @@ class TestServerTestCase(base.TestCase):
@mock.patch('os.makedirs') @mock.patch('os.makedirs')
@mock.patch('os.rename') @mock.patch('os.rename')
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
def _test_haproxy(self, init_system, distro, mock_init_system, def _test_haproxy(self, distro,
mock_subprocess, mock_rename, mock_subprocess, mock_rename,
mock_makedirs, mock_exists, mock_get_version): mock_makedirs, mock_exists, mock_get_version):
@ -142,16 +124,10 @@ class TestServerTestCase(base.TestCase):
'/var/lib/octavia/123/haproxy.cfg.new', '/var/lib/octavia/123/haproxy.cfg.new',
'/var/lib/octavia/123/haproxy.cfg') '/var/lib/octavia/123/haproxy.cfg')
if init_system == consts.INIT_SYSTEMD:
mock_subprocess.assert_any_call( mock_subprocess.assert_any_call(
"systemctl enable haproxy-123".split(), ['systemctl', 'enable', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT,
elif init_system == consts.INIT_SYSVINIT: encoding='utf-8')
mock_subprocess.assert_any_call(
"insserv /etc/init.d/haproxy-123".split(),
stderr=subprocess.STDOUT, encoding='utf-8')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
# exception writing # exception writing
m = self.useFixture(test_utils.OpenFixture(file_name)).mock_open m = self.useFixture(test_utils.OpenFixture(file_name)).mock_open
@ -171,14 +147,7 @@ class TestServerTestCase(base.TestCase):
# check if files get created # check if files get created
mock_exists.return_value = False mock_exists.return_value = False
if init_system == consts.INIT_SYSTEMD:
init_path = consts.SYSTEMD_DIR + '/haproxy-123.service' init_path = consts.SYSTEMD_DIR + '/haproxy-123.service'
elif init_system == consts.INIT_UPSTART:
init_path = consts.UPSTART_DIR + '/haproxy-123.conf'
elif init_system == consts.INIT_SYSVINIT:
init_path = consts.SYSVINIT_DIR + '/haproxy-123'
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
m = self.useFixture(test_utils.OpenFixture(init_path)).mock_open m = self.useFixture(test_utils.OpenFixture(init_path)).mock_open
# happy case upstart file exists # happy case upstart file exists
@ -198,12 +167,8 @@ class TestServerTestCase(base.TestCase):
data='test') data='test')
self.assertEqual(202, rv.status_code) self.assertEqual(202, rv.status_code)
if init_system == consts.INIT_SYSTEMD:
mode = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | mode = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP |
stat.S_IROTH) stat.S_IROTH)
else:
mode = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH)
mock_open.assert_called_with(init_path, flags, mode) mock_open.assert_called_with(init_path, flags, mode)
mock_fdopen.assert_called_with(123, 'w') mock_fdopen.assert_called_with(123, 'w')
handle = mock_fdopen() handle = mock_fdopen()
@ -248,23 +213,6 @@ class TestServerTestCase(base.TestCase):
'/var/lib/octavia/123/haproxy.cfg.new', '/var/lib/octavia/123/haproxy.cfg.new',
'/var/lib/octavia/123/haproxy.cfg.new-failed') '/var/lib/octavia/123/haproxy.cfg.new-failed')
# unhappy path with bogus init system
mock_init_system.return_value = 'bogus'
with mock.patch('os.open') as mock_open, mock.patch.object(
os, 'fdopen', m) as mock_fdopen, mock.patch(
'distro.id') as mock_distro_id:
mock_open.return_value = 123
mock_distro_id.return_value = distro
if distro == consts.UBUNTU:
rv = self.ubuntu_app.put('/' + api_server.VERSION +
'/loadbalancer/amp_123/123/haproxy',
data='test')
elif distro == consts.CENTOS:
rv = self.ubuntu_app.put('/' + api_server.VERSION +
'/loadbalancer/amp_123/123/haproxy',
data='test')
self.assertEqual(500, rv.status_code)
def test_ubuntu_start(self): def test_ubuntu_start(self):
self._test_start(consts.UBUNTU) self._test_start(consts.UBUNTU)
@ -321,8 +269,9 @@ class TestServerTestCase(base.TestCase):
' 123 started'}, ' 123 started'},
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_subprocess.assert_called_with( mock_subprocess.assert_called_with(
['/usr/sbin/service', 'haproxy-123', 'start'], ['systemctl', 'start', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT,
encoding='utf-8')
mock_exists.return_value = True mock_exists.return_value = True
mock_subprocess.side_effect = subprocess.CalledProcessError( mock_subprocess.side_effect = subprocess.CalledProcessError(
@ -340,7 +289,7 @@ class TestServerTestCase(base.TestCase):
'details': RANDOM_ERROR, 'details': RANDOM_ERROR,
}, jsonutils.loads(rv.data.decode('utf-8'))) }, jsonutils.loads(rv.data.decode('utf-8')))
mock_subprocess.assert_called_with( mock_subprocess.assert_called_with(
['/usr/sbin/service', 'haproxy-123', 'start'], ['systemctl', 'start', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT, encoding='utf-8')
def test_ubuntu_reload(self): def test_ubuntu_reload(self):
@ -379,7 +328,7 @@ class TestServerTestCase(base.TestCase):
'details': 'Listener 123 reloaded'}, 'details': 'Listener 123 reloaded'},
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_subprocess.assert_called_with( mock_subprocess.assert_called_with(
['/usr/sbin/service', 'haproxy-123', 'reload'], ['systemctl', 'reload', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT, encoding='utf-8')
# Process not running so start # Process not running so start
@ -398,7 +347,7 @@ class TestServerTestCase(base.TestCase):
' 123 started'}, ' 123 started'},
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_subprocess.assert_called_with( mock_subprocess.assert_called_with(
['/usr/sbin/service', 'haproxy-123', 'start'], ['systemctl', 'start', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT, encoding='utf-8')
def test_ubuntu_info(self): def test_ubuntu_info(self):
@ -432,39 +381,13 @@ class TestServerTestCase(base.TestCase):
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_backend_for_lb_object', return_value='HAPROXY') 'get_backend_for_lb_object', return_value='HAPROXY')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' def test_delete_ubuntu_listener(self, mock_get_proto):
'get_os_init_system', return_value=consts.INIT_SYSTEMD) self._test_delete_listener(consts.UBUNTU)
def test_delete_ubuntu_listener_systemd(self, mock_init_system,
mock_get_proto):
self._test_delete_listener(consts.INIT_SYSTEMD, consts.UBUNTU,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_backend_for_lb_object', return_value='HAPROXY') 'get_backend_for_lb_object', return_value='HAPROXY')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' def test_delete_centos_listener(self, mock_get_proto):
'get_os_init_system', return_value=consts.INIT_SYSTEMD) self._test_delete_listener(consts.CENTOS)
def test_delete_centos_listener_systemd(self, mock_init_system,
mock_get_proto):
self._test_delete_listener(consts.INIT_SYSTEMD, consts.CENTOS,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_backend_for_lb_object', return_value='HAPROXY')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSVINIT)
def test_delete_ubuntu_listener_sysvinit(self, mock_init_system,
mock_get_proto):
self._test_delete_listener(consts.INIT_SYSVINIT, consts.UBUNTU,
mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_backend_for_lb_object', return_value='HAPROXY')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_UPSTART)
def test_delete_ubuntu_listener_upstart(self, mock_init_system,
mock_get_proto):
self._test_delete_listener(consts.INIT_UPSTART, consts.UBUNTU,
mock_init_system)
@mock.patch('os.listdir') @mock.patch('os.listdir')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
@ -475,7 +398,7 @@ class TestServerTestCase(base.TestCase):
'get_haproxy_pid') 'get_haproxy_pid')
@mock.patch('shutil.rmtree') @mock.patch('shutil.rmtree')
@mock.patch('os.remove') @mock.patch('os.remove')
def _test_delete_listener(self, init_system, distro, mock_init_system, def _test_delete_listener(self, distro,
mock_remove, mock_rmtree, mock_pid, mock_vrrp, mock_remove, mock_rmtree, mock_pid, mock_vrrp,
mock_check_output, mock_exists, mock_listdir): mock_check_output, mock_exists, mock_listdir):
self.assertIn(distro, [consts.UBUNTU, consts.CENTOS]) self.assertIn(distro, [consts.UBUNTU, consts.CENTOS])
@ -505,17 +428,8 @@ class TestServerTestCase(base.TestCase):
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_rmtree.assert_called_with('/var/lib/octavia/123') mock_rmtree.assert_called_with('/var/lib/octavia/123')
if init_system == consts.INIT_SYSTEMD:
mock_exists.assert_called_with(consts.SYSTEMD_DIR + mock_exists.assert_called_with(consts.SYSTEMD_DIR +
'/haproxy-123.service') '/haproxy-123.service')
elif init_system == consts.INIT_UPSTART:
mock_exists.assert_called_with(consts.UPSTART_DIR +
'/haproxy-123.conf')
elif init_system == consts.INIT_SYSVINIT:
mock_exists.assert_called_with(consts.SYSVINIT_DIR +
'/haproxy-123')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
mock_exists.assert_any_call('/var/lib/octavia/123/123.pid') mock_exists.assert_any_call('/var/lib/octavia/123/123.pid')
@ -532,17 +446,8 @@ class TestServerTestCase(base.TestCase):
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_rmtree.assert_called_with('/var/lib/octavia/123') mock_rmtree.assert_called_with('/var/lib/octavia/123')
if init_system == consts.INIT_SYSTEMD:
mock_exists.assert_called_with(consts.SYSTEMD_DIR + mock_exists.assert_called_with(consts.SYSTEMD_DIR +
'/haproxy-123.service') '/haproxy-123.service')
elif init_system == consts.INIT_UPSTART:
mock_exists.assert_called_with(consts.UPSTART_DIR +
'/haproxy-123.conf')
elif init_system == consts.INIT_SYSVINIT:
mock_exists.assert_called_with(consts.SYSVINIT_DIR +
'/haproxy-123')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
mock_exists.assert_any_call('/var/lib/octavia/123/123.pid') mock_exists.assert_any_call('/var/lib/octavia/123/123.pid')
@ -558,17 +463,8 @@ class TestServerTestCase(base.TestCase):
self.assertEqual({'message': 'OK'}, self.assertEqual({'message': 'OK'},
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
if init_system == consts.INIT_SYSTEMD:
mock_remove.assert_called_with(consts.SYSTEMD_DIR + mock_remove.assert_called_with(consts.SYSTEMD_DIR +
'/haproxy-123.service') '/haproxy-123.service')
elif init_system == consts.INIT_UPSTART:
mock_remove.assert_called_with(consts.UPSTART_DIR +
'/haproxy-123.conf')
elif init_system == consts.INIT_SYSVINIT:
mock_remove.assert_called_with(consts.SYSVINIT_DIR +
'/haproxy-123')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
# service is stopped + upstart script + vrrp # service is stopped + upstart script + vrrp
mock_exists.side_effect = [True, True, False, True, True] mock_exists.side_effect = [True, True, False, True, True]
@ -582,17 +478,8 @@ class TestServerTestCase(base.TestCase):
self.assertEqual({'message': 'OK'}, self.assertEqual({'message': 'OK'},
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
if init_system == consts.INIT_SYSTEMD:
mock_remove.assert_called_with(consts.SYSTEMD_DIR + mock_remove.assert_called_with(consts.SYSTEMD_DIR +
'/haproxy-123.service') '/haproxy-123.service')
elif init_system == consts.INIT_UPSTART:
mock_remove.assert_called_with(consts.UPSTART_DIR +
'/haproxy-123.conf')
elif init_system == consts.INIT_SYSVINIT:
mock_remove.assert_called_with(consts.SYSVINIT_DIR +
'/haproxy-123')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
# service is running + upstart script + no vrrp # service is running + upstart script + no vrrp
mock_exists.side_effect = [True, True, True, True, False, True] mock_exists.side_effect = [True, True, True, True, False, True]
@ -608,24 +495,12 @@ class TestServerTestCase(base.TestCase):
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_pid.assert_called_once_with('123') mock_pid.assert_called_once_with('123')
mock_check_output.assert_any_call( mock_check_output.assert_any_call(
['/usr/sbin/service', 'haproxy-123', 'stop'], ['systemctl', 'stop', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT, encoding='utf-8')
if init_system == consts.INIT_SYSTEMD:
mock_check_output.assert_any_call( mock_check_output.assert_any_call(
"systemctl disable haproxy-123".split(), ['systemctl', 'disable', 'haproxy-123.service'],
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT, encoding='utf-8')
encoding='utf-8')
elif init_system == consts.INIT_UPSTART:
mock_remove.assert_any_call(consts.UPSTART_DIR +
'/haproxy-123.conf')
elif init_system == consts.INIT_SYSVINIT:
mock_check_output.assert_any_call(
"insserv -r /etc/init.d/haproxy-123".split(),
stderr=subprocess.STDOUT,
encoding='utf-8')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
# service is running + upstart script + vrrp # service is running + upstart script + vrrp
mock_exists.side_effect = [True, True, True, True, True, True] mock_exists.side_effect = [True, True, True, True, True, True]
@ -641,24 +516,12 @@ class TestServerTestCase(base.TestCase):
jsonutils.loads(rv.data.decode('utf-8'))) jsonutils.loads(rv.data.decode('utf-8')))
mock_pid.assert_called_with('123') mock_pid.assert_called_with('123')
mock_check_output.assert_any_call( mock_check_output.assert_any_call(
['/usr/sbin/service', 'haproxy-123', 'stop'], ['systemctl', 'stop', 'haproxy-123.service'],
stderr=subprocess.STDOUT, encoding='utf-8') stderr=subprocess.STDOUT, encoding='utf-8')
if init_system == consts.INIT_SYSTEMD:
mock_check_output.assert_any_call( mock_check_output.assert_any_call(
"systemctl disable haproxy-123".split(), ['systemctl', 'disable', 'haproxy-123.service'],
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT, encoding='utf-8')
encoding='utf-8')
elif init_system == consts.INIT_UPSTART:
mock_remove.assert_any_call(consts.UPSTART_DIR +
'/haproxy-123.conf')
elif init_system == consts.INIT_SYSVINIT:
mock_check_output.assert_any_call(
"insserv -r /etc/init.d/haproxy-123".split(),
stderr=subprocess.STDOUT,
encoding='utf-8')
else:
self.assertIn(init_system, consts.VALID_INIT_SYSTEMS)
# service is running + stopping fails # service is running + stopping fails
mock_exists.side_effect = [True, True, True, True] mock_exists.side_effect = [True, True, True, True]
@ -2716,31 +2579,13 @@ class TestServerTestCase(base.TestCase):
content_type='application/json') content_type='application/json')
self.assertEqual(400, rv.status_code) self.assertEqual(400, rv.status_code)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' def test_ubuntu_upload_keepalived_config(self):
'get_os_init_system', return_value=consts.INIT_SYSTEMD)
def test_ubuntu_upload_keepalived_config_systemd(self, mock_init_system):
with mock.patch('distro.id', return_value='ubuntu'): with mock.patch('distro.id', return_value='ubuntu'):
self._test_upload_keepalived_config( self._test_upload_keepalived_config(consts.UBUNTU)
consts.INIT_SYSTEMD, consts.UBUNTU, mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' def test_centos_upload_keepalived_config(self):
'get_os_init_system', return_value=consts.INIT_SYSTEMD)
def test_centos_upload_keepalived_config_systemd(self, mock_init_system):
with mock.patch('distro.id', return_value='centos'): with mock.patch('distro.id', return_value='centos'):
self._test_upload_keepalived_config( self._test_upload_keepalived_config(consts.CENTOS)
consts.INIT_SYSTEMD, consts.CENTOS, mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_UPSTART)
def test_ubuntu_upload_keepalived_config_upstart(self, mock_init_system):
self._test_upload_keepalived_config(consts.INIT_UPSTART,
consts.UBUNTU, mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system', return_value=consts.INIT_SYSVINIT)
def test_ubuntu_upload_keepalived_config_sysvinit(self, mock_init_system):
self._test_upload_keepalived_config(consts.INIT_SYSVINIT,
consts.UBUNTU, mock_init_system)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'vrrp_check_script_update') 'vrrp_check_script_update')
@ -2749,8 +2594,7 @@ class TestServerTestCase(base.TestCase):
@mock.patch('os.rename') @mock.patch('os.rename')
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
@mock.patch('os.remove') @mock.patch('os.remove')
def _test_upload_keepalived_config(self, init_system, distro, def _test_upload_keepalived_config(self, distro, mock_remove,
mock_init_system, mock_remove,
mock_subprocess, mock_rename, mock_subprocess, mock_rename,
mock_makedirs, mock_exists, mock_makedirs, mock_exists,
mock_vrrp_check): mock_vrrp_check):

View File

@ -32,7 +32,7 @@ class KeepalivedTestCase(base.TestCase):
@mock.patch('subprocess.check_output') @mock.patch('subprocess.check_output')
def test_manager_keepalived_service(self, mock_check_output): def test_manager_keepalived_service(self, mock_check_output):
res = self.test_keepalived.manager_keepalived_service('start') res = self.test_keepalived.manager_keepalived_service('start')
cmd = "/usr/sbin/service octavia-keepalived start" cmd = 'systemctl start octavia-keepalived.service'
mock_check_output.assert_called_once_with(cmd.split(), mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')

View File

@ -16,7 +16,6 @@ from unittest import mock
from oslo_utils import uuidutils from oslo_utils import uuidutils
from octavia.amphorae.backends.agent.api_server import keepalivedlvs from octavia.amphorae.backends.agent.api_server import keepalivedlvs
from octavia.amphorae.backends.agent.api_server import util
from octavia.tests.unit import base from octavia.tests.unit import base
@ -40,20 +39,3 @@ class KeepalivedLvsTestCase(base.TestCase):
mock.call(json={'message': 'OK'}) mock.call(json={'message': 'OK'})
] ]
m_webob.Response.assert_has_calls(calls) m_webob.Response.assert_has_calls(calls)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_os_init_system')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.'
'get_keepalivedlvs_pid')
@mock.patch('subprocess.check_output')
@mock.patch('os.remove')
@mock.patch('os.path.exists')
def test_delete_lvs_listener_unsupported_sysinit(self, m_exist, m_remove,
m_check_output, mget_pid,
m_init_sys):
m_exist.return_value = True
mget_pid.return_value = '0'
self.assertRaises(
util.UnknownInitError,
self.test_keepalivedlvs.delete_lvs_listener,
self.FAKE_ID)

View File

@ -78,14 +78,13 @@ class ListenerTestCase(base.TestCase):
mock_check_status.side_effect = ['bogus', consts.OFFLINE] mock_check_status.side_effect = ['bogus', consts.OFFLINE]
# Happy path - No VRRP # Happy path - No VRRP
ref_command_split = ['/usr/sbin/service'] cmd = "systemctl {action} haproxy-{listener_id}.service".format(
ref_command_split.append(f'haproxy-{listener_id}') action=consts.AMP_ACTION_START, listener_id=listener_id)
ref_command_split.append(consts.AMP_ACTION_START)
result = self.test_loadbalancer.start_stop_lb( result = self.test_loadbalancer.start_stop_lb(
listener_id, consts.AMP_ACTION_START) listener_id, consts.AMP_ACTION_START)
mock_check_output.assert_called_once_with(ref_command_split, mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
mock_lb_exists.assert_called_once_with(listener_id) mock_lb_exists.assert_called_once_with(listener_id)
@ -104,14 +103,13 @@ class ListenerTestCase(base.TestCase):
mock_vrrp_update.reset_mock() mock_vrrp_update.reset_mock()
mock_check_output.reset_mock() mock_check_output.reset_mock()
ref_command_split = ['/usr/sbin/service'] cmd = "systemctl {action} haproxy-{listener_id}.service".format(
ref_command_split.append(f'haproxy-{listener_id}') action=consts.AMP_ACTION_RELOAD, listener_id=listener_id)
ref_command_split.append(consts.AMP_ACTION_RELOAD)
result = self.test_loadbalancer.start_stop_lb( result = self.test_loadbalancer.start_stop_lb(
listener_id, consts.AMP_ACTION_RELOAD) listener_id, consts.AMP_ACTION_RELOAD)
mock_check_output.assert_called_once_with(ref_command_split, mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
mock_lb_exists.assert_called_once_with(listener_id) mock_lb_exists.assert_called_once_with(listener_id)
@ -127,14 +125,13 @@ class ListenerTestCase(base.TestCase):
mock_vrrp_update.reset_mock() mock_vrrp_update.reset_mock()
mock_check_output.reset_mock() mock_check_output.reset_mock()
ref_command_split = ['/usr/sbin/service'] cmd = "systemctl {action} haproxy-{listener_id}.service".format(
ref_command_split.append(f'haproxy-{listener_id}') action=consts.AMP_ACTION_START, listener_id=listener_id)
ref_command_split.append(consts.AMP_ACTION_START)
result = self.test_loadbalancer.start_stop_lb( result = self.test_loadbalancer.start_stop_lb(
listener_id, consts.AMP_ACTION_RELOAD) listener_id, consts.AMP_ACTION_RELOAD)
mock_check_output.assert_called_once_with(ref_command_split, mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
mock_lb_exists.assert_called_once_with(listener_id) mock_lb_exists.assert_called_once_with(listener_id)
@ -154,9 +151,8 @@ class ListenerTestCase(base.TestCase):
mock_vrrp_update.reset_mock() mock_vrrp_update.reset_mock()
mock_check_output.reset_mock() mock_check_output.reset_mock()
ref_command_split = ['/usr/sbin/service'] cmd = "systemctl {action} haproxy-{listener_id}.service".format(
ref_command_split.append(f'haproxy-{listener_id}') action=consts.AMP_ACTION_START, listener_id=listener_id)
ref_command_split.append(consts.AMP_ACTION_START)
mock_check_output.side_effect = subprocess.CalledProcessError( mock_check_output.side_effect = subprocess.CalledProcessError(
output='bogus', returncode=-2, cmd='sit') output='bogus', returncode=-2, cmd='sit')
@ -164,7 +160,7 @@ class ListenerTestCase(base.TestCase):
result = self.test_loadbalancer.start_stop_lb( result = self.test_loadbalancer.start_stop_lb(
listener_id, consts.AMP_ACTION_START) listener_id, consts.AMP_ACTION_START)
mock_check_output.assert_called_once_with(ref_command_split, mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
mock_lb_exists.assert_called_once_with(listener_id) mock_lb_exists.assert_called_once_with(listener_id)
@ -179,9 +175,8 @@ class ListenerTestCase(base.TestCase):
mock_vrrp_update.reset_mock() mock_vrrp_update.reset_mock()
mock_check_output.reset_mock() mock_check_output.reset_mock()
ref_command_split = ['/usr/sbin/service'] cmd = "systemctl {action} haproxy-{listener_id}.service".format(
ref_command_split.append(f'haproxy-{listener_id}') action=consts.AMP_ACTION_START, listener_id=listener_id)
ref_command_split.append(consts.AMP_ACTION_START)
mock_check_output.side_effect = subprocess.CalledProcessError( mock_check_output.side_effect = subprocess.CalledProcessError(
output='Job is already running', returncode=-2, cmd='sit') output='Job is already running', returncode=-2, cmd='sit')
@ -189,7 +184,7 @@ class ListenerTestCase(base.TestCase):
result = self.test_loadbalancer.start_stop_lb( result = self.test_loadbalancer.start_stop_lb(
listener_id, consts.AMP_ACTION_START) listener_id, consts.AMP_ACTION_START)
mock_check_output.assert_called_once_with(ref_command_split, mock_check_output.assert_called_once_with(cmd.split(),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
encoding='utf-8') encoding='utf-8')
mock_lb_exists.assert_called_once_with(listener_id) mock_lb_exists.assert_called_once_with(listener_id)

View File

@ -51,31 +51,11 @@ class TestUtil(base.TestCase):
self.assertEqual(fake_path, result) self.assertEqual(fake_path, result)
def test_keepalived_lvs_init_path(self): def test_keepalived_lvs_init_path(self):
# Test systemd
ref_path = (consts.SYSTEMD_DIR + '/' + ref_path = (consts.SYSTEMD_DIR + '/' +
consts.KEEPALIVED_SYSTEMD_PREFIX % str(self.listener_id)) consts.KEEPALIVEDLVS_SYSTEMD % self.listener_id)
result = util.keepalived_lvs_init_path(consts.INIT_SYSTEMD, result = util.keepalived_lvs_init_path(self.listener_id)
self.listener_id)
self.assertEqual(ref_path, result) self.assertEqual(ref_path, result)
# Test upstart
ref_path = (consts.UPSTART_DIR + '/' +
consts.KEEPALIVED_UPSTART_PREFIX % str(self.listener_id))
result = util.keepalived_lvs_init_path(consts.INIT_UPSTART,
self.listener_id)
self.assertEqual(ref_path, result)
# Test sysvinit
ref_path = (consts.SYSVINIT_DIR + '/' +
consts.KEEPALIVED_SYSVINIT_PREFIX % str(self.listener_id))
result = util.keepalived_lvs_init_path(consts.INIT_SYSVINIT,
self.listener_id)
self.assertEqual(ref_path, result)
# Test bad init system
self.assertRaises(util.UnknownInitError, util.keepalived_lvs_init_path,
'bogus_init', self.listener_id)
def test_keepalived_lvs_pids_path(self): def test_keepalived_lvs_pids_path(self):
fake_path = '/fake/path' fake_path = '/fake/path'
self.CONF.config(group="haproxy_amphora", base_path=fake_path) self.CONF.config(group="haproxy_amphora", base_path=fake_path)
@ -167,7 +147,12 @@ class TestUtil(base.TestCase):
mock_check_output.side_effect = subprocess.CalledProcessError(1, mock_check_output.side_effect = subprocess.CalledProcessError(1,
'boom') 'boom')
util.run_systemctl_command('test', 'world') self.assertRaises(subprocess.CalledProcessError,
util.run_systemctl_command, 'test', 'world')
mock_check_output.side_effect = subprocess.CalledProcessError(1,
'boom')
util.run_systemctl_command('test', 'world', False)
@mock.patch('octavia.amphorae.backends.agent.api_server.util.config_path') @mock.patch('octavia.amphorae.backends.agent.api_server.util.config_path')
@mock.patch('octavia.amphorae.backends.agent.api_server.util.' @mock.patch('octavia.amphorae.backends.agent.api_server.util.'

View File

@ -44,8 +44,6 @@ class AgentJinjaTestCase(base.TestCase):
self.conf.config(group="haproxy_amphora", bind_port=9443) self.conf.config(group="haproxy_amphora", bind_port=9443)
self.conf.config(group="haproxy_amphora", self.conf.config(group="haproxy_amphora",
haproxy_cmd='/usr/sbin/haproxy') haproxy_cmd='/usr/sbin/haproxy')
self.conf.config(group="haproxy_amphora", respawn_count=2)
self.conf.config(group="haproxy_amphora", respawn_interval=2)
self.conf.config(group="health_manager", self.conf.config(group="health_manager",
controller_ip_port_list=['192.0.2.10:5555']) controller_ip_port_list=['192.0.2.10:5555'])
self.conf.config(group="health_manager", heartbeat_interval=10) self.conf.config(group="health_manager", heartbeat_interval=10)
@ -67,8 +65,6 @@ class AgentJinjaTestCase(base.TestCase):
'bind_host = 0.0.0.0\n' 'bind_host = 0.0.0.0\n'
'bind_port = 9443\n' 'bind_port = 9443\n'
'haproxy_cmd = /usr/sbin/haproxy\n' 'haproxy_cmd = /usr/sbin/haproxy\n'
'respawn_count = 2\n'
'respawn_interval = 2\n'
'user_log_facility = 0\n' 'user_log_facility = 0\n'
'administrative_log_facility = 1\n\n' 'administrative_log_facility = 1\n\n'
'[health_manager]\n' '[health_manager]\n'
@ -107,8 +103,6 @@ class AgentJinjaTestCase(base.TestCase):
'bind_host = 0.0.0.0\n' 'bind_host = 0.0.0.0\n'
'bind_port = 9443\n' 'bind_port = 9443\n'
'haproxy_cmd = /usr/sbin/haproxy\n' 'haproxy_cmd = /usr/sbin/haproxy\n'
'respawn_count = 2\n'
'respawn_interval = 2\n'
'user_log_facility = 0\n' 'user_log_facility = 0\n'
'administrative_log_facility = 1\n\n' 'administrative_log_facility = 1\n\n'
'[health_manager]\n' '[health_manager]\n'
@ -150,8 +144,6 @@ class AgentJinjaTestCase(base.TestCase):
'bind_host = 0.0.0.0\n' 'bind_host = 0.0.0.0\n'
'bind_port = 9443\n' 'bind_port = 9443\n'
'haproxy_cmd = /usr/sbin/haproxy\n' 'haproxy_cmd = /usr/sbin/haproxy\n'
'respawn_count = 2\n'
'respawn_interval = 2\n'
'user_log_facility = 0\n' 'user_log_facility = 0\n'
'administrative_log_facility = 1\n\n' 'administrative_log_facility = 1\n\n'
'[health_manager]\n' '[health_manager]\n'

View File

@ -0,0 +1,13 @@
---
upgrade:
- |
SysVinit and Upstart are no longer supported as init system in amphora
instances. The only supported init system is now systemd.
deprecations:
- |
The following options have been deprecated and have no effect now. These
options were used by Upstart support which has been removed.
- ``[haproxy_amphora] respawn_count``
- ``[haproxy_amphora] respawn_interval``