From 201d2be686f4bcb8b95265d5615ae5006b6a1a40 Mon Sep 17 00:00:00 2001 From: Max Erenberg Date: Sun, 3 Dec 2023 21:46:36 -0500 Subject: [PATCH] create persistent Docker images for dev --- .drone/auth1-setup.sh | 194 ++++++++++-------- .drone/coffee-setup.sh | 57 ++--- .drone/common.sh | 177 ++++++++-------- .drone/mail-setup.sh | 37 ++-- .drone/phosphoric-acid-setup.sh | 57 +++-- .githooks/pre-commit | 2 +- README.md | 24 ++- docker-compose.yml | 32 ++- docker-entrypoint.sh | 19 +- scripts/build-all-images.sh | 49 +++++ clear_cache.sh => scripts/clear_cache.sh | 0 scripts/delete-all-images.sh | 16 ++ .../git-hook-install.sh | 0 lint-docker.sh => scripts/lint-docker.sh | 0 14 files changed, 410 insertions(+), 254 deletions(-) create mode 100755 scripts/build-all-images.sh rename clear_cache.sh => scripts/clear_cache.sh (100%) create mode 100755 scripts/delete-all-images.sh rename git-hook-install.sh => scripts/git-hook-install.sh (100%) rename lint-docker.sh => scripts/lint-docker.sh (100%) diff --git a/.drone/auth1-setup.sh b/.drone/auth1-setup.sh index a278e82..cf7c45b 100755 --- a/.drone/auth1-setup.sh +++ b/.drone/auth1-setup.sh @@ -4,102 +4,128 @@ set -ex . .drone/common.sh -# set FQDN in /etc/hosts -add_fqdn_to_hosts $(get_ip_addr $(hostname)) auth1 - -if [ -n "$CI" ]; then - # I'm not sure why, but we also need to remove the hosts entry for the - # container's real hostname, otherwise slapd only looks for the principal - # ldap/ (this is with the sasl-host option) - sed -E "/\\b$(hostname)\\b/d" /etc/hosts > /tmp/hosts - cat /tmp/hosts > /etc/hosts - rm /tmp/hosts -fi - -apt install -y psmisc - # If we don't do this then OpenLDAP uses a lot of RAM ulimit -n 1024 -# LDAP -apt install -y --no-install-recommends slapd ldap-utils libnss-ldapd sudo-ldap -# `service slapd stop` doesn't seem to work -killall slapd || true -service nslcd stop || true -rm -rf /etc/ldap/slapd.d -rm /var/lib/ldap/* -cp .drone/slapd.conf /etc/ldap/slapd.conf -cp .drone/ldap.conf /etc/ldap/ldap.conf -cp /usr/share/doc/sudo-ldap/schema.OpenLDAP /etc/ldap/schema/sudo.schema -cp .drone/rfc2307bis.schema /etc/ldap/schema/ -cp .drone/csc.schema /etc/ldap/schema/ -chown -R openldap:openldap /etc/ldap/schema/ /var/lib/ldap/ /etc/ldap/ -sleep 0.5 && service slapd start -grep -Eq '^map group member uniqueMember$' /etc/nslcd.conf || \ - echo 'map group member uniqueMember' >> /etc/nslcd.conf -sed -E -i 's/^uri .*$/uri ldap:\/\/auth1.csclub.internal/' /etc/nslcd.conf -sed -E -i 's/^base .*$/base dc=csclub,dc=internal/' /etc/nslcd.conf -cp .drone/nsswitch.conf /etc/nsswitch.conf -service nslcd start -ldapadd -c -f .drone/data.ldif -Y EXTERNAL -H ldapi:/// -if [ -z "$CI" ]; then - ldapadd -c -f .drone/uwldap_data.ldif -Y EXTERNAL -H ldapi:/// || true - # setup ldapvi for convenience - apt install -y vim ldapvi - echo 'export EDITOR=vim' >> /root/.bashrc - echo 'alias ldapvi="ldapvi -Y EXTERNAL -h ldapi:///"' >> /root/.bashrc -fi +CONTAINER__fix_hosts() { + add_fqdn_to_hosts $(get_ip_addr $(hostname)) auth1 + if [ -n "$CI" ]; then + # I'm not sure why, but we also need to remove the hosts entry for the + # container's real hostname, otherwise slapd only looks for the principal + # ldap/ (this is with the sasl-host option) + sed -E "/\\b$(hostname)\\b/d" /etc/hosts > /tmp/hosts + cat /tmp/hosts > /etc/hosts + rm /tmp/hosts + fi +} -# KERBEROS -apt install -y krb5-admin-server krb5-user libpam-krb5 libsasl2-modules-gssapi-mit sasl2-bin -service krb5-admin-server stop || true -service krb5-kdc stop || true -service saslauthd stop || true -cp .drone/krb5.conf /etc/krb5.conf -cp .drone/kdc.conf /etc/krb5kdc.conf -echo '*/admin *' > /etc/krb5kdc/kadm5.acl -rm -f /var/lib/krb5kdc/* -echo -e 'krb5\nkrb5' | krb5_newrealm -service krb5-kdc start -service krb5-admin-server start -rm -f /etc/krb5.keytab -cat < /etc/dpkg/dpkg.cfg.d/zz-ceo + apt install -y --no-install-recommends slapd ldap-utils libnss-ldapd sudo-ldap + # `service slapd stop` doesn't seem to work + killall slapd || true + service nslcd stop || true + rm -rf /etc/ldap/slapd.d + rm /var/lib/ldap/* + cp .drone/slapd.conf /etc/ldap/slapd.conf + cp .drone/ldap.conf /etc/ldap/ldap.conf + cp /usr/share/doc/sudo-ldap/schema.OpenLDAP /etc/ldap/schema/sudo.schema + cp .drone/rfc2307bis.schema /etc/ldap/schema/ + cp .drone/csc.schema /etc/ldap/schema/ + chown -R openldap:openldap /etc/ldap/schema/ /var/lib/ldap/ /etc/ldap/ + sleep 0.5 && service slapd start + ldapadd -c -f .drone/data.ldif -Y EXTERNAL -H ldapi:/// + if [ -z "$CI" ]; then + ldapadd -c -f .drone/uwldap_data.ldif -Y EXTERNAL -H ldapi:/// || true + # setup ldapvi for convenience + apt install -y --no-install-recommends vim ldapvi + grep -q 'export EDITOR' /root/.bashrc || \ + echo 'export EDITOR=vim' >> /root/.bashrc + grep -q 'alias ldapvi' /root/.bashrc || \ + echo 'alias ldapvi="ldapvi -Y EXTERNAL -h ldapi:///"' >> /root/.bashrc + fi +} + +IMAGE__setup_krb5() { + apt install -y krb5-admin-server krb5-user libpam-krb5 libsasl2-modules-gssapi-mit sasl2-bin + service krb5-admin-server stop || true + service krb5-kdc stop || true + service saslauthd stop || true + cp .drone/krb5.conf /etc/krb5.conf + cp .drone/kdc.conf /etc/krb5kdc.conf + echo '*/admin *' > /etc/krb5kdc/kadm5.acl + rm -f /var/lib/krb5kdc/* + echo -e 'krb5\nkrb5' | krb5_newrealm + service krb5-kdc start + service krb5-admin-server start + rm -f /etc/krb5.keytab + cat < /usr/lib/sasl2/slapd.conf + # Add all of the people defined in data.ldif + for princ in ctdalek exec1 regular1 office1; do + echo "addprinc -pw krb5 $princ" | kadmin.local + done + groupadd keytab || true + chgrp keytab /etc/krb5.keytab + chmod 640 /etc/krb5.keytab + usermod -a -G keytab openldap + usermod -a -G sasl openldap + cat < /usr/lib/sasl2/slapd.conf mech_list: plain login gssapi external pwcheck_method: saslauthd EOF -sed -E -i 's/^START=.*$/START=yes/' /etc/default/saslauthd -sed -E -i 's/^MECHANISMS=.*$/MECHANISMS="kerberos5"/' /etc/default/saslauthd -service saslauthd start -while true; do - killall slapd - sleep 1 - if service slapd start; then - break - fi -done + sed -E -i 's/^START=.*$/START=yes/' /etc/default/saslauthd + sed -E -i 's/^MECHANISMS=.*$/MECHANISMS="kerberos5"/' /etc/default/saslauthd +} -# sync with phosphoric-acid -nc -l 0.0.0.0 9000 & -if [ -z "$CI" ]; then - # sync with coffee - nc -l 0.0.0.0 9001 & - # sync with mail - nc -l 0.0.0.0 9002 & -fi +IMAGE__setup() { + # slapd needs /etc/hosts to be setup properly + CONTAINER__fix_resolv_conf + CONTAINER__fix_hosts + + apt update + # for the 'killall' command + apt install -y psmisc + + IMAGE__setup_ldap + IMAGE__setup_krb5 + IMAGE__common_setup + + service slapd stop || true + killall slapd || true + service krb5-admin-server stop || true + service krb5-kdc stop || true + service saslauthd stop || true +} + +CONTAINER__setup() { + CONTAINER__fix_resolv_conf + CONTAINER__fix_hosts + + local started_slapd=false + for i in {1..5}; do + if service slapd start; then + started_slapd=true + break + fi + sleep 1 + done + if [ $started_slapd != "true" ]; then + echo "Failed to start slapd" >&2 + return 1 + fi + service krb5-admin-server start + service krb5-kdc start + service saslauthd start + service nslcd start + # Let other containers know that we're ready + nc -l -k 0.0.0.0 9000 & +} diff --git a/.drone/coffee-setup.sh b/.drone/coffee-setup.sh index a93d96a..6433b2e 100755 --- a/.drone/coffee-setup.sh +++ b/.drone/coffee-setup.sh @@ -4,25 +4,28 @@ set -ex . .drone/common.sh -# set FQDN in /etc/hosts -add_fqdn_to_hosts $(get_ip_addr $(hostname)) coffee -add_fqdn_to_hosts $(get_ip_addr auth1) auth1 +CONTAINER__fix_hosts() { + add_fqdn_to_hosts $(get_ip_addr $(hostname)) coffee + add_fqdn_to_hosts $(get_ip_addr auth1) auth1 +} -apt install --no-install-recommends -y default-mysql-server postgresql +IMAGE__setup() { + IMAGE__ceod_setup + apt install --no-install-recommends -y default-mysql-server postgresql -# MYSQL -service mariadb stop -sed -E -i 's/^(bind-address[[:space:]]+= 127\.0\.0\.1)$/#\1/' /etc/mysql/mariadb.conf.d/50-server.cnf -service mariadb start -cat < $POSTGRES_DIR/pg_hba.conf + # POSTGRESQL + service postgresql stop + local POSTGRES_DIR=/etc/postgresql/*/main + cat < $POSTGRES_DIR/pg_hba.conf # TYPE DATABASE USER ADDRESS METHOD local all postgres peer host all postgres localhost md5 @@ -36,19 +39,27 @@ local sameuser all peer host sameuser all 0.0.0.0/0 md5 host sameuser all ::/0 md5 EOF -grep -Eq "^listen_addresses = '*'$" $POSTGRES_DIR/postgresql.conf || \ - echo "listen_addresses = '*'" >> $POSTGRES_DIR/postgresql.conf -service postgresql start -su -c " -cat <> $POSTGRES_DIR/postgresql.conf + service postgresql start + su -c " + cat < /tmp/resolv.conf -# remove empty 'search' lines, if we created them -sed -E -i '/^search[[:space:]]*$/d' /tmp/resolv.conf -# also remove the 'rotate' option, since this can cause the Docker DNS server -# to be circumvented -sed -E -i '/^options.*\brotate/d' /tmp/resolv.conf -cp /tmp/resolv.conf /etc/resolv.conf -rm /tmp/resolv.conf - -# normally systemd creates /run/ceod for us -mkdir -p /run/ceod - -# mock out systemctl -ln -sf /bin/true /usr/local/bin/systemctl -# mock out acme.sh -mkdir -p /root/.acme.sh -ln -sf /bin/true /root/.acme.sh/acme.sh -# mock out kubectl -cp .drone/mock_kubectl /usr/local/bin/kubectl -chmod +x /usr/local/bin/kubectl -# add k8s authority certificate -mkdir -p /etc/csc -cp .drone/k8s-authority.crt /etc/csc/k8s-authority.crt -# openssl is actually already present in the python Docker image, -# so we don't need to mock it out - -# netcat is used for synchronization between the containers export DEBIAN_FRONTEND=noninteractive -apt update -apt install -y netcat-openbsd -if [ "$(hostname)" != auth1 ]; then - # ceod uses Augeas, which is not installed by default in the Python - # Docker container - apt install -y libaugeas0 -fi -get_ip_addr() { - getent hosts $1 | cut -d' ' -f1 -} - -add_fqdn_to_hosts() { - ip_addr=$1 - hostname=$2 - sed -E "/${ip_addr}.*\\b${hostname}\\b/d" /etc/hosts > /tmp/hosts - cp /tmp/hosts /etc/hosts - rm /tmp/hosts - echo "$ip_addr $hostname.csclub.internal $hostname" >> /etc/hosts -} - -sync_with() { - host=$1 - port=9000 - if [ $# -eq 2 ]; then - port=$2 - fi - synced=false - # give it 20 minutes (can be slow if you're using e.g. NFS or Ceph) - for i in {1..240}; do - if nc -vz $host $port ; then - synced=true - break - fi - sleep 5 - done - test $synced = true -} - -auth_setup() { - hostname=$1 +# The IMAGE__ functions should be called when building the image. +# The CONTAINER__ functions should be called when running an instance of the +# image in a container. +IMAGE__auth_setup() { # LDAP apt install -y --no-install-recommends libnss-ldapd service nslcd stop || true @@ -86,28 +19,98 @@ auth_setup() { # KERBEROS apt install -y krb5-user libpam-krb5 libsasl2-modules-gssapi-mit cp .drone/krb5.conf /etc/krb5.conf +} - if [ $hostname = phosphoric-acid ]; then - sync_port=9000 - elif [ $hostname = coffee ]; then - sync_port=9001 - else - sync_port=9002 - fi - sync_with auth1 $sync_port +IMAGE__common_setup() { + apt update + # netcat is used for synchronization between the containers + apt install -y netcat-openbsd + IMAGE__auth_setup +} +IMAGE__ceod_setup() { + IMAGE__common_setup + # ceod uses Augeas, which is not installed by default in the Python + # Docker container + apt install -y libaugeas0 +} + +CONTAINER__fix_resolv_conf() { + # don't resolve container names to *real* CSC machines + sed -E 's/([[:alnum:]-]+\.)*uwaterloo\.ca//g' /etc/resolv.conf > /tmp/resolv.conf + # remove empty 'search' lines, if we created them + sed -E -i '/^search[[:space:]]*$/d' /tmp/resolv.conf + # also remove the 'rotate' option, since this can cause the Docker DNS server + # to be circumvented + sed -E -i '/^options.*\brotate/d' /tmp/resolv.conf + # we can't replace /etc/resolv.conf using 'mv' because it's mounted into the container + cp /tmp/resolv.conf /etc/resolv.conf + rm /tmp/resolv.conf +} + +CONTAINER__auth_setup() { + local hostname=$1 + sync_with auth1 + service nslcd start rm -f /etc/krb5.keytab cat < /tmp/hosts + # we can't replace /etc/hosts using 'mv' because it's mounted into the container + cp /tmp/hosts /etc/hosts + rm /tmp/hosts + echo "$ip_addr $hostname.csclub.internal $hostname" >> /etc/hosts +} + +sync_with() { + local host=$1 + local port=9000 + local synced=false + # give it 20 minutes (can be slow if you're using e.g. NFS or Ceph) + for i in {1..240}; do + if nc -vz $host $port ; then + synced=true + break + fi + sleep 5 + done + test $synced = true } diff --git a/.drone/mail-setup.sh b/.drone/mail-setup.sh index cbb0b78..00425be 100755 --- a/.drone/mail-setup.sh +++ b/.drone/mail-setup.sh @@ -4,20 +4,27 @@ set -ex . .drone/common.sh -# set FQDN in /etc/hosts -add_fqdn_to_hosts $(get_ip_addr $(hostname)) mail -add_fqdn_to_hosts $(get_ip_addr auth1) auth1 +CONTAINER__fix_hosts() { + add_fqdn_to_hosts $(get_ip_addr $(hostname)) mail + add_fqdn_to_hosts $(get_ip_addr auth1) auth1 +} -. venv/bin/activate -python -m tests.MockMailmanServer & -python -m tests.MockSMTPServer & -python -m tests.MockCloudStackServer & -python -m tests.MockHarborServer & +IMAGE__setup() { + IMAGE__ceod_setup +} -auth_setup mail - -# for the VHostManager -mkdir -p /run/ceod/member-vhosts - -# sync with phosphoric-acid -nc -l 0.0.0.0 9000 & +CONTAINER__setup() { + CONTAINER__fix_resolv_conf + CONTAINER__fix_hosts + CONTAINER__ceod_setup + CONTAINER__auth_setup mail + # for the VHostManager + mkdir -p /run/ceod/member-vhosts + # mock services + venv/bin/python -m tests.MockMailmanServer & + venv/bin/python -m tests.MockSMTPServer & + venv/bin/python -m tests.MockCloudStackServer & + venv/bin/python -m tests.MockHarborServer & + # sync with phosphoric-acid + nc -l -k 0.0.0.0 9000 & +} diff --git a/.drone/phosphoric-acid-setup.sh b/.drone/phosphoric-acid-setup.sh index c862258..11a7308 100755 --- a/.drone/phosphoric-acid-setup.sh +++ b/.drone/phosphoric-acid-setup.sh @@ -4,29 +4,42 @@ set -ex . .drone/common.sh -# set FQDN in /etc/hosts -add_fqdn_to_hosts "$(get_ip_addr $(hostname))" phosphoric-acid -add_fqdn_to_hosts "$(get_ip_addr auth1)" auth1 -add_fqdn_to_hosts "$(get_ip_addr coffee)" coffee -# mail container doesn't run in CI -if [ -z "$CI" ]; then - add_fqdn_to_hosts $(get_ip_addr mail) mail -fi +CONTAINER__fix_hosts() { + add_fqdn_to_hosts "$(get_ip_addr $(hostname))" phosphoric-acid + add_fqdn_to_hosts "$(get_ip_addr auth1)" auth1 + add_fqdn_to_hosts "$(get_ip_addr coffee)" coffee + # mail container doesn't run in CI + if [ -z "$CI" ]; then + add_fqdn_to_hosts $(get_ip_addr mail) mail + fi +} -auth_setup phosphoric-acid +CONTAINER__setup_userdirs() { + # initialize the skel directory + shopt -s dotglob + mkdir -p /users/skel + cp /etc/skel/* /users/skel/ -# initialize the skel directory -shopt -s dotglob -mkdir -p /users/skel -cp /etc/skel/* /users/skel/ + # create directories for users + for user in ctdalek regular1 exec1; do + mkdir -p /users/$user + chown $user:$user /users/$user + done +} -# create directories for users -for user in ctdalek regular1 exec1; do - mkdir -p /users/$user - chown $user:$user /users/$user -done +IMAGE__setup() { + IMAGE__ceod_setup +} -sync_with coffee -if [ -z "$CI" ]; then - sync_with mail -fi +CONTAINER__setup() { + CONTAINER__fix_resolv_conf + CONTAINER__fix_hosts + CONTAINER__ceod_setup + CONTAINER__auth_setup phosphoric-acid + CONTAINER__setup_userdirs + echo "ktadd ceod/admin" | kadmin -p sysadmin/admin -w krb5 + sync_with coffee + if [ -z "$CI" ]; then + sync_with mail + fi +} diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 67afa1e..1502f34 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -1,5 +1,5 @@ #!/bin/bash -docker run --rm -v "$PWD:$PWD:z" -w "$PWD" python:3.9-bullseye sh -c './lint-docker.sh' +docker run --rm -v "$PWD:$PWD:z" -w "$PWD" python:3.9-bullseye scripts/lint-docker.sh exit $? diff --git a/README.md b/README.md index 62af1fa..bfb7942 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,29 @@ overview of its architecture. The API documentation is available as a plain HTML file in [docs/redoc-static.html](docs/redoc-static.html). ## Development -### Docker +### Podman If you are not modifying code related to email or Mailman, then you may use -Docker containers instead, which are much easier to work with than the VM. +Podman containers instead, which are much easier to work with than the VM. -First, make sure you create the virtualenv: +If you are using Podman, make sure to set the `DOCKER_HOST` environment variable +if you have not done so already: +```bash +# Add the following to e.g. your ~/.bashrc +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock +``` +The Podman socket also needs to be running: +```bash +# Enabled by default on Debian, but not on Fedora +systemctl --user enable --now podman.socket +``` + +First, create the container images: ```sh -docker run --rm -v "$PWD:$PWD:z" -w "$PWD" python:3.9-bullseye sh -c 'apt update && apt install -y libaugeas0 && python -m venv venv && . venv/bin/activate && pip install -r requirements.txt -r dev-requirements.txt' +scripts/build-all-images.sh ``` Then bring up the containers: ```sh -docker-compose up -d # or without -d to run in the foreground +docker-compose up -d ``` This will create some containers with the bare minimum necessary for ceod to run, and start ceod on each of phosphoric-acid, mail, and coffee container. @@ -188,7 +200,7 @@ flask run -h 0.0.0.0 -p 9987 ``` Sometimes changes you make in the source code don't show up while Flask -is running. Stop the flask app (Ctrl-C), run `clear_cache.sh`, then +is running. Stop the flask app (Ctrl-C), run `scripts/clear_cache.sh`, then restart the app. ## Interacting with the application diff --git a/docker-compose.yml b/docker-compose.yml index ef0c81e..d985398 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,41 +1,51 @@ version: "3.6" x-common: &common - image: python:3.9-bullseye + image: ceo-generic:bullseye volumes: - - .:$PWD:z + - ceo-venv:/app/venv:ro + - ./.drone:/app/.drone:ro + - ./docker-entrypoint.sh:/app/docker-entrypoint.sh:ro + - ./ceo:/app/ceo:ro + - ./ceo_common:/app/ceo_common:ro + - ./ceod:/app/ceod:ro + - ./tests:/app/tests:ro security_opt: - label:disable + working_dir: /app + entrypoint: + - ./docker-entrypoint.sh + +x-ceod-common: &ceod-common + <<: *common environment: FLASK_APP: ceod.api FLASK_DEBUG: "true" - working_dir: $PWD - entrypoint: - - ./docker-entrypoint.sh services: auth1: <<: *common - image: debian:bullseye + image: ceo-auth1:bullseye hostname: auth1 command: auth1 coffee: - <<: *common + <<: *ceod-common + image: ceo-coffee:bullseye command: coffee hostname: coffee depends_on: - auth1 mail: - <<: *common + <<: *ceod-common command: mail hostname: mail depends_on: - auth1 phosphoric-acid: - <<: *common + <<: *ceod-common command: phosphoric-acid hostname: phosphoric-acid depends_on: @@ -43,4 +53,8 @@ services: - coffee - mail +volumes: + ceo-venv: + external: true + # vim: expandtab sw=2 ts=2 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 9f19ecb..bd4db93 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,16 +1,21 @@ -#!/bin/sh -e +#!/bin/bash -if ! [ -d venv ]; then - echo "You need to create the virtualenv first!" >&2 +set -ex + +if [ $# -ne 1 ]; then + echo "Usage: $0 " >&2 exit 1 fi - host="$1" -[ -x ".drone/$host-setup.sh" ] && ".drone/$host-setup.sh" +if ! [ -d venv ]; then + echo "You need to mount the virtualenv" >&2 + exit 1 +fi +. .drone/$host-setup.sh +CONTAINER__setup if [ "$host" = auth1 ]; then exec sleep infinity else - . venv/bin/activate - exec .drone/supervise.sh flask run -h 0.0.0.0 -p 9987 + exec .drone/supervise.sh venv/bin/flask run -h 0.0.0.0 -p 9987 fi diff --git a/scripts/build-all-images.sh b/scripts/build-all-images.sh new file mode 100755 index 0000000..73154bf --- /dev/null +++ b/scripts/build-all-images.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -eux + +SUITE=bullseye +PYTHON_VER=3.9 +DOCKER=docker +if command -v podman >/dev/null; then + DOCKER=podman + export BUILDAH_FORMAT=docker +fi + +build_image() { + local HOST=$1 + local BASE_IMAGE=$2 + local IMAGE=ceo-$HOST:$SUITE + if $DOCKER image exists $IMAGE; then + return + fi + run=". .drone/$HOST-setup.sh && IMAGE__setup" + if [ $HOST = generic ]; then + run=". .drone/phosphoric-acid.sh && IMAGE__setup" + fi + $DOCKER build -t $IMAGE -f - . </dev/null; then + DOCKER=podman +fi + +$DOCKER images --format="{{index .Names 0}}" | \ + grep -E "^(localhost/)?ceo-" | \ + while read name; do $DOCKER rmi $name; done + +if $DOCKER volume exists ceo-venv; then + $DOCKER volume rm ceo-venv +fi diff --git a/git-hook-install.sh b/scripts/git-hook-install.sh similarity index 100% rename from git-hook-install.sh rename to scripts/git-hook-install.sh diff --git a/lint-docker.sh b/scripts/lint-docker.sh similarity index 100% rename from lint-docker.sh rename to scripts/lint-docker.sh