summaryrefslogtreecommitdiffstats
path: root/ansible/docker
diff options
context:
space:
mode:
Diffstat (limited to 'ansible/docker')
-rw-r--r--ansible/docker/.gitignore3
-rw-r--r--ansible/docker/Dockerfile34
-rwxr-xr-xansible/docker/build_ansible_image.sh52
-rwxr-xr-xansible/docker/create_docker_chroot.sh220
-rwxr-xr-xansible/docker/run_chroot.sh465
5 files changed, 774 insertions, 0 deletions
diff --git a/ansible/docker/.gitignore b/ansible/docker/.gitignore
new file mode 100644
index 00000000..7df2d855
--- /dev/null
+++ b/ansible/docker/.gitignore
@@ -0,0 +1,3 @@
+ansible_docker.tar
+ansible_chroot.tgz
+ansible_chroot
diff --git a/ansible/docker/Dockerfile b/ansible/docker/Dockerfile
new file mode 100644
index 00000000..b0172709
--- /dev/null
+++ b/ansible/docker/Dockerfile
@@ -0,0 +1,34 @@
+FROM alpine:3.8
+
+ARG ansible_version=2.6.3
+LABEL ansible_version=$ansible_version vendor=Samsung
+
+# Install Ansible build dependencies
+RUN apk --no-cache update \
+&& apk --no-cache --update add --virtual build-dependencies \
+ gcc \
+ make \
+ musl-dev \
+ libffi-dev \
+ openssl-dev \
+ python3-dev \
+&& apk add --no-cache \
+ python3 \
+ py3-pip \
+ openssh-client \
+ openssl \
+ py3-openssl \
+ openssh \
+ sshpass \
+&& pip3 install --no-cache-dir --upgrade pip \
+&& pip3 install --no-cache-dir \
+ ansible==$ansible_version \
+ jmespath \
+&& apk del build-dependencies && rm -rf /var/cache/apk/*
+
+ENV ANSIBLE_HOST_KEY_CHECKING false
+ENV ANSIBLE_RETRY_FILES_ENABLED false
+
+WORKDIR /ansible
+
+ENTRYPOINT ["ansible-playbook"]
diff --git a/ansible/docker/build_ansible_image.sh b/ansible/docker/build_ansible_image.sh
new file mode 100755
index 00000000..d54ddc43
--- /dev/null
+++ b/ansible/docker/build_ansible_image.sh
@@ -0,0 +1,52 @@
+#! /usr/bin/env bash
+
+# COPYRIGHT NOTICE STARTS HERE
+
+# Copyright 2018 © Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# COPYRIGHT NOTICE ENDS HERE
+
+
+set -e
+
+ansible_version="$1"
+image_name="${2:-ansible:latest}"
+
+script_path=$(readlink -f "$0")
+script_dir=$(dirname "$script_path")
+
+git_commit=$(git rev-parse --revs-only HEAD)
+build_date=$(date -I)
+
+if [ -z "$ansible_version" ]; then
+ docker build "$script_dir" -t "${image_name}" --label "git-commit=$git_commit" --label "build-date=$build_date"
+else
+ docker build "$script_dir" -t "${image_name}" --label "git-commit=$git_commit" --label "build-date=$build_date" --build-arg ansible_version="$ansible_version"
+fi
+
+# Export docker image into chroot and tararchive it. It takes ~40M of space and is packaged together with sw.
+if "${script_dir}"/create_docker_chroot.sh convert "${image_name}" "${script_dir}"/ansible_chroot ; then
+ cd "$script_dir"
+ echo INFO: "Tarring and zipping the chroot directory..." >&2
+ tar -czf ansible_chroot.tgz ansible_chroot
+ rm -rf "${script_dir}"/ansible_chroot
+ echo INFO: "Finished: ${script_dir}/ansible_chroot.tgz" >&2
+ cd -
+else
+ echo ERROR: "I failed to create a chroot environment" >&2
+ exit 1
+fi
+
+exit 0 \ No newline at end of file
diff --git a/ansible/docker/create_docker_chroot.sh b/ansible/docker/create_docker_chroot.sh
new file mode 100755
index 00000000..f8e256da
--- /dev/null
+++ b/ansible/docker/create_docker_chroot.sh
@@ -0,0 +1,220 @@
+#!/bin/sh
+
+# COPYRIGHT NOTICE STARTS HERE
+
+# Copyright 2018 © Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# COPYRIGHT NOTICE ENDS HERE
+
+
+set -e
+
+CMD=$(basename "$0")
+
+help()
+{
+ echo "
+NAME:
+ ${CMD} - create a chroot directory from docker image
+
+DESCRIPTION:
+ It will export docker image into a directory capable of chrooting.
+ It needs and will run these commands (requires docker service):
+ docker create
+ docker export
+
+USAGE:
+ ${CMD} [-h|--help|help]
+ This help
+
+ ${CMD} convert <docker-name> <name-of-directory>
+
+ It will convert docker image into directory - no chroot yet.
+ The name of the docker image must be imported already (not a file):
+ docker image ls
+
+ The directory will be created and so this command will fail if some
+ directory or a file of this name (filepath) already exists!
+ There is another script run_chroot.sh with which you can do chroot
+ on this newly created directory - so it is expected that this
+ directory is kept clean and as it is.
+ If you don't care about this feature (run_chroot.sh) and you know
+ what are you doing, then do necessary mounts and execute:
+ chroot <name-of-directory>/chroot /bin/sh -l
+"
+}
+
+#
+# PLEASE DON'T TOUCH ME
+#
+
+# readme file for run_chroot.sh
+readme()
+{
+ md_codequote='```'
+
+cat > "$CHROOT_METADIR"/README.md <<EOF
+# RUN CHROOT COMMAND
+
+# usage:
+
+${md_codequote}
+run_chroot.sh help
+${md_codequote}
+
+**Don't modify insides of this directory (where this README.md lies).**
+
+The structure is needed as it is.
+
+If you wish to just run chroot by yourself, you can do:
+${md_codequote}
+chroot ./chroot /bin/sh -l
+${md_codequote}
+
+# requirements:
+
+* root privileges
+* docker service
+
+# directory structure:
+${md_codequote}
+ README.md
+ chroot/
+ .overlay
+ .workdir
+ .merged
+${md_codequote}
+EOF
+}
+
+# arg: <docker-name>
+check_docker_image()
+{
+ image="$1"
+ match=$(docker image ls --no-trunc -q "$image" | wc -l)
+
+ case $match in
+ 0)
+ echo ERROR: "Docker image does not exist: ${DOCKER_IMAGE}" >&2
+ exit 1
+ ;;
+ 1)
+ :
+ ;;
+ *)
+ echo ERROR: "Multiple results for this docker name: ${DOCKER_IMAGE}" >&2
+ exit 1
+ ;;
+ esac
+
+ return 0
+}
+
+cleanup()
+{
+ if [ -n "$DOCKER_CONTAINER" ] ; then
+ echo INFO: "Delete the export container: ${DOCKER_CONTAINER}" >&2
+ if ! docker rm "$DOCKER_CONTAINER" > /dev/null ; then
+ echo ERROR: "Failed to delete: ${DOCKER_CONTAINER}" >&2
+ fi
+ fi
+}
+
+on_exit()
+{
+ set +e
+ cleanup
+}
+
+action=nil
+case "$1" in
+ ''|-h|--help|help)
+ help
+ exit 0
+ ;;
+ convert)
+ action=convert
+ DOCKER_IMAGE="$2"
+ CHROOT_METADIR="$3"
+ ;;
+ *)
+ echo ERROR: "Bad usage" >&2
+ help >&2
+ exit 1
+ ;;
+esac
+
+
+case "$action" in
+ ''|nil)
+ echo ERROR: "Nothing to do - missing command" >&2
+ help >&2
+ exit 1
+ ;;
+ convert)
+ if [ -z "$DOCKER_IMAGE" ] || [ -z "$CHROOT_METADIR" ] ; then
+ echo ERROR: "Missing argument" >&2
+ help >&2
+ exit 1
+ fi
+
+ if [ -e "$CHROOT_METADIR" ] ; then
+ echo ERROR: "Filepath already exists: ${CHROOT_METADIR}" >&2
+ echo ERROR: "Please rename it, remove it or use different name" >&2
+ echo ERROR: "I need my working directory empty, thanks" >&2
+ exit 1
+ fi
+
+ # check if docker image is there
+ check_docker_image "$DOCKER_IMAGE"
+
+ # we must be root
+ if [ "$(id -u)" -ne 0 ] ; then
+ echo ERROR: "I need root privileges and you are not root: $(id -nu)" >&2
+ exit 1
+ fi
+
+ # making sure that CHROOT_METADIR is absolute path
+ CHROOT_METADIR=$(readlink -f "$CHROOT_METADIR")
+
+ # set trap
+ trap on_exit INT QUIT TERM EXIT
+
+ # making readme
+ mkdir -p "$CHROOT_METADIR"/
+ readme
+
+ # create container
+ DOCKER_CONTAINER=$(docker create "$DOCKER_IMAGE")
+ if [ -z "$DOCKER_CONTAINER" ] ; then
+ echo ERROR: "I could not create a container from: ${DOCKER_IMAGE}" >&2
+ exit 1
+ fi
+
+ # unpacking of image
+ mkdir -p "$CHROOT_METADIR"/chroot
+ echo INFO: "Export started - it can take a while to finish..." >&2
+ if ! docker export "$DOCKER_CONTAINER" | tar -C "$CHROOT_METADIR"/chroot -xf - ; then
+ echo ERROR: "Unpacking failed - permissions?" >&2
+ exit 1
+ else
+ echo INFO: "Export success: $CHROOT_METADIR/chroot" >&2
+ echo INFO: "Checkout the README file: $CHROOT_METADIR/README.md" >&2
+ fi
+ ;;
+esac
+
+exit 0
+
diff --git a/ansible/docker/run_chroot.sh b/ansible/docker/run_chroot.sh
new file mode 100755
index 00000000..b38c1295
--- /dev/null
+++ b/ansible/docker/run_chroot.sh
@@ -0,0 +1,465 @@
+#!/bin/sh
+
+# COPYRIGHT NOTICE STARTS HERE
+
+# Copyright 2018 © Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# COPYRIGHT NOTICE ENDS HERE
+
+
+set -e
+
+CMD=$(basename "$0")
+UMOUNT_TIMEOUT=120 # 2mins
+
+
+#
+# functions
+#
+
+help()
+{
+ echo "
+NAME:
+ ${CMD} - run command in chrooted directory
+
+DESCRIPTION:
+ It will do necessary steps to be able chroot, optional mounts and it will
+ run commands inside the requested chroot directory.
+
+ It does overlay mount so nothing inside the chroot is modified - if there
+ is no way to do overlay mount it will just do chroot directly - which means
+ that user has power to render chroot useless - beware...
+
+ The chroot is run in it's own namespace for better containerization.
+ Therefore the utility 'unshare' is necessary requirement.
+
+ After exiting the chroot all of those necessary steps are undone.
+
+USAGE:
+ ${CMD} [-h|--help|help]
+ This help
+
+ ${CMD} [OPTIONS] execute <chroot-directory> [<command with args>...]
+
+ It will do some necessary steps after which it will execute chroot
+ command and gives you prompt inside the chroot. When you leave the
+ prompt it will undo those steps.
+ On top of the ordinary chroot it will make overlay, so every change
+ inside the chroot is only temporary and chroot is kept stateless -
+ like inside a docker container. If there is no way to do overlay -
+ ordinary chroot is done.
+ Default command is: /bin/sh -l
+
+ OPTIONS:
+
+ --mount (ro|rw):<src-dir>:<inner-dir>
+ This option will mount 'src-dir' which is full path on the host
+ system into the relative path 'inner-dir' within the chroot
+ directory.
+ It can be mounted as read-only (ro) or read-write (rw).
+ Multiple usage of this argument can be used to create complex
+ hierarchy. Order is significant.
+ For example:
+ --mount ro:/scripts/ANSIBLE_DIR:/ansible \
+ --mount rw:/scripts/ANSIBLE_DIR/app:/ansible/app
+ This will mount directory ansible as read-only into chroot,
+ but it's subdirectory 'app' will be writeable.
+
+ --workdir <inner-dir>
+ This will set working directory (PWD) inside the chroot.
+
+EXAMPLE:
+ ${CMD} --mount ro:/scripts/ansible:ansible \
+ --mount rw:/scripts/ansible/app:ansible/app \
+ --workdir /ansible execute /tmp/ansible_chroot
+ # pwd
+ /ansible
+ # mount
+ overlay on / type overlay ...
+ /dev/disk on /ansible type ext4 (ro,relatime,errors=remount-ro)
+ /dev/disk on /ansible/application type ext4 (rw,relatime,errors=remount-ro)
+ none on /proc type proc (rw,relatime)
+ none on /sys type sysfs (rw,relatime)
+ none on /dev/shm type tmpfs (rw,relatime)
+
+ Directory /ansible inside the chroot is not writable but subdirectory
+ /ansible/app is.
+
+ Rest of the chroot is under overlay and all changes will be lost when
+ chroot command ends. Only changes in app directory persists bacause it
+ was bind mounted as read-write and is not part of overlay.
+
+ Note: as you can see app directory is mounted over itself but read-write.
+"
+}
+
+# arg: <directory>
+is_mounted()
+{
+ mountpoint=$(echo "$1" | sed 's#//*#/#g')
+
+ LANG=C mount | grep -q "^[^[:space:]]\+[[:space:]]\+on[[:space:]]\+${mountpoint}[[:space:]]\+type[[:space:]]\+"
+}
+
+# layers are right to left! First is on the right, top/last is on the left
+do_overlay_mount()
+{
+ if [ -d "$overlay" ] && is_mounted "$overlay" ; then
+ echo ERROR: "The overlay directory is already mounted: $overlay" >&2
+ echo ERROR: "Fix the issue - cannot proceed" >&2
+ exit 1
+ fi
+
+ # prepare dirs
+ rm -rf "$overlay" "$upperdir" "$workdir"
+ mkdir -p "$overlay"
+ mkdir -p "$upperdir"
+ mkdir -p "$workdir"
+
+ # finally overlay mount
+ if ! mount -t overlay --make-rprivate \
+ -o lowerdir="$lowerdir",upperdir="$upperdir",workdir="$workdir" \
+ overlay "$overlay" ;
+ then
+ echo ERROR: "Failed to do overlay mount!" >&2
+ echo ERROR: "Please check that your system supports overlay!" >&2
+ echo NOTE: "Continuing with the ordinary chroot without overlay!"
+
+ CHROOT_DIR="$lowerdir"
+ return 1
+ fi
+
+ CHROOT_DIR="$overlay"
+
+ return 0
+}
+
+cleanup()
+{
+ case "$OVERLAY_MOUNT" in
+ yes)
+ echo INFO: "Umounting overlay..." >&2
+ if ! umount_retry "$CHROOT_DIR" ; then
+ echo ERROR: "Cannot umount chroot: $CHROOT_DIR" >&2
+ return 1
+ fi
+
+ ;;
+ no)
+ echo INFO: "No overlay to umount" >&2
+ ;;
+ esac
+
+ if ! is_mounted "$overlay" ; then
+ echo INFO: "Deleting of temp directories..." >&2
+ rm -rf "$overlay" "$upperdir" "$workdir"
+ else
+ echo ERROR: "Overlay is still mounted: $CHROOT_DIR" >&2
+ echo ERROR: "Cannot delete: $overlay" >&2
+ echo ERROR: "Cannot delete: $upperdir" >&2
+ echo ERROR: "Cannot delete: $workdir" >&2
+ return 1
+ fi
+}
+
+check_external_mounts()
+{
+ echo "$EXTERNAL_MOUNTS" | sed '/^[[:space:]]*$/d' | while read -r mountexpr ; do
+ mount_type=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $1;}')
+ external=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $2;}')
+ internal=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $3;}' | sed -e 's#^/*##' -e 's#//*#/#g')
+
+ case "$mount_type" in
+ ro|rw)
+ :
+ ;;
+ *)
+ echo ERROR: "Wrong mount type (should be 'ro' or 'rw') in: ${mountexpr}" >&2
+ exit 1
+ ;;
+ esac
+
+ if ! [ -d "$external" ] ; then
+ echo ERROR: "Directory for mounting does not exist: ${external}" >&2
+ exit 1
+ fi
+
+ if echo "$internal" | grep -q '^/*$' ; then
+ echo ERROR: "Unacceptable internal path: ${internal}" >&2
+ exit 1
+ fi
+ done
+}
+
+do_external_mounts()
+{
+ echo INFO: "Bind mounting of external mounts..." >&2
+ echo "$EXTERNAL_MOUNTS" | sed '/^[[:space:]]*$/d' | while read -r mountexpr ; do
+ mount_type=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $1;}')
+ external=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $2;}')
+ internal=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $3;}' | sed -e 's#^/*##' -e 's#//*#/#g')
+
+ if is_mounted "${CHROOT_DIR}/${internal}" ; then
+ echo ERROR: "Mountpoint is already mounted: ${CHROOT_DIR}/${internal}" >&2
+ echo ERROR: "Fix the issue - cannot proceed" >&2
+ exit 1
+ fi
+
+ if ! mkdir -p "${CHROOT_DIR}/${internal}" ; then
+ echo ERROR: "Cannot create mountpoint: ${CHROOT_DIR}/${internal}" >&2
+ exit 1
+ fi
+
+ if ! mount --make-rprivate -o bind,${mount_type} "$external" "${CHROOT_DIR}/${internal}" ; then
+ echo ERROR: "Failed to mount: ${external} -> ${internal}" >&2
+ exit 1
+ else
+ echo INFO: "Mount: ${external} -> ${internal}" >&2
+ fi
+ done
+}
+
+# arg: <mountpoint>
+umount_retry()
+{
+ mountpoint=$(echo "$1" | sed 's#//*#/#g')
+ timeout=${UMOUNT_TIMEOUT}
+
+ umount "$mountpoint" 2>/dev/null
+ while is_mounted "$mountpoint" && [ $timeout -gt 0 ] ; do
+ umount "$mountpoint" 2>/dev/null
+ sleep 1
+ timeout=$(( timeout - 1 ))
+ done
+
+ if ! is_mounted "$mountpoint" ; then
+ return 0
+ fi
+
+ return 1
+}
+
+undo_external_mounts()
+{
+ echo INFO: "Umount external mount points..." >&2
+ echo "$EXTERNAL_MOUNTS" | tac | sed '/^[[:space:]]*$/d' | while read -r mountexpr ; do
+ mount_type=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $1;}')
+ external=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $2;}')
+ internal=$(echo "$mountexpr" | awk 'BEGIN{FS=":"}{print $3;}' | sed -e 's#^/*##' -e 's#//*#/#g')
+ if umount_retry "${CHROOT_DIR}/${internal}" ; then
+ echo INFO: "Unmounted: ${CHROOT_DIR}/${internal}" >&2
+ else
+ echo ERROR: "Failed to umount: ${CHROOT_DIR}/${internal}" >&2
+ fi
+ done
+}
+
+install_wrapper()
+{
+ cat > "$CHROOT_DIR"/usr/local/bin/fakeshell.sh <<EOF
+#!/bin/sh
+
+PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+export PATH
+
+gid_tty=\$(getent group | sed -n '/^tty:/p' | cut -d: -f 3)
+
+mount -t proc proc /proc
+mount -t sysfs none /sys
+mount -t tmpfs none /dev
+
+mkdir -p /dev/shm
+mkdir -p /dev/pts
+mount -t devpts -o gid=\${gid_tty},mode=620 none /dev/pts
+
+[ -e /dev/full ] || mknod -m 666 /dev/full c 1 7
+[ -e /dev/ptmx ] || mknod -m 666 /dev/ptmx c 5 2
+[ -e /dev/random ] || mknod -m 644 /dev/random c 1 8
+[ -e /dev/urandom ] || mknod -m 644 /dev/urandom c 1 9
+[ -e /dev/zero ] || mknod -m 666 /dev/zero c 1 5
+[ -e /dev/tty ] || mknod -m 666 /dev/tty c 5 0
+[ -e /dev/console ] || mknod -m 622 /dev/console c 5 1
+[ -e /dev/null ] || mknod -m 666 /dev/null c 1 3
+
+chown root:tty /dev/console
+chown root:tty /dev/ptmx
+chown root:tty /dev/tty
+
+mkdir -p "\$1" || exit 1
+cd "\$1" || exit 1
+shift
+
+exec "\$@"
+
+EOF
+ chmod +x "$CHROOT_DIR"/usr/local/bin/fakeshell.sh
+}
+
+on_exit()
+{
+ set +e
+ echo
+
+ if [ -n "$OVERLAY_MOUNT" ] ; then
+ undo_external_mounts
+ fi
+ cleanup
+}
+
+
+#
+# parse arguments
+#
+
+state=nil
+action=nil
+EXTERNAL_MOUNTS=''
+CHROOT_WORKDIR=''
+CHROOT_METADIR=''
+CHROOT_DIR=''
+COMMAND=''
+while [ -n "$1" ] ; do
+ case "$state" in
+ nil)
+ case "$1" in
+ ''|-h|--help|help)
+ help
+ exit 0
+ ;;
+ --mount)
+ EXTERNAL_MOUNTS=$(printf "%s\n%s\n" "$EXTERNAL_MOUNTS" "${2}")
+ state=next
+ ;;
+ --workdir)
+ if [ -z "$CHROOT_WORKDIR" ] ; then
+ CHROOT_WORKDIR="$2"
+ state=next
+ else
+ echo ERROR: "Multiple working directory argument" >&2
+ help >&2
+ exit 1
+ fi
+ ;;
+ execute)
+ action=execute
+ state=execute
+ ;;
+ *)
+ echo ERROR: "Bad usage" >&2
+ help >&2
+ exit 1
+ ;;
+ esac
+ ;;
+ next)
+ state=nil
+ ;;
+ execute)
+ CHROOT_METADIR="$1"
+ shift
+ break
+ ;;
+ esac
+ shift
+done
+
+
+case "$action" in
+ ''|nil)
+ echo ERROR: "Nothing to do - missing command" >&2
+ help >&2
+ exit 1
+ ;;
+ execute)
+ # firstly do sanity checking ...
+
+ if [ -z "$CHROOT_METADIR" ] ; then
+ echo ERROR: "Missing argument" >&2
+ help >&2
+ exit 1
+ fi
+
+ # making sure that CHROOT_METADIR is absolute path
+ CHROOT_METADIR=$(readlink -f "$CHROOT_METADIR")
+
+ if ! [ -d "$CHROOT_METADIR"/chroot ] ; then
+ echo ERROR: "Filepath does not exist: ${CHROOT_METADIR}/chroot" >&2
+ exit 1
+ fi
+
+ # check external mounts if there are any
+ check_external_mounts
+
+ # check workdir
+ if [ -n "$CHROOT_WORKDIR" ] ; then
+ CHROOT_WORKDIR=$(echo "$CHROOT_WORKDIR" | sed -e 's#^/*##' -e 's#//*#/#g')
+ fi
+
+ # we must be root
+ if [ "$(id -u)" -ne 0 ] ; then
+ echo ERROR: "Need to be root and you are not: $(id -nu)" >&2
+ exit 1
+ fi
+
+ if ! which unshare >/dev/null 2>/dev/null ; then
+ echo ERROR: "'unshare' system command is missing - ABORT" >&2
+ echo INFO: "Try to install 'util-linux' package" >&2
+ exit 1
+ fi
+
+ # ... sanity checking done
+
+ # setup paths
+ lowerdir="$CHROOT_METADIR"/chroot
+ upperdir="$CHROOT_METADIR"/.overlay
+ workdir="$CHROOT_METADIR"/.workdir
+ overlay="$CHROOT_METADIR"/.merged
+
+ # set trap
+ trap on_exit QUIT TERM EXIT
+
+ # mount overlay
+ OVERLAY_MOUNT=''
+ if do_overlay_mount ; then
+ # overlay chroot
+ OVERLAY_MOUNT=yes
+ else
+ # non overlay mount
+ OVERLAY_MOUNT=no
+ fi
+
+ # do the user-specific mounts
+ do_external_mounts
+
+ # I need this wrapper to do some setup inside the chroot...
+ install_wrapper
+
+ # execute chroot
+ # copy resolv.conf
+ cp -a /etc/resolv.conf "$CHROOT_DIR"/etc/resolv.conf
+
+ if [ -n "$1" ] ; then
+ :
+ else
+ set -- /bin/sh -l
+ fi
+ unshare -mfpi --propagation private \
+ chroot "$CHROOT_DIR" /usr/local/bin/fakeshell.sh "${CHROOT_WORKDIR:-/}" "$@"
+ ;;
+esac
+
+exit 0
+