Split amphora haproxy systemd unit

Move namespace handling to separate unit. This also allows a cleaner
handling of the namespace (creation, status), and namespace operations do
not run in the haproxy context

Force haproxy SELinux context in the main unit, as currently haproxy
runs in ifconfig_t domain. Also depend on the new network namespace unit

Story: 1646125
Task: 5831

Change-Id: Ic8bf097499b00ca32dcb501aadfda59755039194
This commit is contained in:
Bernard Cafarelli 2017-11-10 12:43:58 +01:00
parent 62c398c5cb
commit 87eeba6397
No known key found for this signature in database
GPG Key ID: D148244A3C2462BD
3 changed files with 44 additions and 16 deletions

View File

@ -42,6 +42,7 @@ CONF = cfg.CONF
UPSTART_CONF = 'upstart.conf.j2'
SYSVINIT_CONF = 'sysvinit.conf.j2'
SYSTEMD_CONF = 'systemd.conf.j2'
AMPHORA_NETNS = 'amphora-netns'
JINJA_ENV = jinja2.Environment(
autoescape=True,
@ -180,6 +181,22 @@ class Listener(object):
# mode 00755
mode = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH)
if init_system == consts.INIT_SYSTEMD:
# TODO(bcafarel): implement this for other init systems
# netns handling depends on a separate unit file
netns_path = os.path.join(consts.SYSTEMD_DIR,
AMPHORA_NETNS + '.service')
if not os.path.exists(netns_path):
with os.fdopen(os.open(netns_path, flags, mode),
'w') as text_file:
text = JINJA_ENV.get_template(AMPHORA_NETNS +
'.systemd.j2').render(
amphora_nsname=consts.AMPHORA_NAMESPACE,
HasIFUPAll=self._osutils.has_ifup_all()
)
text_file.write(text)
if not os.path.exists(init_path):
with os.fdopen(os.open(init_path, flags, mode), 'w') as text_file:
@ -192,6 +209,7 @@ class Listener(object):
respawn_count=util.CONF.haproxy_amphora.respawn_count,
respawn_interval=(util.CONF.haproxy_amphora.
respawn_interval),
amphora_netns=AMPHORA_NETNS,
amphora_nsname=consts.AMPHORA_NAMESPACE,
HasIFUPAll=self._osutils.has_ifup_all()
)

View File

@ -0,0 +1,22 @@
[Unit]
Description=Configure {{ amphora_nsname }} network namespace
StopWhenUnneeded=true
[Service]
Type=oneshot
RemainAfterExit=yes
# Re-add the namespace
ExecStart=-/sbin/ip netns add {{ amphora_nsname }}
# Load the system sysctl into the new namespace
ExecStart=-/sbin/ip netns exec {{ amphora_nsname }} sysctl --system
# We need the plugged_interfaces file sorted to join the host interfaces
ExecStart=-/bin/sh -c '/usr/bin/sort -k 1 /var/lib/octavia/plugged_interfaces > /var/lib/octavia/plugged_interfaces.sorted'
# Assign the interfaces into the namespace with the appropriate name
ExecStart=-/bin/sh -c '/sbin/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"")}\''
# Bring up all of the namespace interfaces
{%- if HasIFUPAll %}
ExecStart=-/sbin/ip netns exec {{ amphora_nsname }} ifup -a
{%- else %}
ExecStart=-/bin/awk '{system("/sbin/ip netns exec {{ amphora_nsname }} ifup " $2)}' /var/lib/octavia/plugged_interfaces
{%- endif %}

View File

@ -2,28 +2,16 @@
Description=HAProxy Load Balancer
Documentation=man:haproxy(1)
Documentation=file:/usr/share/doc/haproxy/configuration.txt.gz
After=network.target syslog.service
After=network.target syslog.service {{ amphora_netns }}.service
Before=octavia-keepalived.service
Wants=syslog.service
Requires={{ amphora_netns }}.service
[Service]
# Force context as we start haproxy under "ip netns exec"
SELinuxContext=system_u:system_r:haproxy_t:s0
EnvironmentFile=-/etc/default/haproxy
ExecStartPre=/usr/sbin/haproxy -f {{ haproxy_cfg }} -f {{ haproxy_user_group_cfg }} -c -q
# Re-add the namespace
ExecStartPre=-/sbin/ip netns add {{ amphora_nsname }}
# Load the system sysctl into the new namespace
ExecStartPre=-/sbin/ip netns exec {{ amphora_nsname }} sysctl --system
# We need the plugged_interfaces file sorted to join the host interfaces
ExecStartPre=-/bin/sh -c '/usr/bin/sort -k 1 /var/lib/octavia/plugged_interfaces > /var/lib/octavia/plugged_interfaces.sorted'
# Assign the interfaces into the namespace with the appropriate name
ExecStartPre=-/bin/sh -c '/sbin/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"")}\''
# Bring up all of the namespace interfaces
{%- if HasIFUPAll %}
ExecStartPre=-/sbin/ip netns exec {{ amphora_nsname }} ifup -a
{%- else %}
ExecStartPre=-/bin/awk '{system("/sbin/ip netns exec {{ amphora_nsname }} ifup " $2)}' /var/lib/octavia/plugged_interfaces
{%- endif %}
#
ExecStart=/sbin/ip netns exec {{ amphora_nsname }} /usr/sbin/haproxy-systemd-wrapper -f {{ haproxy_cfg }} -f {{ haproxy_user_group_cfg }} -p {{ haproxy_pid }} -L {{ peer_name }} $EXTRAOPTS
ExecReload=/usr/sbin/haproxy -c -f {{ haproxy_cfg }} -f {{ haproxy_user_group_cfg }} -L {{ peer_name }}
ExecReload=/bin/kill -USR2 $MAINPID