Petr Ospalý | c2b0f6d | 2018-12-19 13:08:22 +0100 | [diff] [blame^] | 1 | #!/bin/sh |
| 2 | |
| 3 | # COPYRIGHT NOTICE STARTS HERE |
| 4 | |
| 5 | # Copyright 2018 © Samsung Electronics Co., Ltd. |
| 6 | # |
| 7 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | # you may not use this file except in compliance with the License. |
| 9 | # You may obtain a copy of the License at |
| 10 | # |
| 11 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | # |
| 13 | # Unless required by applicable law or agreed to in writing, software |
| 14 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | # See the License for the specific language governing permissions and |
| 17 | # limitations under the License. |
| 18 | |
| 19 | # COPYRIGHT NOTICE ENDS HERE |
| 20 | |
| 21 | |
| 22 | set -e |
| 23 | |
| 24 | CMD=$(basename "$0") |
| 25 | |
| 26 | help() |
| 27 | { |
| 28 | echo " |
| 29 | NAME: |
| 30 | ${CMD} - create a chroot directory from docker image |
| 31 | |
| 32 | DESCRIPTION: |
| 33 | It will export docker image into a directory capable of chrooting. |
| 34 | It needs and will run these commands (requires docker service): |
| 35 | docker create |
| 36 | docker export |
| 37 | |
| 38 | USAGE: |
| 39 | ${CMD} [-h|--help|help] |
| 40 | This help |
| 41 | |
| 42 | ${CMD} convert <docker-name> <name-of-directory> |
| 43 | |
| 44 | It will convert docker image into directory - no chroot yet. |
| 45 | The name of the docker image must be imported already (not a file): |
| 46 | docker image ls |
| 47 | |
| 48 | The directory will be created and so this command will fail if some |
| 49 | directory or a file of this name (filepath) already exists! |
| 50 | There is another script run_chroot.sh with which you can do chroot |
| 51 | on this newly created directory - so it is expected that this |
| 52 | directory is kept clean and as it is. |
| 53 | If you don't care about this feature (run_chroot.sh) and you know |
| 54 | what are you doing, then do necessary mounts and execute: |
| 55 | chroot <name-of-directory>/chroot /bin/sh -l |
| 56 | " |
| 57 | } |
| 58 | |
| 59 | # |
| 60 | # PLEASE DON'T TOUCH ME |
| 61 | # |
| 62 | |
| 63 | # readme file for run_chroot.sh |
| 64 | readme() |
| 65 | { |
| 66 | md_codequote='```' |
| 67 | |
| 68 | cat > "$CHROOT_METADIR"/README.md <<EOF |
| 69 | # RUN CHROOT COMMAND |
| 70 | |
| 71 | # usage: |
| 72 | |
| 73 | ${md_codequote} |
| 74 | run_chroot.sh help |
| 75 | ${md_codequote} |
| 76 | |
| 77 | **Don't modify insides of this directory (where this README.md lies).** |
| 78 | |
| 79 | The structure is needed as it is. |
| 80 | |
| 81 | If you wish to just run chroot by yourself, you can do: |
| 82 | ${md_codequote} |
| 83 | chroot ./chroot /bin/sh -l |
| 84 | ${md_codequote} |
| 85 | |
| 86 | # requirements: |
| 87 | |
| 88 | * root privileges |
| 89 | * docker service |
| 90 | |
| 91 | # directory structure: |
| 92 | ${md_codequote} |
| 93 | README.md |
| 94 | chroot/ |
| 95 | .overlay |
| 96 | .workdir |
| 97 | .merged |
| 98 | ${md_codequote} |
| 99 | EOF |
| 100 | } |
| 101 | |
| 102 | # arg: <docker-name> |
| 103 | check_docker_image() |
| 104 | { |
| 105 | image="$1" |
| 106 | match=$(docker image ls --no-trunc -q "$image" | wc -l) |
| 107 | |
| 108 | case $match in |
| 109 | 0) |
| 110 | echo ERROR: "Docker image does not exist: ${DOCKER_IMAGE}" >&2 |
| 111 | exit 1 |
| 112 | ;; |
| 113 | 1) |
| 114 | : |
| 115 | ;; |
| 116 | *) |
| 117 | echo ERROR: "Multiple results for this docker name: ${DOCKER_IMAGE}" >&2 |
| 118 | exit 1 |
| 119 | ;; |
| 120 | esac |
| 121 | |
| 122 | return 0 |
| 123 | } |
| 124 | |
| 125 | cleanup() |
| 126 | { |
| 127 | if [ -n "$DOCKER_CONTAINER" ] ; then |
| 128 | echo INFO: "Delete the export container: ${DOCKER_CONTAINER}" >&2 |
| 129 | if ! docker rm "$DOCKER_CONTAINER" > /dev/null ; then |
| 130 | echo ERROR: "Failed to delete: ${DOCKER_CONTAINER}" >&2 |
| 131 | fi |
| 132 | fi |
| 133 | } |
| 134 | |
| 135 | on_exit() |
| 136 | { |
| 137 | set +e |
| 138 | cleanup |
| 139 | } |
| 140 | |
| 141 | action=nil |
| 142 | case "$1" in |
| 143 | ''|-h|--help|help) |
| 144 | help |
| 145 | exit 0 |
| 146 | ;; |
| 147 | convert) |
| 148 | action=convert |
| 149 | DOCKER_IMAGE="$2" |
| 150 | CHROOT_METADIR="$3" |
| 151 | ;; |
| 152 | *) |
| 153 | echo ERROR: "Bad usage" >&2 |
| 154 | help >&2 |
| 155 | exit 1 |
| 156 | ;; |
| 157 | esac |
| 158 | |
| 159 | |
| 160 | case "$action" in |
| 161 | ''|nil) |
| 162 | echo ERROR: "Nothing to do - missing command" >&2 |
| 163 | help >&2 |
| 164 | exit 1 |
| 165 | ;; |
| 166 | convert) |
| 167 | if [ -z "$DOCKER_IMAGE" ] || [ -z "$CHROOT_METADIR" ] ; then |
| 168 | echo ERROR: "Missing argument" >&2 |
| 169 | help >&2 |
| 170 | exit 1 |
| 171 | fi |
| 172 | |
| 173 | if [ -e "$CHROOT_METADIR" ] ; then |
| 174 | echo ERROR: "Filepath already exists: ${CHROOT_METADIR}" >&2 |
| 175 | echo ERROR: "Please rename it, remove it or use different name" >&2 |
| 176 | echo ERROR: "I need my working directory empty, thanks" >&2 |
| 177 | exit 1 |
| 178 | fi |
| 179 | |
| 180 | # check if docker image is there |
| 181 | check_docker_image "$DOCKER_IMAGE" |
| 182 | |
| 183 | # we must be root |
| 184 | if [ "$(id -u)" -ne 0 ] ; then |
| 185 | echo ERROR: "I need root privileges and you are not root: $(id -nu)" >&2 |
| 186 | exit 1 |
| 187 | fi |
| 188 | |
| 189 | # making sure that CHROOT_METADIR is absolute path |
| 190 | CHROOT_METADIR=$(readlink -f "$CHROOT_METADIR") |
| 191 | |
| 192 | # set trap |
| 193 | trap on_exit INT QUIT TERM EXIT |
| 194 | |
| 195 | # making readme |
| 196 | mkdir -p "$CHROOT_METADIR"/ |
| 197 | readme |
| 198 | |
| 199 | # create container |
| 200 | DOCKER_CONTAINER=$(docker create "$DOCKER_IMAGE") |
| 201 | if [ -z "$DOCKER_CONTAINER" ] ; then |
| 202 | echo ERROR: "I could not create a container from: ${DOCKER_IMAGE}" >&2 |
| 203 | exit 1 |
| 204 | fi |
| 205 | |
| 206 | # unpacking of image |
| 207 | mkdir -p "$CHROOT_METADIR"/chroot |
| 208 | echo INFO: "Export started - it can take a while to finish..." >&2 |
| 209 | if ! docker export "$DOCKER_CONTAINER" | tar -C "$CHROOT_METADIR"/chroot -xf - ; then |
| 210 | echo ERROR: "Unpacking failed - permissions?" >&2 |
| 211 | exit 1 |
| 212 | else |
| 213 | echo INFO: "Export success: $CHROOT_METADIR/chroot" >&2 |
| 214 | echo INFO: "Checkout the README file: $CHROOT_METADIR/README.md" >&2 |
| 215 | fi |
| 216 | ;; |
| 217 | esac |
| 218 | |
| 219 | exit 0 |
| 220 | |