From fb01a659da5c4216ff20007341d789ac9c7df933 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Petr=20Ospal=C3=BD?= 
Date: Mon, 7 Jan 2019 13:28:57 +0100
Subject: [PATCH] Add support for plain files mounting into chroot
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit
In this commit I tried to follow a behaviour of docker. If mounted
path does not exist then it will handle it as a directory - it
creates it and the mountpoint is expected to be a directory also.
If the mounted path is a plain file it will do file bind mounting.
The mountpoint must be a plain file.
Change-Id: Ie8b29442c8ebb8da389ba6c9a152a49d8cf6e9be
Issue-ID: OOM-1575
Signed-off-by: Petr Ospalý 
---
 ansible/docker/run_chroot.sh | 37 ++++++++++++++++++++++++++-----------
 ansible/run_playbook.sh      |  4 ++--
 2 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/ansible/docker/run_chroot.sh b/ansible/docker/run_chroot.sh
index 1ab26373..3359fdcd 100755
--- a/ansible/docker/run_chroot.sh
+++ b/ansible/docker/run_chroot.sh
@@ -192,11 +192,7 @@ check_external_mounts()
                 ;;
         esac
 
-        if ! [ -d "$external" ] ; then
-            echo ERROR: "Directory for mounting does not exist: ${external}" >&2
-            exit 1
-        fi
-
+        # sanity check that the mountpoint is not empty or the root directory itself
         if echo "$internal" | grep -q '^/*$' ; then
             echo ERROR: "Unacceptable internal path: ${internal}" >&2
             exit 1
@@ -218,8 +214,31 @@ do_external_mounts()
             exit 1
         fi
 
-        if ! mkdir -p "${CHROOT_DIR}/${internal}" ; then
-            echo ERROR: "Cannot create mountpoint: ${CHROOT_DIR}/${internal}" >&2
+        # trying to follow the behaviour of docker
+        if ! [ -e "$external" ] || [ -d "$external" ] ; then
+            # external is a dir
+            if ! mkdir -p "$external" ; then
+                echo ERROR: "Cannot create directory: ${external}" >&2
+                exit 1
+            fi
+            if ! mkdir -p "${CHROOT_DIR}/${internal}" ; then
+                echo ERROR: "Cannot create mountpoint: ${CHROOT_DIR}/${internal}" >&2
+                exit 1
+            fi
+        elif [ -f "$external" ] ; then
+            # if external is a file mount it as a file
+            if [ -e "${CHROOT_DIR}/${internal}" ] && ! [ -f "${CHROOT_DIR}/${internal}" ] ; then
+                echo ERROR: "Mounting a file but the mountpoint is not a file: ${CHROOT_DIR}/${internal}" >&2
+                exit 1
+            else
+                if ! touch "${CHROOT_DIR}/${internal}" ; then
+                    echo ERROR: "Cannot create mountpoint: ${CHROOT_DIR}/${internal}" >&2
+                    exit 1
+                fi
+            fi
+        else
+            # anything but a simple file or a directory will fail
+            echo ERROR: "Unsupported mount: ${external} -> ${internal}" >&2
             exit 1
         fi
 
@@ -448,10 +467,6 @@ case "$action" in
         install_wrapper
 
         # execute chroot
-        # copy resolv.conf and hosts file
-        cp -a /etc/resolv.conf "$CHROOT_DIR"/etc/resolv.conf
-        cp -a /etc/hosts "$CHROOT_DIR"/etc/hosts
-
         if [ -n "$1" ] ; then
             :
         else
diff --git a/ansible/run_playbook.sh b/ansible/run_playbook.sh
index 88c86bc3..9a2ca56f 100755
--- a/ansible/run_playbook.sh
+++ b/ansible/run_playbook.sh
@@ -119,13 +119,13 @@ if ! [ -d "$ANSIBLE_CHROOT" ] ; then
 fi
 
 # run chroot
-mkdir -p "$ANSIBLE_DIR"/application
-mkdir -p "$ANSIBLE_DIR"/certs
 "$ANSIBLE_DIR"/docker/run_chroot.sh \
     --mount rw:"${HOME}/.ssh":/root/.ssh \
     --mount ro:"$ANSIBLE_DIR":/ansible \
     --mount rw:"$ANSIBLE_DIR"/application:/ansible/application \
     --mount rw:"$ANSIBLE_DIR"/certs:/certs \
+    --mount ro:/etc/resolv.conf:/etc/resolv.conf \
+    --mount ro:/etc/hosts:/etc/hosts \
     --workdir /ansible \
     execute "$ANSIBLE_CHROOT" ansible-playbook "$@"
 
-- 
2.16.6