File: img-functions

package info (click to toggle)
python-diskimage-builder 3.37.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,572 kB
  • sloc: sh: 7,380; python: 6,444; makefile: 37
file content (225 lines) | stat: -rw-r--r-- 9,483 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# Copyright 2012 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
# 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.

function unmount_image () {
    # Calling sync before helps ensure the mount isn't busy when you unmount it.
    # Previously observing having disk corruption issues; one possibility is
    # qemu-nbd not flushing dirty pages on disconnect?
    # https://bugs.launchpad.net/diskimage-builder/+bug/1214388
    sync

    # unmount from the chroot
    # Don't use TMP_MOUNT_PATH here, it might not have been set.
    unmount_dir "$TMP_BUILD_DIR/mnt"
    if [ -n "$EXTRA_DETACH" ]; then
        $EXTRA_DETACH
    fi
    if [ -n "$EXTRA_UNMOUNT" ]; then
        $EXTRA_UNMOUNT
    fi
}

function trap_cleanup() {
    exitval=$?
    cleanup
    exit $exitval
}

function cleanup () {
    unmount_image
    ${DIB_PYTHON_EXEC} ${_LIB}/dib-block-device.py umount
    cleanup_build_dir
    cleanup_image_dir
}

# Helper function to run a command inside the chroot
function run_in_target () {
    cmd="$@"
    # -E to preserve http_proxy
    ORIG_HOME=$HOME
    export HOME=/root
    # Force an empty TMPDIR inside the chroot. There is no need to use an user
    # defined tmp dir which may not exist in the chroot.
    # Bug: #1330290
    # Force the inclusion of a typical set of dirs in PATH, this is needed for guest
    # distros that have path elements not in the host PATH.
    sudo -E chroot $TMP_MOUNT_PATH env -u TMPDIR -u VIRTUAL_ENV PATH="\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" sh -c "$cmd"
    export HOME=$ORIG_HOME
}

# Helper function to run a directory of scripts inside the chroot
function run_d_in_target () {
    check_element
    # If we can find a directory of hooks to run in the target filesystem, bind
    # mount it into the target and then execute run-parts in a chroot
    if [ -d ${TMP_HOOKS_PATH}/$1.d ] ; then
      sudo mkdir $TMP_MOUNT_PATH/tmp/in_target.d
      # Copy dib-run-parts to be visible inside chroot.  Note we leave
      # this here because in the future we might like to use a
      # different in-chroot runner that doesn't rely on the chroot
      # having bash/glibc/etc (containers, micro-images, etc).
      sudo cp ${DIB_RUN_PARTS} ${TMP_HOOKS_PATH}
      # Note that bind mounting R/O is a two step process, and it
      # wasn't until later util-linux that "bind,ro" worked as a
      # single step, see
      #  https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=9ac77b8a78452eab0612523d27fee52159f5016a
      sudo mount --bind ${TMP_HOOKS_PATH} $TMP_MOUNT_PATH/tmp/in_target.d
      sudo mount -o remount,ro,bind ${TMP_HOOKS_PATH} $TMP_MOUNT_PATH/tmp/in_target.d
      check_break before-$1 run_in_target bash
      [ -z "$break_outside_target" ] && in_target_arg="run_in_target" || in_target_arg=
      trap "check_break after-error $in_target_arg ${break_cmd:-bash}" ERR
      run_in_target /tmp/in_target.d/dib-run-parts /tmp/in_target.d/$1.d
      trap - ERR
      check_break after-$1 run_in_target bash
      sudo umount -f $TMP_MOUNT_PATH/tmp/in_target.d
      if ! timeout 10  sh -c " while ! sudo rmdir $TMP_MOUNT_PATH/tmp/in_target.d; do sleep 1; done"; then
          echo "ERROR: unable to cleanly remove $TMP_MOUNT_PATH/tmp/in_target.d"
          exit 1
      fi
    fi
}

function finalise_base () {
    TARGET_ROOT=$TMP_MOUNT_PATH run_d cleanup

    # Finalise resolv.conf
    #
    # NOTE(ianw): the /etc/resolv.conf.ORIG file is an
    # external interface; elements might put a resolv.conf they
    # want in the final image into this file.
    #
    # In create_base() we replaced/created the initial resolv.conf
    # inside the image with a copy of the "outside" version so that
    # resolving during the build will work.
    #
    # If that file has been replace with a symlink (resolvconf package
    # can do this), or marked immutable, then don't restore the
    # original version, just leave it alone.
    if [ -L $TMP_MOUNT_PATH/etc/resolv.conf ] || \
           lsattr $TMP_MOUNT_PATH/etc/resolv.conf | grep '^....i' >/dev/null ; then
        # We're keeping the contents of resolv.conf set in the elements,
        # so remove the old saved file
        sudo rm -f $TMP_MOUNT_PATH/etc/resolv.conf.ORIG
    else
        # Remove the resolv.conf we created and put the original (or
        # perhaps modified) version back.
        sudo rm -f $TMP_MOUNT_PATH/etc/resolv.conf
        # Note that we use -L and -f to test here as test (and bash [[)
        # return false with -e if the link target does not exist.
        if [ -L $TMP_MOUNT_PATH/etc/resolv.conf.ORIG ] || [ -f $TMP_MOUNT_PATH/etc/resolv.conf.ORIG ] ; then
            sudo mv $TMP_MOUNT_PATH/etc/resolv.conf.ORIG $TMP_MOUNT_PATH/etc/resolv.conf
        fi
    fi

    # Cleanup /tmp in the guest, so there is less cruft left there
    unmount_dir $TMP_MOUNT_PATH/tmp
    find $TMP_MOUNT_PATH/tmp -maxdepth 1 -mindepth 1 | xargs sudo rm -rf --one-file-system
    # Truncate /var/log files in preparation for first boot
    sudo find ${TMP_MOUNT_PATH}/var/log -type f -exec cp /dev/null '{}' \;
    # also /root logs
    sudo find ${TMP_MOUNT_PATH}/root -name \*.log -type f -delete
}

