#!/bin/bash # -*- coding: utf-8-unix -*- TEXTDOMAIN=vbootstrap TEXTDOMAINDIR=/usr/share/locale Usage(){ UARCH=$(uname -i) case "${UARCH}" in arm*) UARCH="arm" ;; esac cat< /dev/null 2>&1 echo $"done." ;; --chroot) echo -n $"apt-get update on chroot ... " $__chroot_sh 'apt-get -qq update' > /dev/null 2>&1 echo $"done." ;; *) echo apt-get-update: unknown option $1 exit 1 ;; esac } ## mount-chroot {|--umount} [file system|name] ## support file systems: /home /tmp /sys /proc /dev/shm /dev/pts /dev ## support names: vfs archives_dir ## NOTE: /tmp needs for applications which use X ## vfs is virtual file systems ## archives_dir uses to mount ${EXTERNAL_ARCHIVES_DIR} to ${ARCHIVES_DIR} ## unionfs_dir covers ${BUILD_ROOT} with unionfs mount-chroot(){ if [ "$1" = "--umount" ]; then mount-chroot-umount $2 || return 1 else mount-chroot-mount $1 || return 1 fi return 0 } ## mount-chroot-umount [file system|name] mount-chroot-umount(){ local fs=$1 case $fs in /home|/tmp|/sys|/proc|/dev/shm|/dev/pts|/dev) [ -d ${BUILD_ROOT}${fs} ] || return 1 [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] || \ umount ${BUILD_ROOT}${fs} if [ ! -z "$(mount | grep ${BUILD_ROOT}${fs})" ]; then echo $"Retry lazy unmount ${BUILD_ROOT}${fs} ... " umount -l ${BUILD_ROOT}${fs} echo $"done." fi ;; vfs) for dir in /sys /proc /dev/shm /dev/pts /dev; do mount-chroot-umount ${dir} || return 1 done ;; archives_dir) [ -d ${ARCHIVES_DIR} ] || return 1 [ -z "$(mount | grep ${ARCHIVES_DIR})" ] || \ umount ${ARCHIVES_DIR} ;; unionfs_dir) [ -d ${BUILD_ROOT} ] || return 1 [ -z "$(mount | grep ${BUILD_ROOT} | grep unionfs)" ] || \ umount ${BUILD_ROOT} if [ ! -z "$(mount | grep ${BUILD_ROOT} | grep unionfs)" ]; then echo $"Retry lazy unmount ${BUILD_ROOT} ... " umount -l ${BUILD_ROOT} echo $"done." fi ;; *) echo mount-chroot-umount: unknown file system $fs exit 1 ;; esac return 0 } ## mount-chroot-mount [file system|name] mount-chroot-mount(){ local fs=$1 case $fs in /home) [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs} [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \ mount -o _netdev,rbind ${fs} ${BUILD_ROOT}${fs} ;; /tmp|/dev) [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs} [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \ mount --bind -o _netdev ${fs} ${BUILD_ROOT}${fs} ;; /sys) [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs} [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \ mount -o _netdev -t sysfs vbuildersysfs ${BUILD_ROOT}${fs} ;; /proc) [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs} [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \ mount -o _netdev -t proc vbuilderproc ${BUILD_ROOT}${fs} ;; /dev/shm) [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs} [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \ mount -o _netdev -t tmpfs vbuildertmpfs ${BUILD_ROOT}${fs} ;; /dev/pts) [ -d ${BUILD_ROOT}${fs} ] || mkdir -p ${BUILD_ROOT}${fs} [ -z "$(mount | grep ${BUILD_ROOT}${fs})" ] && \ mount -o gid=5,mode=620,_netdev -t devpts vbuilderdevpts ${BUILD_ROOT}${fs} ;; vfs) for dir in /dev /dev/pts /dev/shm /proc /sys; do mount-chroot-mount ${dir} || return 1 done ;; archives_dir) [ -d ${EXTERNAL_ARCHIVES_DIR} ] || mkdir -p ${EXTERNAL_ARCHIVES_DIR} [ -d ${ARCHIVES_DIR} ] || mkdir -p ${ARCHIVES_DIR} [ -z "$(mount | grep ${ARCHIVES_DIR})" ] && \ mount --bind -o _netdev ${EXTERNAL_ARCHIVES_DIR} ${ARCHIVES_DIR} [ -d ${ARCHIVES_DIR}/partial ] || mkdir -p ${ARCHIVES_DIR}/partial ;; unionfs_dir) if [ $with_unionfs -eq 1 ]; then [ -d ${UNIONFS_ROOT} ] || mkdir -p ${UNIONFS_ROOT} [ -z "$(mount | grep ${UNIONFS_ROOT})" ] && \ mount -t unionfs -o dirs=${UNIONFS_ROOT}=rw:${BUILD_ROOT}=ro unionfs ${BUILD_ROOT} unionctl ${BUILD_ROOT} --list fi ;; *) echo mount-chroot-mount: unknown file system $fs exit 1 ;; esac return 0 } write-vbuilder-log(){ HRULE="======================================================================" [ -d ${BUILD_ROOT} ] || return 1 if [ ! -f $VBUILDER_LOG ]; then cat< $VBUILDER_LOG ${HRULE} VBUILDER REPORT DATE: $(LANG=C date) HOSTNAME: $(hostname) OS: $(echo $($__chroot_sh "cat /etc/vine-release")) %_arch: $(echo $($__chroot_sh "rpm --eval %_arch")) --version: ${VERSION} $(echo $([ -z "${VARCH}" ] || echo "--arch: ${VARCH}")) $(echo $([ -z "${CATEGORIES}" ] || echo "--category: ${CATEGORIES}")) $(echo $([ $with_dist_upgrade -eq 1 ] && echo "--dist-upgrade")) $(echo $([ $with_unionfs -eq 1 ] && echo "--unionfs")) $(echo $([ -z "${TARGET}" ] || echo "--target: ${TARGET}")) --bootstrap-dir: ${VBOOTSTRAP_DIR} --unionfs-dir: ${UNIONFS_DIR} --cache-dir: ${CACHE_DIR} --built-rpms-dir: ${BUILT_RPMS_DIR} ${HRULE} [$VBUILDER_CONF] $(cat $VBUILDER_CONF) [History] EOF else cat<> $VBUILDER_LOG $* EOF fi return 0 } ############################################################################## Clean(){ setup-vbootstrap || return 1 # mount-chroot --umount /home mount-chroot --umount /tmp mount-chroot --umount /dev/shm mount-chroot --umount /dev/pts mount-chroot --umount /proc mount-chroot --umount archives_dir mount-chroot --umount unionfs_dir apt-get-update --host ## We remark that we first remove /, and secondly remove /. ## If we directly remove /, we obtained some non-empty directories: ## /dev/.udev/rules.d. if [ $with_unionfs -eq 1 ]; then if [ -d ${UNIONFS_ROOT} ]; then echo -n $"Cleaning build root ${UNIONFS_ROOT} via unionfs ... " rm -rf ${UNIONFS_ROOT} 2>/dev/null rm -rf ${UNIONFS_ROOT} echo $"done." fi else if [ -d ${BUILD_ROOT} ]; then echo -n $"Cleaning build root ${BUILD_ROOT} ... " rm -rf ${BUILD_ROOT} 2>/dev/null rm -rf ${BUILD_ROOT} echo $"done." fi fi echo $"Cleanup a build farm for ${VERSION} done." return 0 } Build(){ setup-vbootstrap || return 1 if [ $with_dist_upgrade -eq 1 ]; then ## make bootstrap of ${STABLE_VERSION} /usr/sbin/vbootstrap \ $(echo ${VERSION} | sed -e "s/VineSeed/${STABLE_VERSION}/") \ ${BUILD_ROOT} ## aim apt-line to VineSeed sed -i "s/apt ${STABLE_VERSION}/apt VineSeed/g" \ ${BUILD_ROOT}/etc/apt/sources.list.d/main.list else /usr/sbin/vbootstrap ${VERSION} ${BUILD_ROOT} fi mount-chroot /proc mount-chroot archives_dir mount-chroot /dev/pts mount-chroot /dev/shm # mount-chroot /tmp # mount-chroot /home $__chroot_sh 'apt-get -qq update && apt-get -qq -y dist-upgrade' ##!! 4.2 has no apt-sourceslist-{plus,nonfree,proposed-updates} packages case ${MAJOR_VERSION} in 4.2) $__chroot_sh "sed -i -e 's/main plus updates nonfree *$/$(echo ${CATEGORIES} | sed -e "s/,/ /"g) updates/g' /etc/apt/sources.list" # [ $with_category_security -eq 1 ] && \ # echo ;; @@VBUILDER_STABLE_VERSION@@) [ $with_category_plus -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y install apt-sourceslist-plus' [ $with_category_nonfree -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y install apt-sourceslist-nonfree' [ $with_category_proposed_updates -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y install apt-sourceslist-proposed-updates' # [ $with_category_security -eq 1 ] && \ # echo ;; VineSeed) [ $with_category_plus -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y install apt-sourceslist-plus' [ $with_category_nonfree -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y install apt-sourceslist-nonfree' [ $with_category_test -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y install apt-sourceslist-test' ;; esac [ $with_dist_upgrade -eq 1 ] && \ $__chroot_sh 'apt-get -qq update && apt-get -qq -y dist-upgrade' $__chroot_sh 'apt-get -qq -y install build-essential' [ $with_category_nonfree -eq 1 ] && \ $__chroot_sh 'apt-get -qq -y install self-build-setup' $__chroot_sh 'apt-get -qq -y install etcskel shadow-utils' $__chroot_sh 'cd /dev && /sbin/MAKEDEV console' $__chroot_sh 'cd /dev && /sbin/MAKEDEV ptmx' $__chroot_sh 'cd /dev && /sbin/MAKEDEV null' $__chroot_sh 'cd /dev && /sbin/MAKEDEV zero' $__chroot_sh 'cd /dev && /sbin/MAKEDEV random' $__chroot_sh 'cd /dev && /sbin/MAKEDEV urandom' $__chroot_sh 'cd /dev && mkdir -p shm && chmod 777 shm' $__chroot_sh 'cd /dev && mkdir -p pts && chmod 755 pts' $__chroot_sh '/usr/sbin/pwconv' $__chroot_sh "/usr/sbin/useradd ${BUILD_USER}" ##!! for rpm-4.8.0 or higher ##!! (See http://trac.vinelinux.org/wiki/Vine6/AboutUpdateToolchain) if [ "$(echo ${VERSION} | sed -e "s/\(VineSeed\).*/\1/")" = "VineSeed" ]; then $__chroot_sh "sed -i -e 's/^%_topdir/#%_topdir/' /home/${BUILD_USER}/.rpmmacros" fi ## output basic informations in chroot write-vbuilder-log write-vbuilder-log "build" # mount-chroot --umount /home # mount-chroot --umount /tmp mount-chroot --umount /dev/shm mount-chroot --umount /dev/pts mount-chroot --umount archives_dir mount-chroot --umount /proc apt-get-update --host echo $"Making a build farm for ${VERSION} done." return 0 } Show-Info(){ setup-vbootstrap || return 1 [ -f $VBUILDER_LOG ] && cat $VBUILDER_LOG return 0 } RPM_Remove(){ setup-vbootstrap-rpm || return 1 mount-chroot unionfs_dir mount-chroot archives_dir mount-chroot /proc mount-chroot /dev/pts mount-chroot /dev/shm apt-get-update --chroot [ -f $RPM_PKG ] && \ echo $"E: $RPM_PKG is not a package name" && return 1 $__chroot_sh "apt-get -y remove $BASE_RPM_PKG" write-vbuilder-log "remove-rpm $RPM_PKG" mount-chroot --umount /dev/shm mount-chroot --umount /dev/pts mount-chroot --umount /proc mount-chroot --umount archives_dir mount-chroot --umount unionfs_dir apt-get-update --host return 0 } RPM_Install(){ setup-vbootstrap-rpm || return 1 mount-chroot unionfs_dir mount-chroot archives_dir mount-chroot /proc mount-chroot /dev/pts mount-chroot /dev/shm apt-get-update --chroot $__chroot_sh "cd ${BUILD_DIR} && apt-get -y install $BASE_RPM_PKG" write-vbuilder-log "install-rpm $RPM_PKG" mount-chroot --umount /dev/shm mount-chroot --umount /dev/pts mount-chroot --umount /proc mount-chroot --umount archives_dir mount-chroot --umount unionfs_dir apt-get-update --host return 0 } RPM_Build(){ setup-vbootstrap-rpm || return 1 mount-chroot unionfs_dir mount-chroot archives_dir mount-chroot /proc mount-chroot /dev/pts mount-chroot /dev/shm apt-get-update --chroot [ ! -f $RPM_PKG ] && \ echo $"E: $RPM_PKG is not a source RPM package" && return 1 RPM_PKG_USER=$(stat -c %U $RPM_PKG) RPM_PKG_GROUP=$(stat -c %G $RPM_PKG) [ ! -z "${SUDO_UID}" ] && RPM_PKG_USER=${SUDO_UID} [ ! -z "${SUDO_GID}" ] && RPM_PKG_GROUP=${SUDO_GID} local __install="install -p -v -o ${RPM_PKG_USER} -g ${RPM_PKG_GROUP}" ## make src.rpm for $VERSION $__chroot_sh "cd ${BUILD_DIR} && su ${BUILD_USER} -c 'rpm -ivh $BASE_RPM_PKG'" $__chroot_sh "cd ${BUILD_DIR} && su ${BUILD_USER} -c 'rpmbuild -bs --nodeps --clean --rmsource --rmspec $RPM_OPTS ${BUILD_DIR}/SPECS/*.spec'" ## change ${DIST_RELEASE} BASE_RPM_PKG=$(echo $BASE_RPM_PKG | sed -e "s/vl[0-9]*\([A-Za-z]*\)\./vl${DIST_RELEASE}\1\./") ## rebuild $BASE_RPM_PKG on ${DIST_RELEASE} $__chroot_sh "cd ${BUILD_DIR}/SRPMS && apt-get -o APT::Install::Virtual=true -y build-dep $BASE_RPM_PKG" $__chroot_sh "cd ${BUILD_DIR}/SRPMS && su ${BUILD_USER} -c 'rpmbuild --rebuild $RPM_OPTS $BASE_RPM_PKG'" [ $with_no_install -eq 0 ] && \ $__chroot_sh "cd ${BUILD_DIR} && apt-get -y install $(find $BUILD_ROOT${BUILD_DIR}/RPMS -type f -regex '.*\.rpm' | sed -e s@${BUILD_ROOT}@@g -e 's|.*\/compat32-.*||g' -e 's|.*\/.*\.src\.rpm||g' -e 's/$/ \\/g')" ## copy built rpms to ${HOME}/rpm/ for each archtectures echo $"Copying built rpms to ${BUILT_RPMS_DIR} for each archtectures ... " for i in $RPM_PKG_ARCH_LIST; do \ if [ -d $BUILD_ROOT${BUILD_DIR}/${i} ]; then if [ ! -d ${BUILT_RPMS_DIR}/${MAJOR_VERSION}/${i} ]; then $__install -d ${BUILT_RPMS_DIR}/${MAJOR_VERSION}/${i}/ chown -R ${RPM_PKG_USER}:${RPM_PKG_GROUP} ${BUILT_RPMS_DIR} fi find $BUILD_ROOT${BUILD_DIR}/${i} -type f -regex '.*\.rpm' \ -exec $__install -m0644 {} ${BUILT_RPMS_DIR}/${MAJOR_VERSION}/${i}/ \; fi done write-vbuilder-log "build-rpm $RPM_PKG" mount-chroot --umount /dev/shm mount-chroot --umount /dev/pts mount-chroot --umount /proc mount-chroot --umount archives_dir mount-chroot --umount unionfs_dir apt-get-update --host echo $"done." return 0 } RPM_Sign(){ [ $with_sign -eq 1 ] || return 1 setup-vbootstrap || return 1 [ -d ${BUILD_ROOT} ] || Build mount-chroot unionfs_dir echo $"Signing built rpms using ${RPM_SIGN_USER}'s key: " su $RPM_SIGN_USER -c "rpm --addsign $(for i in $RPM_PKG_ARCH_LIST; do find $BUILD_ROOT${BUILD_DIR}/${i} -type f -regex '.*\.rpm' 2>/dev/null; done | sed -e s,$BUILD_ROOT${BUILD_DIR},${BUILT_RPMS_DIR}/${MAJOR_VERSION},g -e 's/$/ \\/g')" mount-chroot --umount unionfs_dir return 0 } Login_Chroot(){ [ $with_login -eq 1 ] || return 1 setup-vbootstrap || return 1 __chroot="/usr/sbin/chroot ${BUILD_ROOT}" ## setarch ix86 if ix86 chroot on x86_64 host [ $with_ix86_on_x86_64 -eq 1 ] && \ __chroot="/usr/sbin/chroot ${BUILD_ROOT} setarch ${VARCH}" mount-chroot unionfs_dir mount-chroot archives_dir mount-chroot /proc mount-chroot /dev/pts mount-chroot /dev/shm mount-chroot /tmp # mount-chroot /home apt-get-update --chroot ## copy host's configurations of /etc #passwd shadow group gshadow for i in resolv.conf hosts; do cp -pf /etc/${i} ${BUILD_ROOT}/etc done cp -Ppf /etc/localtime ${BUILD_ROOT}/etc $__chroot /bin/bash || return 1 # mount-chroot --umount /home mount-chroot --umount /tmp mount-chroot --umount /dev/shm mount-chroot --umount /dev/pts mount-chroot --umount /proc mount-chroot --umount archives_dir mount-chroot --umount unionfs_dir apt-get-update --host return 0 } ############################################################################## setup-vbuilder || exit 1 check-parameter $* || exit 1 while [ $# -gt 0 ]; do tmpARG=$1 case $tmpARG in --version|--arch|--category|--target|--rpmbuild-define|--rpmbuild-with|--rpmbuild-without|--bootstrap-dir|--unionfs-dir|--cache-dir|--built-rpms-dir) shift ;; --dist-upgrade|--unionfs|--with-compat32|--sign|--no-install|--login|--debug) ;; --build-rpm|build-rpm|--install-rpm|install-rpm|--remove-rpm|remove-rpm) shift ;; --build|build|--clean|clean|--show-info|show-info) ;; *) echo unknown option $1 exit 1 ;; esac case $tmpARG in --version) VERSION=$1 ;; --arch) VARCH=$1 ;; --category) CATEGORIES=$1 ;; --dist-upgrade) with_dist_upgrade=1 ;; --unionfs) with_unionfs=1 ;; --target) TARGET=$1 RPM_OPTS="${RPM_OPTS} --target $TARGET" ;; --with-compat32) RPM_OPTS="${RPM_OPTS} --with compat32" ;; --rpmbuild-define) RPM_OPTS="${RPM_OPTS} --define $1" ;; --rpmbuild-with) RPM_OPTS="${RPM_OPTS} --with $1" ;; --rpmbuild-without) RPM_OPTS="${RPM_OPTS} --without $1" ;; --sign) with_sign=1 ;; --no-install) with_no_install=1 ;; --login) with_login=1 ;; --bootstrap-dir) VBOOTSTRAP_DIR=$1 ;; --unionfs-dir) UNIONFS_DIR=$1 ;; --cache-dir) CACHE_DIR=$1 ;; --built-rpms-dir) BUILT_RPMS_DIR=$1 ;; --debug) with_debug=1 ;; --build-rpm|build-rpm) RPM_PKG=$1 RPM_Build || exit 1 ;; --install-rpm|install-rpm) RPM_PKG=$1 RPM_Install || exit 1 ;; --remove-rpm|remove-rpm) RPM_PKG=$1 RPM_Remove || exit 1 ;; --show-info|show-info) Show-Info || exit 1 ;; --build|build) Build || exit 1 ;; --clean|clean) Clean || exit 1 ;; esac shift done RPM_Sign ||: Login_Chroot ||: exit