source: projects/vbootstrap/trunk/libvbuilder.sh.in @ 11148

Revision 11148, 13.6 KB checked in by iwamoto, 7 years ago (diff)

vbootstrap: add support overlayfs

  • Property svn:executable set to *
Line 
1#!/bin/bash
2
3initialize-variables(){
4    ## set boolian variables
5    with_profile=0
6    with_setup_vbootstrap=0
7    with_dist_upgrade=0
8    with_unionfs=0
9    with_sign=0
10    with_no_install=0
11    with_login=0
12    with_debug=0
13    with_actions=0
14    with_ix86_on_x86_64=0
15    with_category_main=0
16    with_category_plus=0
17    with_category_nonfree=0
18    with_category_test=0
19    with_category_proposed_updates=0
20    with_category_security=0
21
22    return 0
23}
24
25check-parameter(){
26    [ -z "$*" ] && Usage && return 1
27
28    while [ ! -z "$*" ]; do
29        case $1 in
30            --help|help)
31                setup-vbuilder ||:
32                Usage
33                return 1
34                ;;
35            --profile)
36                shift
37                with_profile=1
38                PROFILE=$1
39                check-next-parameter $1 || return 1
40                ;;
41            --version|--arch|--category|--fetch-url|--target|--rpmbuild-define|--rpmbuild-with|--rpmbuild-without|--bootstrap-dir|--unionfs-dir|--cache-dir|--built-rpms-dir)
42                [ $with_actions -eq 1 ] && \
43                    echo $"E: You can give no more options after actions" && \
44                    return 1
45                shift
46                check-next-parameter $1 || return 1
47                ;;
48            --dist-upgrade|--unionfs|--with-compat32|--sign|--no-install|--login|--debug)
49                [ $with_actions -eq 1 ] && \
50                    echo $"E: You can give no more options after actions" && \
51                    return 1
52                ;;
53            --build-rpm|build-rpm|--install-rpm|install-rpm|--remove-rpm|remove-rpm)
54                with_actions=1
55                shift
56                check-next-parameter $1 || return 1
57                ;;
58            --build|build|--clean|clean)
59                with_actions=1
60                ;;
61            *)
62                echo $"E: Missing some parameters after $1"
63                return 1
64                ;;
65        esac
66        shift
67    done
68
69    [ $with_actions -eq 0 ] && \
70        echo $"E: You must give at least one action" && return 1
71
72    return 0
73}
74
75check-next-parameter(){
76    [ -z "$1" ] && echo $"E: Missing some parameters after $1" && return 1
77
78    [ $(echo $1 | grep '^-') ] && \
79        echo $"E: Missing some parameters after $1" && return 1
80
81    return 0
82}
83
84## NOTE: setup-vbuilder() loads
85##  - system wide configurations (from /etc/vbootstrap/vbuilder.conf)
86##  - given profile (from /etc/vbootstrap/profile.d/*.conf)
87##  - given command-line parameters
88## where given command-line parameters override the settings given profile,
89## and the settings given profile override system wide settings.
90## If you use a profile of vbuilder, you may not override the settings
91## given profile.
92setup-vbuilder(){
93    ## check $SUDO_USER and $USERHELPER_UID
94    RPM_SIGN_USER=$SUDO_USER
95    if [ -z "${RPM_SIGN_USER}" ]; then
96        [ -z "${USERHELPER_UID}" ] && \
97            echo $"W: \$SUDO_USER and \$USERHELPER_UID are empty" && \
98            return 1
99           
100        RPM_SIGN_USER=$(getent passwd $USERHELPER_UID | cut -d":" -f1)
101    fi
102    ## get $RPM_SIGN_USER's home directory
103    HOME=$(getent passwd $RPM_SIGN_USER |  cut -d":" -f6)
104
105    ## load default settings
106    VBUILDER_CONF=/etc/vbootstrap/vbuilder.conf
107    if [ -r $VBUILDER_CONF ]; then
108        . $VBUILDER_CONF
109        [ $? -eq 1 ] && return 1
110    fi
111    [ -z "${CATEGORIES}" ] && \
112        CATEGORIES=@@VBUILDER_CATEGORIES@@
113    [ -z "${VBOOTSTRAP_FETCH_URL}" ] && \
114        VBOOTSTRAP_FETCH_URL=@@VBUILDER_VBOOTSTRAP_FETCH_URL@@
115    [ -z "${VBOOTSTRAP_DIR}" ] && \
116        VBOOTSTRAP_DIR=@@VBUILDER_VBOOTSTRAP_DIR@@
117    [ -z "${UNIONFS_DIR}" ] && \
118        UNIONFS_DIR=@@VBUILDER_UNIONFS_DIR@@
119    [ -z "${CACHE_DIR}" ] && \
120        CACHE_DIR=@@VBUILDER_CACHE_DIR@@
121    [ -z "${BUILT_RPMS_DIR}" ] && \
122        BUILT_RPMS_DIR=@@VBUILDER_BUILT_RPMS_DIR@@
123
124    ## set default version for vbootstrap
125    VERSION=@@VBUILDER_DEFAULT_VERSION@@
126
127    ## load profile
128    if [ ${with_profile} -eq 1 ]; then
129        [ ! -r /etc/vbootstrap/profile.d/${PROFILE}.conf ] && \
130            echo $"E: No such profile found: ${PROFILE}" && return 1
131
132        . /etc/vbootstrap/profile.d/${PROFILE}.conf
133        [ $? -eq 1 ] && return 1
134    fi
135
136    ## set current stable relase version
137    STABLE_VERSION=@@VBUILDER_STABLE_VERSION@@
138
139    ## set default chroot archtecture
140    UARCH=$(uname -i)
141    case "${UARCH}" in
142        arm*)
143            UARCH="arm"
144            ;;
145    esac
146
147    return 0
148}
149
150setup-vbootstrap(){
151    if [ ${with_setup_vbootstrap} -eq 0 ]; then
152        with_setup_vbootstrap=1
153
154        ## check debug mode
155        [ ${with_debug} -eq 1 ] && \
156            cat $VBUILDER_CONF && \
157            set && set -x
158
159        ## check some directories
160        ## Note: create $BUILT_RPMS_DIR in RPM_Build()
161        [ -d $VBOOTSTRAP_DIR ] || mkdir -p $VBOOTSTRAP_DIR
162        [ -d $CACHE_DIR ] || mkdir -p $CACHE_DIR
163
164        ## check chroot version
165        case ${VERSION} in
166            4.2|5.2|6|6.5|VineSeed)
167                ;;
168            6.?)
169                VERSION="6.5"
170                ;;
171            *)
172                echo $"E: ${VERSION} is NOT supported"
173                return 1
174                ;;
175        esac
176
177        case "${VARCH}" in
178            arm*)
179                VARCH="arm"
180                ;;
181        esac
182
183        ## check a chroot archtecture
184        if [ -z ${VARCH} ]; then
185            VARCH=${UARCH}
186        else
187            case "${VARCH}" in
188                i386|x86_64)
189                    [ "${UARCH}" = "ppc" -o "${UARCH}" = "arm" ] && \
190                        echo $"E: arch ${VARCH} is NOT supported on ${UARCH}" && return 1
191                    ;;
192                ppc)
193                    [ "${UARCH}" = "i386" -o "${UARCH}" = "x86_64" -o "${UARCH}" = "arm" ] && \
194                        echo $"E: arch ${VARCH} is NOT supported on ${UARCH}" && return 1
195                    ;;
196                arm)
197                    [ "${UARCH}" = "i386" -o "${UARCH}" = "x86_64" -o "${UARCH}" = "ppc" ] && \
198                        echo $"E: arch ${VARCH} is NOT supported on ${UARCH}" && return 1
199                    ;;
200            esac
201        fi
202
203        ##!! 4.2 is NO support on VARCH=x86_64 or VARCH=arch
204        if [ "${VERSION}" = "4.2" ]; then
205            if [ "${VARCH}" = "x86_64" -o "${VARCH}" = "arm" ]; then
206                echo $"E: ${VERSION}_${VARCH} is NOT supported"
207                return 1
208            fi
209        fi
210
211        ## set base profile <version>_<arch>
212        BASE_PROFILE=${VERSION}_${VARCH}
213
214        ## check support ${BASE_PROFILE}
215        if [ -z "$(/usr/sbin/vbootstrap | sed -e s/^Usage:.*// -e s/^E:.*// | grep -m 1 ${BASE_PROFILE})" ]; then
216            echo $"E: ${BASE_PROFILE} is NOT supported"
217            return 1
218        fi
219
220        ## check ${VERSION} equals VineSeed*, when with_dist_upgrade=1
221        if [ $with_dist_upgrade -eq 1 ]; then
222            if [ "${VERSION}" != "VineSeed" ]; then
223                echo $"E: version ${VERSION} does not support --dist-upgrade option"
224                return 1
225            fi
226        fi
227
228        ## support i386 chroot on x86_64 below:
229        [ "${UARCH}" = "x86_64" -a "${VARCH}" = "i386" ] && \
230            with_ix86_on_x86_64=1
231
232        ## check apt categories
233        ## "main" category is unconditionally permited
234        with_category_main=1
235        for cat in $(echo ${CATEGORIES} | sed -e "s/,/ /"g); do
236            case $cat in
237                main)
238                    with_category_main=1
239                    ;;
240                plus)
241                    with_category_plus=1
242                    ;;
243                nonfree)
244                    with_category_nonfree=1
245                    ;;
246                test)
247                    ## "test" category only exists in VineSeed
248                    [ "${VERSION}" = "VineSeed" ] || \
249                        echo $"E: No such category exists: $cat" && return 1
250                    with_category_test=1
251                    ;;
252                proposed-updates)
253                    ##!! "proposed-updates" category does not exist in 4.2
254                    [ "${VERSION}" = "4.2" ] && \
255                        echo $"E: No such category exists: $cat" && return 1
256
257                    with_category_proposed_updates=1
258                    ;;
259                security)
260                    ## "security" category does not exist in VineSeed
261                    [ "${VERSION}" = "VineSeed" ] && \
262                        echo $"E: No such category exists: $cat" && return 1
263                    with_category_security=1
264                    ;;
265                *)
266                    echo $"E: No such category exists: $cat" && return 1
267                    ;;
268            esac
269        done
270
271        ## check build target option ${TARGET}
272        if [ ! -z "${TARGET}" ]; then
273            RPM_TARGET_LIST="$(cat /usr/lib/rpm/rpmrc | grep arch_canon: | sed -e "s/arch_canon:[[:blank:]]*\(.*\):.*/\1/")"
274            RPM_TARGET_LIST="${RPM_TARGET_LIST} noarch"
275            if [ -z "$(echo ${RPM_TARGET_LIST} | grep ${TARGET})" ]; then
276                echo $"E: rpm build target ${TARGET} is NOT supported"
277                return 1
278            fi
279        fi
280
281        ## set ${RPM_PKG_ARCH_LIST}
282        RPM_PKG_ARCH_LIST=" \
283            RPMS/i386 RPMS/i486 RPMS/i586 RPMS/i686 RPMS/x86_64 RPMS/ppc \
284            RPMS/noarch \
285            RPMS/armv3l RPMS/armv4l RPMS/armv4tl \
286            RPMS/armv5tejl RPMS/armv5tel RPMS/armv6l RPMS/armv7l \
287            SRPMS"
288        [ -z "${TARGET}" ] || \
289            RPM_PKG_ARCH_LIST="RPMS/${TARGET} ${RPM_PKG_ARCH_LIST}"
290
291    fi
292
293    ## set global variables
294    BUILD_USER=vbuilder
295    BUILD_DIR=/home/${BUILD_USER}/rpm
296    if [ ${with_profile} -eq 1 ]; then
297        BUILD_ROOT=${VBOOTSTRAP_DIR}/${PROFILE}
298        UNIONFS_ROOT=${UNIONFS_DIR}/${PROFILE}
299    else
300        BUILD_ROOT=${VBOOTSTRAP_DIR}/${BASE_PROFILE}
301        UNIONFS_ROOT=${UNIONFS_DIR}/${BASE_PROFILE}
302    fi
303    ARCHIVES_DIR=${BUILD_ROOT}/var/cache/apt/archives
304    EXTERNAL_ARCHIVES_DIR=${CACHE_DIR}/${BASE_PROFILE}/apt/archives
305    UNIONFS_WORK=${UNIONFS_DIR}/unionfs_work
306
307    __chroot_sh="/usr/sbin/chroot ${BUILD_ROOT} /bin/sh -c -l"
308
309    mkdir -p $VBOOTSTRAP_DIR
310
311    return 0
312}
313
314setup-vbootstrap-rpm(){
315    setup-vbootstrap || return 1
316
317    ## check ${BUILD_ROOT}
318    [ -d ${BUILD_ROOT} ] || Build
319    ## setarch ix86 if ix86 chroot on x86_64 host
320    [ $with_ix86_on_x86_64 -eq 1 ] && \
321        __chroot_sh="/usr/sbin/chroot ${BUILD_ROOT} setarch ${VARCH} /bin/sh -c -l"
322
323    DIST_RELEASE=$(cat ${BUILD_ROOT}/etc/vine-release | cut -f3 -d" " | cut -f1 -d.)
324
325    if [ -f $RPM_PKG ]; then
326        BASE_RPM_PKG=$(basename $RPM_PKG)
327        cp -f $RPM_PKG $BUILD_ROOT${BUILD_DIR}
328    else
329        BASE_RPM_PKG=$RPM_PKG   
330    fi
331
332    return 0
333}
334
335## recover apt-get data on host/chroot
336apt-get-update(){
337    case $1 in
338        --host)
339            echo -n $"apt-get update on host ... "
340            apt-get -qq update > /dev/null 2>&1
341            echo $"done."
342            ;;
343        --chroot)
344            echo -n $"apt-get update on chroot ... "
345            $__chroot_sh 'apt-get -qq update' > /dev/null 2>&1
346            echo $"done."
347            ;;
348        *)
349            echo apt-get-update: unknown option $1
350            exit 1
351            ;;
352    esac
353}
354
355## mount-chroot {|--umount} [file system|name]
356## support file systems: /home /tmp /sys /proc /dev/shm /dev/pts /dev
357## support names: vfs archives_dir
358## NOTE: /tmp needs for applications which use X
359##       vfs is virtual file systems
360##       archives_dir uses to mount ${EXTERNAL_ARCHIVES_DIR} to ${ARCHIVES_DIR}
361##       unionfs_dir covers ${BUILD_ROOT} with unionfs
362mount-chroot(){
363    if [ "$1" = "--umount" ]; then
364        mount-chroot-umount $2 || return 1
365    else
366        mount-chroot-mount $1 || return 1
367    fi
368    return 0
369}
370
371## mount-chroot-umount [file system|name]
372mount-chroot-umount(){
373    local fs=$1
374    case $fs in
375        /home|/tmp|/sys|/proc|/dev/shm|/dev/pts|/dev)
376            [ -d ${BUILD_ROOT}${fs} ] || return 1
377            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] || \
378                umount ${BUILD_ROOT}${fs}
379            if [ ! -z "$(mount | grep ${BUILD_ROOT}${fs})" ]; then
380                echo $"Retry lazy unmount ${BUILD_ROOT}${fs} ... "
381                umount -l ${BUILD_ROOT}${fs}
382                echo $"done."
383            fi
384            ;;
385        vfs)
386            for dir in /sys /proc /dev/shm /dev/pts /dev; do
387                mount-chroot-umount ${dir} || return 1
388            done
389            ;;
390        archives_dir)
391            [ -d ${ARCHIVES_DIR} ] || return 1
392            [ -z "$(mount | grep ${ARCHIVES_DIR})" ] || \
393                umount ${ARCHIVES_DIR}
394            ;;
395        unionfs_dir)
396            [ -d ${BUILD_ROOT} ] || return 1
397            [ -z "$(mount | grep ${BUILD_ROOT} | egrep '(unionfs|aufs|overlay)')" ] || \
398                umount ${BUILD_ROOT}
399            if [ ! -z "$(mount | grep ${BUILD_ROOT} | egrep '(unionfs|aufs|overlay)')" ]; then
400                echo $"Retry lazy unmount ${BUILD_ROOT} ... "
401                umount -l ${BUILD_ROOT}
402                echo $"done."
403            fi
404            ;;
405        *)
406            echo mount-chroot-umount: unknown file system $fs
407            exit 1
408            ;;
409    esac
410    return 0
411}
412
413## mount-chroot-mount [file system|name]
414mount-chroot-mount(){
415    local fs=$1
416
417    case $fs in
418        /home)
419            [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs}
420            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \
421                mount -o _netdev,rbind ${fs} ${BUILD_ROOT}${fs}
422            ;;
423        /tmp|/dev)
424            [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs}
425            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \
426                mount --bind -o _netdev ${fs} ${BUILD_ROOT}${fs}
427            ;;
428        /sys)
429            [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs}
430            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \
431                mount -o _netdev -t sysfs vbuildersysfs ${BUILD_ROOT}${fs}
432            ;;
433        /proc)
434            [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs}
435            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \
436                mount -o _netdev -t proc vbuilderproc ${BUILD_ROOT}${fs}
437            ;;
438        /dev/shm)
439            [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs}
440            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \
441                mount -o _netdev -t tmpfs vbuildertmpfs ${BUILD_ROOT}${fs}
442            ;;
443        /dev/pts)
444            [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs}
445            [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \
446                mount -o gid=5,mode=620,_netdev -t devpts vbuilderdevpts ${BUILD_ROOT}${fs}
447            ;;
448        vfs)
449            for dir in /dev /dev/pts /dev/shm /proc /sys; do
450                mount-chroot-mount ${dir} || return 1
451            done
452            ;;
453        archives_dir)
454            [ -d ${EXTERNAL_ARCHIVES_DIR} ] || mkdir -p ${EXTERNAL_ARCHIVES_DIR}
455            [ -d ${ARCHIVES_DIR} ] || mkdir -p ${ARCHIVES_DIR}
456            [ -z "$(mount | grep ${ARCHIVES_DIR})" ] && \
457                mount --bind -o _netdev ${EXTERNAL_ARCHIVES_DIR} ${ARCHIVES_DIR}
458            [ -d ${ARCHIVES_DIR}/partial ] || mkdir -p ${ARCHIVES_DIR}/partial
459            ;;
460        unionfs_dir)
461            if [ $with_unionfs -eq 1 ]; then
462                [ -d ${UNIONFS_ROOT} ] || mkdir -p ${UNIONFS_ROOT}
463                if [ -d ${UNIONFS_WORK} ]; then
464                    #workdir needs emply
465                    rm -rf ${UNIONFS_WORK}; mkdir -p ${UNIONFS_WORK}
466                else
467                    mkdir -p ${UNIONFS_WORK}
468                fi
469                /sbin/modprobe overlay >& /dev/null ||:
470                /sbin/modprobe aufs >& /dev/null ||:
471                #overlayfs
472                if ( grep -q overlay /proc/filesystems ) ; then
473                    [ -z "$(mount | grep ${UNIONFS_ROOT})" ] && \
474                        mount -t overlay overlay -o lowerdir=${BUILD_ROOT},upperdir=${UNIONFS_ROOT},workdir=${UNIONFS_WORK} ${BUILD_ROOT}
475                #aufs
476                elif ( grep -q aufs /proc/filesystems ) ; then
477                    [ -z "$(mount | grep ${UNIONFS_ROOT})" ] && \
478                        mount -t aufs -o br=${UNIONFS_ROOT}=rw:${BUILD_ROOT}=ro aufs ${BUILD_ROOT}
479                else
480                #unionfs
481                    [ -z "$(mount | grep ${UNIONFS_ROOT})" ] && \
482                        mount -t unionfs -o dirs=${UNIONFS_ROOT}=rw:${BUILD_ROOT}=ro unionfs ${BUILD_ROOT}
483                    unionctl ${BUILD_ROOT} --list
484                fi
485            fi
486            ;;
487        *)
488            echo mount-chroot-mount: unknown file system $fs
489            exit 1
490            ;;
491    esac
492    return 0
493}
494
495### end of file
Note: See TracBrowser for help on using the repository browser.