function compress_and_save_image () {
    # Recreate our image to throw away unnecessary data
    test $IMAGE_TYPE != qcow2 && COMPRESS_IMAGE=""
    if [ -n "$QEMU_IMG_OPTIONS" ]; then
        EXTRA_OPTIONS="-o $QEMU_IMG_OPTIONS"
    else
        EXTRA_OPTIONS=""
    fi
    if [ "$IMAGE_TYPE" = "raw" ]; then
        mv $TMP_IMAGE_PATH $1-new
    elif [ "$IMAGE_TYPE" == "tgz" ]; then
        $DIB_GZIP_BIN -9 < $IMAGE_NAME.tar > $1-new
        rm $IMAGE_NAME.tar
    elif [ "$IMAGE_TYPE" == "vhd" ]; then
        cp $TMP_IMAGE_PATH $1-intermediate
        vhd-util convert -s 0 -t 1 -i $1-intermediate -o $1-intermediate
        vhd-util convert -s 1 -t 2 -i $1-intermediate -o $1-new
        # The previous command creates a .bak file
        rm $1-intermediate.bak
        OUT_IMAGE_PATH=$1-new
    else
        echo "Converting image using qemu-img convert"
        qemu-img convert ${COMPRESS_IMAGE:+-c} -f raw -O $IMAGE_TYPE $EXTRA_OPTIONS $TMP_IMAGE_PATH $1-new
    fi

    OUT_IMAGE_PATH=$1-new
    finish_image $1
}

function do_extra_package_install () {
  # Install any packages that were requested with the -p command line option
  if [ "$INSTALL_PACKAGES" != "" ]; then
    run_in_target install-packages ${INSTALL_PACKAGES[@]}
  fi
}

function copy_elements_lib () {
  sudo mkdir -p $TMP_MOUNT_PATH/lib/diskimage-builder
  sudo cp -t $TMP_MOUNT_PATH/lib/diskimage-builder $_LIB/elements-functions
}

# Dig up the initrd and kernel.
function select_boot_kernel_initrd () {
    TARGET_ROOT=$1
    BOOTDIR=$TARGET_ROOT/boot
    if [ -n "${DIB_BAREMETAL_KERNEL_PATTERN:-}" -a -n "${DIB_BAREMETAL_INITRD_PATTERN:-}" ]; then
        KERNEL=$(basename $(eval ls -1rv "$BOOTDIR/${DIB_BAREMETAL_KERNEL_PATTERN}" | head -1))
        RAMDISK=$(basename $(eval ls -1rv "$BOOTDIR/${DIB_BAREMETAL_INITRD_PATTERN}" | head -1))
    elif [ -f $TARGET_ROOT/etc/redhat-release ]; then

        # Prioritize PAE if present
        KERNEL=$(ls -1rv $BOOTDIR/vmlinuz* | grep PAE | grep -v debug | head -1 || echo "")
        KERNEL=${KERNEL:-$(ls -1rv $BOOTDIR/vmlinuz* | grep -v debug | head -1 || echo "")}
        if [ ! $KERNEL ]; then
           echo "No suitable kernel found."
           exit 1
        fi

        KERNEL=$(basename $KERNEL)
        KERNEL_VERSION=${KERNEL#vmlinuz-}
        RAMDISK=$(basename $(ls $BOOTDIR/initramfs-$KERNEL_VERSION.img) || echo "")
        if [ ! $RAMDISK ]; then
            echo "Can't find an initramfs for the $KERNEL_VERSION version of the kernel."
            exit 1
        fi
    elif [ -f $TARGET_ROOT/etc/debian_version ]; then
        KERNEL=$(basename $(ls -1rv $BOOTDIR/vmlinu*generic 2>/dev/null || ls -1rv $BOOTDIR/vmlinu* | head -1))
        RAMDISK=$(basename $(ls -1rv $BOOTDIR/initrd*generic 2>/dev/null || ls -1rv $BOOTDIR/initrd* | head -1))

        if [ -f $TARGET_ROOT/dib-signed-kernel-version ] ; then
            . $TARGET_ROOT/dib-signed-kernel-version
        fi

        if [ -n "${DIB_SIGNED_KERNEL_VERSION:-}" ]; then
            echo "Using signed kernel $DIB_SIGNED_KERNEL_VERSION"
            KERNEL=$(basename $(ls -1rv $BOOTDIR/vmlinu*generic.efi.signed 2>/dev/null))
        fi
    elif [ -f $TARGET_ROOT/etc/SuSE-release ]; then
        KERNEL=$(basename $(readlink -e $BOOTDIR/vmlinuz))
        RAMDISK=$(basename $(readlink -e $BOOTDIR/initrd))
    elif [[ -f "${TARGET_ROOT}"/etc/gentoo-release ]]; then
        KERNEL="$(basename $(ls -1rv $BOOTDIR/vmlinuz-* | head -n 1))"
        RAMDISK="$(basename $(ls -1rv $BOOTDIR/initramfs-* | head -n 1))"
    elif [[ $DISTRO_NAME = opensuse ]]; then
        KERNEL=$(basename $(readlink -e $BOOTDIR/vmlinuz))
        RAMDISK=$(basename $(readlink -e $BOOTDIR/initrd))
    else
        echo "ERROR: Unable to detect operating system"
        exit 1
    fi
}