From 5f438c1f371ae8e7bf1107199fbf104455febebd Mon Sep 17 00:00:00 2001 From: Pete Birley Date: Thu, 12 Jan 2017 04:19:08 +0000 Subject: [PATCH] Intial commit of Neutron Containers (#1) * Intial commit of Neutron Containers * Update Neutron initial commit in response to feedback * Fix Dockerfile Indentation --- README.md | 60 ++++++++++++++++++++++++- dockerfiles/Dockerfile-centos | 84 +++++++++++++++++++++++++++++++++++ dockerfiles/Dockerfile-debian | 81 +++++++++++++++++++++++++++++++++ dockerfiles/Dockerfile-ubuntu | 81 +++++++++++++++++++++++++++++++++ update.sh | 41 +++++++++++++++++ 5 files changed, 346 insertions(+), 1 deletion(-) create mode 100644 dockerfiles/Dockerfile-centos create mode 100644 dockerfiles/Dockerfile-debian create mode 100644 dockerfiles/Dockerfile-ubuntu create mode 100755 update.sh diff --git a/README.md b/README.md index 044d0fd..928d63b 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# docker-neutron \ No newline at end of file +# OpenStack yaodu/neutron +[![Docker Automated](https://img.shields.io/docker/automated/yaodu/neutron.svg)](https://hub.docker.com/r/yaodu/neutron/) + +Yaodu/neutron is a set of Dockerfiles that builds lightweight deployment agnostic images for OpenStack Neutron. + +Images are built in the Docker Hub automatically on each push to the master branch to provide a continuously updated set of images based on a number of distributions. Additionally, this repo may be cloned and used to build images for OpenStack Neutron either for development purposes or as part of a CI/CD workflow. + + +### Image Layer Info +[![](https://images.microbadger.com/badges/version/yaodu/neutron:latest.svg)](https://microbadger.com/images/yaodu/neutron:latest "yaodu/neutron:latest") [![](https://images.microbadger.com/badges/image/yaodu/neutron:latest.svg)](https://microbadger.com/images/yaodu/neutron:latest "yaodu/neutron:latest") + +[![](https://images.microbadger.com/badges/version/yaodu/neutron:ubuntu.svg)](https://microbadger.com/images/yaodu/neutron:ubuntu "yaodu/neutron:ubuntu") [![](https://images.microbadger.com/badges/image/yaodu/neutron:ubuntu.svg)](https://microbadger.com/images/yaodu/neutron:ubuntu "yaodu/neutron:ubuntu") + +[![](https://images.microbadger.com/badges/version/yaodu/neutron:centos.svg)](https://microbadger.com/images/yaodu/neutron:centos "yaodu/neutron:centos") [![](https://images.microbadger.com/badges/image/yaodu/neutron:centos.svg)](https://microbadger.com/images/yaodu/neutron:centos "yaodu/neutron:centos") + + +## Building locally +It's really easy to build images locally for the distro of your choice. To clone the repo and build run the following: +``` bash +$ git clone https://github.com/yaodu/docker-neutron.git +$ cd ./docker-neutron +$ docker build dockerfiles \ + --file dockerfiles/Dockerfile-debian \ + --tag yaodu/neutron:latest +``` +You can, of course, substitute `debian` with your distro of choice. + +For more advanced building you can use docker build arguments to define: + * The git repo containing the OpenStack project the container should contain, `GIT_REPO` + * The git ref the container should use when building, `GIT_REF` + * The git repo the container should use when building from a git ref, `GIT_REF_REPO` + * The docker image name to use for the base requirements python wheels, `DOCKER_REPO` + * The docker image tag to use for the base requirements python wheels, `DOCKER_TAG` + * If present, rather than using a docker image containing OpenStack requirements a tarball will be used from the defined URL, `WHEELS` + +This makes it really easy to integrate Yaodu images into your development or CI/CD workflow, for example, if you wanted to build an image from [this PS](https://review.openstack.org/#/c/416048/4) you could run: +``` bash +$ docker build dockerfiles \ + --file dockerfiles/Dockerfile-ubuntu \ + --tag mydockernamespace/neutron-testing:416048-3 \ + --build-arg GIT_REPO=http://git.openstack.org/openstack/neutron.git \ + --build-arg GIT_REF_REPO=http://git.openstack.org/openstack/neutron.git \ + --build-arg GIT_REF=refs/changes/48/416048/3 +``` + + +## Customizing +The images should contain all the required assets for running the service. But if you wish or need to customize the `yaodu/neutron` image that's great! We hope to have built the images to make this as easy and flexible as possible. To do this we recommend that you perform any required customisation in a child image using a pattern similar to: + +``` Dockerfile +FROM yaodu/neutron:latest +MAINTAINER you@example.com + +RUN set -x \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + your-awesome-binary-package \ + && rm -rf /var/lib/apt/lists/* +``` diff --git a/dockerfiles/Dockerfile-centos b/dockerfiles/Dockerfile-centos new file mode 100644 index 0000000..aedd045 --- /dev/null +++ b/dockerfiles/Dockerfile-centos @@ -0,0 +1,84 @@ +FROM centos:7 + +ENV PATH=/virtualenv/bin:${PATH} \ + PROJECT=neutron \ + OPENSTACK_RPMS_VERSION=newton +ARG DOCKER_REPO=yaodu/openstack-requirements +ARG DOCKER_TAG=centos +ARG WHEELS +ARG GIT_REPO=https://github.com/openstack/${PROJECT} +ARG GIT_REF +ARG GIT_REF_REPO=https://git.openstack.org/openstack/${PROJECT} + +RUN set -x \ + # NOTE(Pete Birley): CentOS-OpenStack repo is only used for openvswitch + && curl -L https://raw.githubusercontent.com/rdo-infra/centos-release-openstack/${OPENSTACK_RPMS_VERSION}-rdo/CentOS-OpenStack.repo > /etc/yum.repos.d/CentOS-OpenStack.repo \ + && sed -i "s/OPENSTACK_VERSION/${OPENSTACK_RPMS_VERSION}/g" /etc/yum.repos.d/CentOS-OpenStack.repo \ + && sed -i "/\[centos-openstack-${OPENSTACK_RPMS_VERSION}\]/s/.*/&\nincludepkgs=*openvswitch*/" /etc/yum.repos.d/CentOS-OpenStack.repo \ + && curl -L https://raw.githubusercontent.com/rdo-infra/centos-release-openstack/newton-rdo/RPM-GPG-KEY-CentOS-SIG-Cloud > /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Cloud \ + && yum install --setopt=tsflags=nodocs -y \ +# Project specific packages start + bridge-utils \ + conntrack-tools \ + dnsmasq \ + dnsmasq-utils \ + ebtables \ + ipset \ + keepalived \ + sudo \ + openvswitch \ + python \ + uuid \ +# Project specific packages end + && yum install --setopt=tsflags=nodocs -y git \ +# common install start + && if [ -n "$WHEELS" ]; then \ + curl -sSL ${WHEELS} > /tmp/wheels.tar.gz; \ + else \ + TOKEN=$(curl -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKER_REPO}:pull" | \ + python -c "import sys, json; print json.load(sys.stdin)['token']") \ + && BLOB=$(curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/manifests/${DOCKER_TAG} | \ + python -c "import sys, json; print json.load(sys.stdin)['fsLayers'][0]['blobSum']") \ + && curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/blobs/${BLOB} > /tmp/wheels.tar.gz; \ + fi \ + && git clone ${GIT_REPO} /tmp/${PROJECT} \ + && if [ -n "$GIT_REF" ]; then \ + git --git-dir /tmp/${PROJECT}/.git fetch ${GIT_REF_REPO} ${GIT_REF} \ + && git --git-dir /tmp/${PROJECT}/.git checkout FETCH_HEAD; \ + fi \ + && mkdir /tmp/packages \ + && tar xf /tmp/wheels.tar.gz -C /tmp/packages/ --strip-components=2 root/packages \ + && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ + && python get-pip.py \ + && rm get-pip.py \ + && pip install virtualenv \ + && virtualenv /virtualenv \ + && hash -r \ + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt /tmp/${PROJECT} \ + && groupadd -g 42424 ${PROJECT} \ + && useradd -u 42424 -g ${PROJECT} -M -d /var/lib/${PROJECT} -s /usr/sbin/nologin -c "${PROJECT} user" ${PROJECT} \ + && mkdir -p /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \ + && chown ${PROJECT}:${PROJECT} /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \ +# common install end +# Project specific command block start + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt python-memcached pymysql \ +# Setup config file structure + && ( cd /tmp/${PROJECT} && ./tools/generate_config_file_samples.sh ) \ + && mv /tmp/${PROJECT}/etc/neutron.conf.sample /tmp/${PROJECT}/etc/neutron.conf \ + && mv /tmp/${PROJECT}/etc/neutron/* /tmp/${PROJECT}/etc/ \ + && rm -rf /tmp/${PROJECT}/etc/neutron /tmp/${PROJECT}/etc/oslo-config-generator \ + && cp -rfv /tmp/${PROJECT}/etc/* /etc/${PROJECT}/ \ + && chown -R ${PROJECT}:${PROJECT} /etc/${PROJECT} \ + && mkdir -p /usr/share/neutron/rootwrap \ + && chown -R root:root /etc/${PROJECT}/policy.json /etc/${PROJECT}/rootwrap.conf /etc/neutron/rootwrap.d /usr/share/neutron/rootwrap \ +# Setup Neutron RootWrap & sudo + && ln -s /virtualenv/bin/neutron-rootwrap-daemon /usr/bin/neutron-rootwrap-daemon \ + && chmod 0640 /etc/sudoers \ + && echo "neutron ALL = (root) NOPASSWD: /usr/bin/neutron-rootwrap-daemon" >> /etc/sudoers \ + && echo "Defaults!/usr/bin/neutron-rootwrap-daemon !requiretty" >> /etc/sudoers \ + && chmod 0440 /etc/sudoers \ +# Project specific command block end + && yum history -y undo $(yum history list git | tail -2 | head -1 | awk '{ print $1}') \ + && yum clean all \ + && rm -rf /tmp/* /root/.cache \ + && find / -type f \( -name "*.pyc" -o -name "pip" -o -name "easy_install" -o -name "wheel" \) -delete diff --git a/dockerfiles/Dockerfile-debian b/dockerfiles/Dockerfile-debian new file mode 100644 index 0000000..99d05dd --- /dev/null +++ b/dockerfiles/Dockerfile-debian @@ -0,0 +1,81 @@ +FROM debian:jessie + +ENV PATH=/virtualenv/bin:${PATH} \ + PROJECT=neutron +ARG DOCKER_REPO=yaodu/openstack-requirements +ARG DOCKER_TAG=latest +ARG WHEELS +ARG GIT_REPO=https://github.com/openstack/${PROJECT} +ARG GIT_REF +ARG GIT_REF_REPO=https://git.openstack.org/openstack/${PROJECT} + +RUN set -x \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ +# Project specific packages start + bridge-utils \ + conntrack \ + dnsmasq \ + dnsmasq-utils \ + ebtables \ + iproute2 \ + ipset \ + iptables \ + iputils-arping \ + keepalived \ + sudo \ + openvswitch-switch \ + python \ + uuid-runtime \ +# Project specific packages end + && apt-get install -y --no-install-recommends ca-certificates curl git \ +# common install start + && if [ -n "$WHEELS" ]; then \ + curl -sSL ${WHEELS} > /tmp/wheels.tar.gz; \ + else \ + TOKEN=$(curl -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKER_REPO}:pull" | \ + python -c "import sys, json; print json.load(sys.stdin)['token']") \ + && BLOB=$(curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/manifests/${DOCKER_TAG} | \ + python -c "import sys, json; print json.load(sys.stdin)['fsLayers'][0]['blobSum']") \ + && curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/blobs/${BLOB} > /tmp/wheels.tar.gz; \ + fi \ + && git clone ${GIT_REPO} /tmp/${PROJECT} \ + && if [ -n "$GIT_REF" ]; then \ + git --git-dir /tmp/${PROJECT}/.git fetch ${GIT_REF_REPO} ${GIT_REF} \ + && git --git-dir /tmp/${PROJECT}/.git checkout FETCH_HEAD; \ + fi \ + && mkdir /tmp/packages \ + && tar xf /tmp/wheels.tar.gz -C /tmp/packages/ --strip-components=2 root/packages \ + && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ + && python get-pip.py \ + && rm get-pip.py \ + && pip install virtualenv \ + && virtualenv /virtualenv \ + && hash -r \ + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt /tmp/${PROJECT} \ + && groupadd -g 42424 ${PROJECT} \ + && useradd -u 42424 -g ${PROJECT} -M -d /var/lib/${PROJECT} -s /usr/sbin/nologin -c "${PROJECT} user" ${PROJECT} \ + && mkdir -p /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \ + && chown ${PROJECT}:${PROJECT} /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \ +# common install end +# Project specific command block start + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt python-memcached pymysql \ +# Setup config file structure + && ( cd /tmp/${PROJECT} && ./tools/generate_config_file_samples.sh ) \ + && mv /tmp/${PROJECT}/etc/neutron.conf.sample /tmp/${PROJECT}/etc/neutron.conf \ + && mv /tmp/${PROJECT}/etc/neutron/* /tmp/${PROJECT}/etc/ \ + && rm -rf /tmp/${PROJECT}/etc/neutron /tmp/${PROJECT}/etc/oslo-config-generator \ + && cp -rfv /tmp/${PROJECT}/etc/* /etc/${PROJECT}/ \ + && chown -R ${PROJECT}:${PROJECT} /etc/${PROJECT} \ + && mkdir -p /usr/share/neutron/rootwrap \ + && chown -R root:root /etc/${PROJECT}/policy.json /etc/${PROJECT}/rootwrap.conf /etc/neutron/rootwrap.d /usr/share/neutron/rootwrap \ +# Setup Neutron RootWrap & sudo + && ln -s /virtualenv/bin/neutron-rootwrap-daemon /usr/bin/neutron-rootwrap-daemon \ + && chmod 0640 /etc/sudoers \ + && echo "neutron ALL = (root) NOPASSWD: /usr/bin/neutron-rootwrap-daemon" >> /etc/sudoers \ + && echo "Defaults!/usr/bin/neutron-rootwrap-daemon !requiretty" >> /etc/sudoers \ + && chmod 0440 /etc/sudoers \ +# Project specific command block end + && apt-get purge -y --auto-remove ca-certificates curl git \ + && rm -rf /var/lib/apt/lists/* /tmp/* /root/.cache \ + && find / -type f \( -name "*.pyc" -o -name "pip" -o -name "easy_install" -o -name "wheel" \) -delete diff --git a/dockerfiles/Dockerfile-ubuntu b/dockerfiles/Dockerfile-ubuntu new file mode 100644 index 0000000..67a88c2 --- /dev/null +++ b/dockerfiles/Dockerfile-ubuntu @@ -0,0 +1,81 @@ +FROM ubuntu:xenial + +ENV PATH=/virtualenv/bin:${PATH} \ + PROJECT=neutron +ARG DOCKER_REPO=yaodu/openstack-requirements +ARG DOCKER_TAG=ubuntu +ARG WHEELS +ARG GIT_REPO=https://github.com/openstack/${PROJECT} +ARG GIT_REF +ARG GIT_REF_REPO=https://git.openstack.org/openstack/${PROJECT} + +RUN set -x \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ +# Project specific packages start + bridge-utils \ + conntrack \ + dnsmasq \ + dnsmasq-utils \ + ebtables \ + iproute2 \ + ipset \ + iptables \ + iputils-arping \ + keepalived \ + sudo \ + openvswitch-switch \ + python \ + uuid-runtime \ +# Project specific packages end + && apt-get install -y --no-install-recommends ca-certificates curl git \ +# common install start + && if [ -n "$WHEELS" ]; then \ + curl -sSL ${WHEELS} > /tmp/wheels.tar.gz; \ + else \ + TOKEN=$(curl -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKER_REPO}:pull" | \ + python -c "import sys, json; print json.load(sys.stdin)['token']") \ + && BLOB=$(curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/manifests/${DOCKER_TAG} | \ + python -c "import sys, json; print json.load(sys.stdin)['fsLayers'][0]['blobSum']") \ + && curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/blobs/${BLOB} > /tmp/wheels.tar.gz; \ + fi \ + && git clone ${GIT_REPO} /tmp/${PROJECT} \ + && if [ -n "$GIT_REF" ]; then \ + git --git-dir /tmp/${PROJECT}/.git fetch ${GIT_REF_REPO} ${GIT_REF} \ + && git --git-dir /tmp/${PROJECT}/.git checkout FETCH_HEAD; \ + fi \ + && mkdir /tmp/packages \ + && tar xf /tmp/wheels.tar.gz -C /tmp/packages/ --strip-components=2 root/packages \ + && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ + && python get-pip.py \ + && rm get-pip.py \ + && pip install virtualenv \ + && virtualenv /virtualenv \ + && hash -r \ + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt /tmp/${PROJECT} \ + && groupadd -g 42424 ${PROJECT} \ + && useradd -u 42424 -g ${PROJECT} -M -d /var/lib/${PROJECT} -s /usr/sbin/nologin -c "${PROJECT} user" ${PROJECT} \ + && mkdir -p /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \ + && chown ${PROJECT}:${PROJECT} /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \ +# common install end +# Project specific command block start + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt python-memcached pymysql \ +# Setup config file structure + && ( cd /tmp/${PROJECT} && ./tools/generate_config_file_samples.sh ) \ + && mv /tmp/${PROJECT}/etc/neutron.conf.sample /tmp/${PROJECT}/etc/neutron.conf \ + && mv /tmp/${PROJECT}/etc/neutron/* /tmp/${PROJECT}/etc/ \ + && rm -rf /tmp/${PROJECT}/etc/neutron /tmp/${PROJECT}/etc/oslo-config-generator \ + && cp -rfv /tmp/${PROJECT}/etc/* /etc/${PROJECT}/ \ + && chown -R ${PROJECT}:${PROJECT} /etc/${PROJECT} \ + && mkdir -p /usr/share/neutron/rootwrap \ + && chown -R root:root /etc/${PROJECT}/policy.json /etc/${PROJECT}/rootwrap.conf /etc/neutron/rootwrap.d /usr/share/neutron/rootwrap \ +# Setup Neutron RootWrap & sudo + && ln -s /virtualenv/bin/neutron-rootwrap-daemon /usr/bin/neutron-rootwrap-daemon \ + && chmod 0640 /etc/sudoers \ + && echo "neutron ALL = (root) NOPASSWD: /usr/bin/neutron-rootwrap-daemon" >> /etc/sudoers \ + && echo "Defaults!/usr/bin/neutron-rootwrap-daemon !requiretty" >> /etc/sudoers \ + && chmod 0440 /etc/sudoers \ +# Project specific command block end + && apt-get purge -y --auto-remove ca-certificates curl git \ + && rm -rf /var/lib/apt/lists/* /tmp/* /root/.cache \ + && find / -type f \( -name "*.pyc" -o -name "pip" -o -name "easy_install" -o -name "wheel" \) -delete diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..54c61f3 --- /dev/null +++ b/update.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -x +set -e +set -u + +COMMON_INSTALL=$(cat <<'END_HEREDOC' +# common install start + && if [ -n "$WHEELS" ]; then \\\n\ + curl -sSL ${WHEELS} > /tmp/wheels.tar.gz; \\\n\ + else \\\n\ + TOKEN=$(curl -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKER_REPO}:pull" | \\\n\ + python -c "import sys, json; print json.load(sys.stdin)['token']") \\\n\ + && BLOB=$(curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/manifests/${DOCKER_TAG} | \\\n\ + python -c "import sys, json; print json.load(sys.stdin)['fsLayers'][0]['blobSum']") \\\n\ + && curl -sSL -H "Authorization: Bearer ${TOKEN}" https://registry.hub.docker.com/v2/${DOCKER_REPO}/blobs/${BLOB} > /tmp/wheels.tar.gz; \\\n\ + fi \\\n\ + && git clone ${GIT_REPO} /tmp/${PROJECT} \\\n\ + && if [ -n "$GIT_REF" ]; then \\\n\ + git --git-dir /tmp/${PROJECT}/.git fetch ${GIT_REF_REPO} ${GIT_REF} \\\n\ + && git --git-dir /tmp/${PROJECT}/.git checkout FETCH_HEAD; \\\n\ + fi \\\n\ + && mkdir /tmp/packages \\\n\ + && tar xf /tmp/wheels.tar.gz -C /tmp/packages/ --strip-components=2 root/packages \\\n\ + && curl -sSL https://bootstrap.pypa.io/get-pip.py -o get-pip.py \\\n\ + && python get-pip.py \\\n\ + && rm get-pip.py \\\n\ + && pip install virtualenv \\\n\ + && virtualenv /virtualenv \\\n\ + && hash -r \\\n\ + && pip install --no-index --no-compile --find-links /tmp/packages --constraint /tmp/packages/upper-constraints.txt /tmp/${PROJECT} \\\n\ + && groupadd -g 42424 ${PROJECT} \\\n\ + && useradd -u 42424 -g ${PROJECT} -M -d /var/lib/${PROJECT} -s /usr/sbin/nologin -c "${PROJECT} user" ${PROJECT} \\\n\ + && mkdir -p /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \\\n\ + && chown ${PROJECT}:${PROJECT} /etc/${PROJECT} /var/log/${PROJECT} /var/lib/${PROJECT} /var/cache/${PROJECT} \\\ + +END_HEREDOC +) + +for repo in $(ls dockerfiles/Dockerfile-*); do + awk -i inplace -v install="${COMMON_INSTALL}" 'BEGIN {p=1} /^# common install start/ {print install; p=0} /^# common install end/ {p=1} p' ${repo} +done