diff --git a/docker/neutron/neutron-base/Dockerfile.j2 b/docker/neutron/neutron-base/Dockerfile.j2 index 3d0b748693..b40dbf6485 100644 --- a/docker/neutron/neutron-base/Dockerfile.j2 +++ b/docker/neutron/neutron-base/Dockerfile.j2 @@ -68,6 +68,10 @@ ADD plugins-archive / COPY neutron_sudoers /etc/sudoers.d/kolla_neutron_sudoers COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN mkdir -p /usr/local/lib/neutron-wrappers /usr/local/etc/neutron-wrappers +COPY dnsmasq haproxy keepalived neutron-keepalived-state-change radvd copy-wrappers delete-wrappers /usr/local/lib/neutron-wrappers/ +RUN chmod +x /usr/local/lib/neutron-wrappers/copy-wrappers \ + && chmod +x /usr/local/lib/neutron-wrappers/delete-wrappers RUN ln -s neutron-base-source/* neutron \ && {{ macros.install_pip(neutron_base_pip_packages | customizable("pip_packages")) }} \ diff --git a/docker/neutron/neutron-base/copy-wrappers b/docker/neutron/neutron-base/copy-wrappers new file mode 100644 index 0000000000..e03bdfdf7a --- /dev/null +++ b/docker/neutron/neutron-base/copy-wrappers @@ -0,0 +1,9 @@ +#!/bin/bash +for binary in dnsmasq haproxy keepalived neutron-keepalived-state-change radvd; do + cp /usr/local/lib/neutron-wrappers/${binary} /usr/local/bin/${binary} + chmod +x /usr/local/bin/${binary} +done + +echo "KOLLA_IMAGE=${KOLLA_IMAGE}" > /usr/local/etc/neutron-wrappers/config +echo "KOLLA_NAME=${KOLLA_NAME}" >> /usr/local/etc/neutron-wrappers/config +echo "KOLLA_SERVICE_NAME=${KOLLA_SERVICE_NAME}" >> /usr/local/etc/neutron-wrappers/config diff --git a/docker/neutron/neutron-base/delete-wrappers b/docker/neutron/neutron-base/delete-wrappers new file mode 100644 index 0000000000..239d977f25 --- /dev/null +++ b/docker/neutron/neutron-base/delete-wrappers @@ -0,0 +1,6 @@ +#!/bin/bash +for binary in dnsmasq haproxy keepalived neutron-keepalived-state-change radvd; do + rm -f /usr/local/bin/${binary} +done + +rm -f /usr/local/etc/neutron-wrappers/config diff --git a/docker/neutron/neutron-base/dnsmasq b/docker/neutron/neutron-base/dnsmasq new file mode 100644 index 0000000000..44b73f0b2a --- /dev/null +++ b/docker/neutron/neutron-base/dnsmasq @@ -0,0 +1,45 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_dnsmasq_${NETNS} + +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec ${NETNS} /usr/sbin/dnsmasq -k" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t1 podman" + CMD="/usr/sbin/dnsmasq -k" +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${SERVICE}_dnsmasq_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') + +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla/ \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + $CMD $ARGS diff --git a/docker/neutron/neutron-base/haproxy b/docker/neutron/neutron-base/haproxy new file mode 100644 index 0000000000..43b9ef9d28 --- /dev/null +++ b/docker/neutron/neutron-base/haproxy @@ -0,0 +1,45 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_haproxy_${NETNS} +HAPROXY_CMD='$(if [ -f /usr/sbin/haproxy-systemd-wrapper ]; then echo "/usr/sbin/haproxy -Ds"; else echo "/usr/sbin/haproxy -Ws"; fi)' +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec ${NETNS} "'$HAPROXY' +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman" + CMD='$HAPROXY' +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${KOLLA_NAME}_haproxy_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') + +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + /bin/bash -c "HAPROXY=\"$HAPROXY_CMD\"; exec $CMD $ARGS" diff --git a/docker/neutron/neutron-base/keepalived b/docker/neutron/neutron-base/keepalived new file mode 100644 index 0000000000..34b1afaeaf --- /dev/null +++ b/docker/neutron/neutron-base/keepalived @@ -0,0 +1,47 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_keepalived_${NETNS} + +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec ${NETNS} /usr/sbin/keepalived -n -l -D" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman" + CMD='/usr/sbin/keepalived -n -l -D' +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${KOLLA_SERVICE}_keepalived_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') + +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /lib/modules:/lib/modules:ro \ + -v /sbin/modprobe:/sbin/modprobe:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla/ \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + $CMD $ARGS diff --git a/docker/neutron/neutron-base/neutron-keepalived-state-change b/docker/neutron/neutron-base/neutron-keepalived-state-change new file mode 100644 index 0000000000..0b30d88cf7 --- /dev/null +++ b/docker/neutron/neutron-base/neutron-keepalived-state-change @@ -0,0 +1,40 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_keepalived_${NETNS} +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker exec --detach" + CMD="ip netns exec ${NETNS} /usr/bin/neutron-keepalived-state-change" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman exec" + CMD="/usr/bin/neutron-keepalived-state-change" +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +# The state change daemon only runs as a daemon for the moment so we need to +# run it within an existing container with a sensibly matching lifetime. The +# related keepalived container seems an obvious choice. +container_id=$($CLI ps --filter name=$NAME --format "{{.ID}}") + +if [[ -z $container_id ]]; +then + echo "WARNING: keepalived container is not running." + exit 0 +fi + +$CLI -u root \ + --privileged \ + $NAME \ + $CMD $ARGS diff --git a/docker/neutron/neutron-base/neutron_sudoers b/docker/neutron/neutron-base/neutron_sudoers index 348ff0fbdd..d0de94f0ef 100644 --- a/docker/neutron/neutron-base/neutron_sudoers +++ b/docker/neutron/neutron-base/neutron_sudoers @@ -8,3 +8,4 @@ neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --set iptables /usr neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --auto iptables neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --auto ip6tables +neutron ALL = (root) NOPASSWD: /usr/local/lib/neutron-wrappers/copy-wrappers, /usr/local/lib/neutron-wrappers/delete-wrappers diff --git a/docker/neutron/neutron-base/radvd b/docker/neutron/neutron-base/radvd new file mode 100644 index 0000000000..3f5dd1cfa8 --- /dev/null +++ b/docker/neutron/neutron-base/radvd @@ -0,0 +1,42 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETWORK_ID=$(echo $ARGS| awk '{if (match($0, /(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})/,m)) print m[0] }') +NAME=${KOLLA_NAME}_radvd_${NETWORK_ID} +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec qrouter-${NETWORK_ID} /usr/sbin/radvd -n" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman" + CMD="/usr/sbin/radvd -n" +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${KOLLA_NAME}_radvd_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla/ \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + $CMD $ARGS diff --git a/docker/neutron/neutron-dhcp-agent/extend_start.sh b/docker/neutron/neutron-dhcp-agent/extend_start.sh index 8becf549d9..edaad2a3a8 100644 --- a/docker/neutron/neutron-dhcp-agent/extend_start.sh +++ b/docker/neutron/neutron-dhcp-agent/extend_start.sh @@ -6,4 +6,12 @@ if [[ ! -f "/var/log/kolla/neutron/dnsmasq.log" ]]; then chown neutron:kolla /var/log/kolla/neutron/dnsmasq.log fi +if [[ "${KOLLA_NEUTRON_WRAPPERS:-false}" == "true" ]]; then + echo "Copying neutron agent wrappers to /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/copy-wrappers +else + echo "Removing neutron agent wrappers from /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/delete-wrappers +fi + . /usr/local/bin/kolla_neutron_extend_start diff --git a/docker/neutron/neutron-l3-agent/Dockerfile.j2 b/docker/neutron/neutron-l3-agent/Dockerfile.j2 index 7aed7e2f61..8344026574 100644 --- a/docker/neutron/neutron-l3-agent/Dockerfile.j2 +++ b/docker/neutron/neutron-l3-agent/Dockerfile.j2 @@ -23,6 +23,10 @@ LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" build-date="{{ build {{ macros.install_packages(neutron_l3_agent_packages | customizable("packages")) }} +{{ macros.kolla_patch_sources() }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + {% block neutron_l3_agent_footer %}{% endblock %} {% block footer %}{% endblock %} diff --git a/docker/neutron/neutron-l3-agent/extend_start.sh b/docker/neutron/neutron-l3-agent/extend_start.sh new file mode 100644 index 0000000000..f95c1eda29 --- /dev/null +++ b/docker/neutron/neutron-l3-agent/extend_start.sh @@ -0,0 +1,39 @@ +#!/bin/bash +if [[ ! -d "/var/log/kolla/neutron" ]]; then + mkdir -p /var/log/kolla/neutron +fi +if [[ $(stat -c %a /var/log/kolla/neutron) != "755" ]]; then + chmod 755 /var/log/kolla/neutron +fi + +# NOTE(hrw): from RHEL 9 release notes: +# "Iptables-nft and ipset are now deprecated, which included the utilities, +# iptables, ip6tables, ebtables, and arptables. These are all replaced by the +# nftables framework." +# so no need to even use u-a on RHEL 9 family as there is one provider +# (and there is no u-a for ip6tables so script fails) +if [[ ! ${KOLLA_BASE_DISTRO} =~ centos|rocky ]]; then + if /usr/bin/update-alternatives --display iptables; then + # NOTE(yoctozepto): Kolla-Ansible does not always set KOLLA_LEGACY_IPTABLES; + # the workaround below ensures it gets set to `false` in such cases to fix + # this code under `set -o nounset`. + KOLLA_LEGACY_IPTABLES=${KOLLA_LEGACY_IPTABLES-false} + if [[ $KOLLA_LEGACY_IPTABLES == "true" ]]; then + sudo /usr/bin/update-alternatives --set iptables /usr/sbin/iptables-legacy + sudo /usr/bin/update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy + else + sudo /usr/bin/update-alternatives --auto iptables + sudo /usr/bin/update-alternatives --auto ip6tables + fi + fi +fi + +if [[ "${KOLLA_NEUTRON_WRAPPERS:-false}" == "true" ]]; then + echo "Copying neutron agent wrappers to /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/copy-wrappers +else + echo "Removing neutron agent wrappers from /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/delete-wrappers +fi + +. /usr/local/bin/kolla_neutron_extend_start