From 991e0da01e315a7ac91f7bd654ba188757c79008 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Thu, 30 May 2024 15:02:29 +0900 Subject: [PATCH] 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 --- .../75-amphora-agent-install | 8 - .../certs-ramfs/init-scripts/sysv/certs-ramfs | 39 --- .../init-scripts/upstart/certs-ramfs.conf | 14 - .../30-enable-certs-ramfs-service | 4 - .../backends/agent/agent_jinja_cfg.py | 2 - .../backends/agent/api_server/keepalived.py | 61 ++--- .../agent/api_server/keepalivedlvs.py | 109 +++----- .../backends/agent/api_server/loadbalancer.py | 114 ++------ .../templates/keepalived.sysvinit.j2 | 87 ------- .../templates/keepalived.upstart.j2 | 29 --- .../keepalived_lvs_check_script.sh.j2 | 4 - .../api_server/templates/sysvinit.conf.j2 | 232 ----------------- .../api_server/templates/upstart.conf.j2 | 71 ----- .../backends/agent/api_server/util.py | 68 +---- .../templates/amphora_agent_conf.template | 2 - octavia/common/config.py | 6 + octavia/common/constants.py | 23 +- .../agent/api_server/test_keepalivedlvs.py | 84 +++--- .../backend/agent/api_server/test_server.py | 244 ++++-------------- .../agent/api_server/test_keepalived.py | 2 +- .../agent/api_server/test_keepalivedlvs.py | 18 -- .../agent/api_server/test_loadbalancer.py | 35 ++- .../backends/agent/api_server/test_util.py | 31 +-- .../backends/agent/test_agent_jinja_cfg.py | 8 - ...sysvinit-and-upstart-f1655e9d0c53e5cc.yaml | 13 + 25 files changed, 208 insertions(+), 1100 deletions(-) delete mode 100644 elements/certs-ramfs/init-scripts/sysv/certs-ramfs delete mode 100644 elements/certs-ramfs/init-scripts/upstart/certs-ramfs.conf delete mode 100644 octavia/amphorae/backends/agent/api_server/templates/keepalived.sysvinit.j2 delete mode 100644 octavia/amphorae/backends/agent/api_server/templates/keepalived.upstart.j2 delete mode 100644 octavia/amphorae/backends/agent/api_server/templates/sysvinit.conf.j2 delete mode 100644 octavia/amphorae/backends/agent/api_server/templates/upstart.conf.j2 create mode 100644 releasenotes/notes/remove-sysvinit-and-upstart-f1655e9d0c53e5cc.yaml diff --git a/elements/amphora-agent/install.d/amphora-agent-source-install/75-amphora-agent-install b/elements/amphora-agent/install.d/amphora-agent-source-install/75-amphora-agent-install index 2bee343ef0..c154b882dc 100755 --- a/elements/amphora-agent/install.d/amphora-agent-source-install/75-amphora-agent-install +++ b/elements/amphora-agent/install.d/amphora-agent-source-install/75-amphora-agent-install @@ -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 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) 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 ;; - 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" exit 1 diff --git a/elements/certs-ramfs/init-scripts/sysv/certs-ramfs b/elements/certs-ramfs/init-scripts/sysv/certs-ramfs deleted file mode 100644 index 2cf110079f..0000000000 --- a/elements/certs-ramfs/init-scripts/sysv/certs-ramfs +++ /dev/null @@ -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 diff --git a/elements/certs-ramfs/init-scripts/upstart/certs-ramfs.conf b/elements/certs-ramfs/init-scripts/upstart/certs-ramfs.conf deleted file mode 100644 index 050474b245..0000000000 --- a/elements/certs-ramfs/init-scripts/upstart/certs-ramfs.conf +++ /dev/null @@ -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 diff --git a/elements/certs-ramfs/post-install.d/30-enable-certs-ramfs-service b/elements/certs-ramfs/post-install.d/30-enable-certs-ramfs-service index 9a19b60af4..a79fe24a83 100755 --- a/elements/certs-ramfs/post-install.d/30-enable-certs-ramfs-service +++ b/elements/certs-ramfs/post-install.d/30-enable-certs-ramfs-service @@ -7,10 +7,6 @@ set -eu set -o pipefail case "$DIB_INIT_SYSTEM" in - upstart|sysv) - # nothing to do - exit 0 - ;; systemd) systemctl enable certs-ramfs.service ;; diff --git a/octavia/amphorae/backends/agent/agent_jinja_cfg.py b/octavia/amphorae/backends/agent/agent_jinja_cfg.py index 4d3c610ad2..3709d84770 100644 --- a/octavia/amphorae/backends/agent/agent_jinja_cfg.py +++ b/octavia/amphorae/backends/agent/agent_jinja_cfg.py @@ -52,8 +52,6 @@ class AgentJinjaTemplater: 'haproxy_cmd': CONF.haproxy_amphora.haproxy_cmd, 'heartbeat_interval': CONF.health_manager.heartbeat_interval, '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, 'agent_tls_protocol': CONF.amphora_agent.agent_tls_protocol, 'topology': topology, diff --git a/octavia/amphorae/backends/agent/api_server/keepalived.py b/octavia/amphorae/backends/agent/api_server/keepalived.py index 081870f5fb..781219d56a 100644 --- a/octavia/amphorae/backends/agent/api_server/keepalived.py +++ b/octavia/amphorae/backends/agent/api_server/keepalived.py @@ -34,8 +34,6 @@ LOG = logging.getLogger(__name__) j2_env = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader( 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) check_script_template = j2_env.get_template(consts.CHECK_SCRIPT_CONF) @@ -60,34 +58,17 @@ class Keepalived: f.write(b) 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) + template = SYSTEMD_TEMPLATE - init_enable_cmd = None - if init_system == consts.INIT_SYSTEMD: - template = SYSTEMD_TEMPLATE - init_enable_cmd = "systemctl enable octavia-keepalived" + # Render and install the network namespace systemd service + util.install_netns_systemd_service() + util.run_systemctl_command( + consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX, False) - # Render and install the network namespace systemd service - util.install_netns_systemd_service() - util.run_systemctl_command( - consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX) - 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 = 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) + # mode 00644 + mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH if not os.path.exists(file_path): with os.fdopen(os.open(file_path, flags, mode), 'w') as text_file: text = template.render( @@ -118,17 +99,13 @@ class Keepalived: util.vrrp_check_script_update(None, consts.AMP_ACTION_START) # Make sure the new service is enabled on boot - if init_enable_cmd is not None: - try: - subprocess.check_output(init_enable_cmd.split(), - stderr=subprocess.STDOUT, - encoding='utf-8') - 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={ - 'message': "Error enabling octavia-keepalived service", - 'details': e.output}, status=500) + try: + util.run_systemctl_command(consts.ENABLE, + consts.KEEPALIVED_SYSTEMD) + except subprocess.CalledProcessError as e: + return webob.Response(json={ + 'message': "Error enabling octavia-keepalived service", + 'details': e.output}, status=500) res = webob.Response(json={'message': 'OK'}, status=200) res.headers['ETag'] = stream.get_md5() @@ -158,14 +135,10 @@ class Keepalived: except OSError: pass - cmd = f"/usr/sbin/service octavia-keepalived {action}" - try: - subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, - encoding='utf-8') + util.run_systemctl_command(action, + consts.KEEPALIVED_SYSTEMD) except subprocess.CalledProcessError as e: - LOG.debug('Failed to %s octavia-keepalived service: %s %s', - action, e, e.output) return webob.Response(json={ 'message': f"Failed to {action} octavia-keepalived service", 'details': e.output}, status=500) diff --git a/octavia/amphorae/backends/agent/api_server/keepalivedlvs.py b/octavia/amphorae/backends/agent/api_server/keepalivedlvs.py index 6dd875a3c1..7e797c9002 100644 --- a/octavia/amphorae/backends/agent/api_server/keepalivedlvs.py +++ b/octavia/amphorae/backends/agent/api_server/keepalivedlvs.py @@ -38,8 +38,6 @@ LOG = logging.getLogger(__name__) j2_env = jinja2.Environment(autoescape=True, loader=jinja2.FileSystemLoader( 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) check_script_file_template = j2_env.get_template( consts.KEEPALIVED_CHECK_SCRIPT) @@ -92,32 +90,18 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase): f.write(b) 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) + template = SYSTEMD_TEMPLATE - if init_system == consts.INIT_SYSTEMD: - template = SYSTEMD_TEMPLATE - - # Render and install the network namespace systemd service - util.install_netns_systemd_service() - util.run_systemctl_command( - consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX) - 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 network namespace systemd service + util.install_netns_systemd_service() + util.run_systemctl_command( + consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX, False) # Render and install the keepalivedlvs init script - if init_system == consts.INIT_SYSTEMD: - # mode 00644 - 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) + # mode 00644 + mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH keepalived_pid, vrrp_pid, check_pid = util.keepalived_lvs_pids_path( listener_id) if not os.path.exists(file_path): @@ -136,23 +120,15 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase): text_file.write(text) # Make sure the keepalivedlvs service is enabled on boot - if init_system == consts.INIT_SYSTEMD: + try: 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: - subprocess.check_output(init_enable_cmd.split(), - stderr=subprocess.STDOUT, - encoding='utf-8') - except subprocess.CalledProcessError as e: - LOG.debug('Failed to enable ' - 'octavia-keepalivedlvs service: ' - '%(err)s', {'err': str(e)}) - return webob.Response(json={ - 'message': ("Error enabling " - "octavia-keepalivedlvs service"), - 'details': e.output}, status=500) + consts.ENABLE, + consts.KEEPALIVEDLVS_SYSTEMD % listener_id) + except subprocess.CalledProcessError as e: + return webob.Response(json={ + 'message': ("Error enabling " + "octavia-keepalivedlvs service"), + 'details': e.output}, status=500) if NEED_CHECK: # inject the check script for keepalived process @@ -166,7 +142,6 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase): 'w') as script_file: text = check_script_file_template.render( consts=consts, - init_system=init_system, keepalived_lvs_pid_dir=util.keepalived_lvs_dir() ) script_file.write(text) @@ -217,15 +192,10 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase): if consts.OFFLINE == self._check_lvs_listener_status(listener_id): action = consts.AMP_ACTION_START - cmd = ("/usr/sbin/service " - f"octavia-keepalivedlvs-{listener_id} {action}") - try: - subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, - encoding='utf-8') + util.run_systemctl_command( + action, consts.KEEPALIVEDLVS_SYSTEMD % listener_id) except subprocess.CalledProcessError as e: - LOG.debug('Failed to %s keepalivedlvs listener %s', - listener_id + ' : ' + action, e) return webob.Response(json={ 'message': (f"Failed to {action} keepalivedlvs listener " f"{listener_id}"), @@ -280,11 +250,10 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase): if os.path.exists(keepalived_pid) and os.path.exists( os.path.join('/proc', util.get_keepalivedlvs_pid(listener_id))): - cmd = (f"/usr/sbin/service " - f"octavia-keepalivedlvs-{listener_id} stop") try: - subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, - encoding='utf-8') + util.run_systemctl_command( + consts.STOP, + consts.KEEPALIVEDLVS_SYSTEMD % listener_id) except subprocess.CalledProcessError as e: LOG.error("Failed to stop keepalivedlvs service: %s", e) return webob.Response(json={ @@ -301,31 +270,21 @@ class KeepalivedLvs(lvs_listener_base.LvsListenerApiServerBase): os.remove(pid) # disable the service - init_system = util.get_os_init_system() - init_path = util.keepalived_lvs_init_path(init_system, listener_id) + init_path = util.keepalived_lvs_init_path(listener_id) - if init_system == consts.INIT_SYSTEMD: + try: 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: - subprocess.check_output(init_disable_cmd.split(), - stderr=subprocess.STDOUT, - encoding='utf-8') - except subprocess.CalledProcessError as e: - LOG.error("Failed to disable " - "octavia-keepalivedlvs-%(list)s service: " - "%(err)s", {'list': listener_id, 'err': str(e)}) - return webob.Response(json={ - 'message': ( - f"Error disabling octavia-keepalivedlvs-{listener_id} " - f"service"), - 'details': e.output}, status=500) - - elif init_system != consts.INIT_UPSTART: - raise util.UnknownInitError() + consts.DISABLE, + consts.KEEPALIVEDLVS_SYSTEMD % listener_id) + except subprocess.CalledProcessError as e: + LOG.error("Failed to disable " + "octavia-keepalivedlvs-%(list)s service: " + "%(err)s", {'list': listener_id, 'err': str(e)}) + return webob.Response(json={ + 'message': ( + f"Error disabling octavia-keepalivedlvs-{listener_id} " + "service"), + 'details': e.output}, status=500) # delete init script ,config file and log file for that listener if os.path.exists(init_path): diff --git a/octavia/amphorae/backends/agent/api_server/loadbalancer.py b/octavia/amphorae/backends/agent/api_server/loadbalancer.py index f10eec6f46..f3d54e167d 100644 --- a/octavia/amphorae/backends/agent/api_server/loadbalancer.py +++ b/octavia/amphorae/backends/agent/api_server/loadbalancer.py @@ -41,8 +41,6 @@ HAPROXY_QUERY_RETRIES = 5 CONF = cfg.CONF -UPSTART_CONF = 'upstart.conf.j2' -SYSVINIT_CONF = 'sysvinit.conf.j2' SYSTEMD_CONF = 'systemd.conf.j2' JINJA_ENV = jinja2.Environment( @@ -50,8 +48,6 @@ JINJA_ENV = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname( os.path.realpath(__file__) ) + 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) @@ -146,43 +142,16 @@ class Loadbalancer: # file ok - move it os.rename(name, util.config_path(lb_id)) - try: + init_path = util.init_path(lb_id) - init_system = util.get_os_init_system() + template = SYSTEMD_TEMPLATE + # Render and install the network namespace systemd service + util.install_netns_systemd_service() + util.run_systemctl_command( + consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX + '.service', False) - 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 - # Render and install the network namespace systemd service - util.install_netns_systemd_service() - util.run_systemctl_command( - consts.ENABLE, consts.AMP_NETNS_SVC_PREFIX + '.service') - 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 = 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) + # mode 00644 + mode = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH hap_major, hap_minor = haproxy_compatibility.get_haproxy_versions() if not os.path.exists(init_path): @@ -196,9 +165,6 @@ class Loadbalancer: haproxy_state_file=util.state_file_path(lb_id), haproxy_socket=util.haproxy_sock_path(lb_id), 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_nsname=consts.AMPHORA_NAMESPACE, haproxy_major_version=hap_major, @@ -207,21 +173,13 @@ class Loadbalancer: text_file.write(text) # Make sure the new service is enabled on boot - if init_system == consts.INIT_SYSTEMD: + try: util.run_systemctl_command( - consts.ENABLE, f"haproxy-{lb_id}") - elif init_system == consts.INIT_SYSVINIT: - try: - subprocess.check_output(init_enable_cmd.split(), - stderr=subprocess.STDOUT, - encoding='utf-8') - 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={ - 'message': "Error enabling haproxy-{} service".format( - lb_id), 'details': e.output}, status=500) + consts.ENABLE, consts.LOADBALANCER_SYSTEMD % lb_id) + except subprocess.CalledProcessError as e: + return webob.Response(json={ + 'message': "Error enabling octavia-keepalived service", + 'details': e.output}, status=500) res = webob.Response(json={'message': 'OK'}, status=202) res.headers['ETag'] = stream.get_md5() @@ -283,11 +241,9 @@ class Loadbalancer: else 1) saved_exc = None for idx in range(retries): - cmd = f"/usr/sbin/service haproxy-{lb_id} {action}" - try: - subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, - encoding='utf-8') + util.run_systemctl_command( + action, consts.LOADBALANCER_SYSTEMD % lb_id) except subprocess.CalledProcessError as e: # Mitigation for # https://bugs.launchpad.net/octavia/+bug/2054666 @@ -296,11 +252,6 @@ class Loadbalancer: 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 uptime = self._check_haproxy_uptime(lb_id) # If haproxy is not reachable or was restarted more than 15 @@ -314,10 +265,6 @@ class Loadbalancer: "more details.") break 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={ 'message': f"Error {action}ing haproxy", 'details': e.output @@ -358,10 +305,9 @@ class Loadbalancer: # check if that haproxy is still running and if stop it if os.path.exists(util.pid_path(lb_id)) and os.path.exists( os.path.join('/proc', util.get_haproxy_pid(lb_id))): - cmd = f"/usr/sbin/service haproxy-{lb_id} stop" try: - subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT, - encoding='utf-8') + util.run_systemctl_command( + consts.STOP, consts.LOADBALANCER_SYSTEMD % lb_id) except subprocess.CalledProcessError as e: LOG.error("Failed to stop haproxy-%s service: %s %s", lb_id, e, e.output) @@ -390,28 +336,10 @@ class Loadbalancer: pass # disable the service - init_system = util.get_os_init_system() - init_path = util.init_path(lb_id, init_system) + init_path = util.init_path(lb_id) - if init_system == consts.INIT_SYSTEMD: - util.run_systemctl_command( - consts.DISABLE, f"haproxy-{lb_id}") - 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() + util.run_systemctl_command( + consts.DISABLE, consts.LOADBALANCER_SYSTEMD % lb_id, False) # delete the directory + init script for that listener shutil.rmtree(util.haproxy_dir(lb_id)) diff --git a/octavia/amphorae/backends/agent/api_server/templates/keepalived.sysvinit.j2 b/octavia/amphorae/backends/agent/api_server/templates/keepalived.sysvinit.j2 deleted file mode 100644 index 147761a932..0000000000 --- a/octavia/amphorae/backends/agent/api_server/templates/keepalived.sysvinit.j2 +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh -# -# keepalived LVS cluster monitor daemon. -# -# Written by Andres Salomon -# -### 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 diff --git a/octavia/amphorae/backends/agent/api_server/templates/keepalived.upstart.j2 b/octavia/amphorae/backends/agent/api_server/templates/keepalived.upstart.j2 deleted file mode 100644 index 1faf89d2e9..0000000000 --- a/octavia/amphorae/backends/agent/api_server/templates/keepalived.upstart.j2 +++ /dev/null @@ -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 %} diff --git a/octavia/amphorae/backends/agent/api_server/templates/keepalived_lvs_check_script.sh.j2 b/octavia/amphorae/backends/agent/api_server/templates/keepalived_lvs_check_script.sh.j2 index 46d8ef33cc..0c42dd1fc3 100644 --- a/octavia/amphorae/backends/agent/api_server/templates/keepalived_lvs_check_script.sh.j2 +++ b/octavia/amphorae/backends/agent/api_server/templates/keepalived_lvs_check_script.sh.j2 @@ -11,11 +11,7 @@ do pid) echo "Check keepalived pid file: " $file;; *) continue;; esac - {% if init_system == consts.INIT_SYSTEMD %} systemctl status $(basename $file .pid) > /dev/null - {% elif init_system in (consts.INIT_UPSTART, consts.INIT_SYSVINIT) %} - kill -0 `cat $file` - {% endif %} status=$(( $status + $? )) done exit $status diff --git a/octavia/amphorae/backends/agent/api_server/templates/sysvinit.conf.j2 b/octavia/amphorae/backends/agent/api_server/templates/sysvinit.conf.j2 deleted file mode 100644 index f2db01eb48..0000000000 --- a/octavia/amphorae/backends/agent/api_server/templates/sysvinit.conf.j2 +++ /dev/null @@ -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 -: diff --git a/octavia/amphorae/backends/agent/api_server/templates/upstart.conf.j2 b/octavia/amphorae/backends/agent/api_server/templates/upstart.conf.j2 deleted file mode 100644 index c8fcd5c050..0000000000 --- a/octavia/amphorae/backends/agent/api_server/templates/upstart.conf.j2 +++ /dev/null @@ -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 <