diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/man/poudriere-bulk.8 | 9 | ||||
-rw-r--r-- | src/man/poudriere-jail.8 | 9 | ||||
-rw-r--r-- | src/man/poudriere-pkgclean.8 | 28 | ||||
-rw-r--r-- | src/man/poudriere-testport.8 | 9 | ||||
-rw-r--r-- | src/man/poudriere.8 | 10 | ||||
-rwxr-xr-x | src/share/poudriere/common.sh | 31 | ||||
-rw-r--r-- | src/share/poudriere/image.sh | 10 | ||||
-rw-r--r-- | src/share/poudriere/image_hybridiso.sh | 97 | ||||
-rw-r--r-- | src/share/poudriere/image_zfs.sh | 49 | ||||
-rw-r--r-- | src/share/poudriere/include/pkg.sh | 16 | ||||
-rwxr-xr-x | src/share/poudriere/jail.sh | 4 | ||||
-rwxr-xr-x | src/share/poudriere/pkgclean.sh | 148 |
12 files changed, 325 insertions, 95 deletions
diff --git a/src/man/poudriere-bulk.8 b/src/man/poudriere-bulk.8 index 77223543..196567ce 100644 --- a/src/man/poudriere-bulk.8 +++ b/src/man/poudriere-bulk.8 @@ -28,7 +28,7 @@ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. -.Dd September 9, 2021 +.Dd April 29, 2022 .Dt POUDRIERE-BULK 8 .Os .Sh NAME @@ -298,13 +298,12 @@ Dry run. Show what would be done, but do not actually build or delete any packages. .It Fl O Ar overlay -Specify an extra ports tree to use as an overlay. +Specify an extra +.Xr poudriere-ports 8 +tree to use as an overlay. Multiple .Fl O Ar overlay arguments may be specified to stack them. -.Pp -These overlays should be setup with -.Xr poudriere-ports(8) . .It Fl p Ar tree Specify on which ports .Ar tree diff --git a/src/man/poudriere-jail.8 b/src/man/poudriere-jail.8 index b59aff90..792a4c4d 100644 --- a/src/man/poudriere-jail.8 +++ b/src/man/poudriere-jail.8 @@ -28,7 +28,7 @@ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. -.Dd August 19, 2021 +.Dd April 29, 2022 .Dt POUDRIERE-JAIL 8 .Os .Sh NAME @@ -421,10 +421,10 @@ that is based on .It Sy Example 2\&: No Checking If a Jail Already Exists .Pp The following command returns success if a poudriere jail called -.Dq 112i386 +.Dq 130i386 already exists. .Bd -literal -offset 2n -.Li # Ic poudriere jail -l -n -q | grep --quiet '^112i386$' +.Li # Ic poudriere jail -l -n -q | grep --quiet '^130i386$' .Ed .El .Sh SEE ALSO @@ -454,7 +454,8 @@ and flags are all used directly in the name of the jail created by poudriere. .Pp -Be careful to respect the names supported by jail(8): +Be careful to respect the names supported by +.Xr jail 8 : .Bd -literal -offset indent This is an arbitrary string that identifies a jail (except it may not contain a '.'). diff --git a/src/man/poudriere-pkgclean.8 b/src/man/poudriere-pkgclean.8 index b6a14c6a..25791df2 100644 --- a/src/man/poudriere-pkgclean.8 +++ b/src/man/poudriere-pkgclean.8 @@ -28,7 +28,7 @@ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. -.Dd July 28, 2021 +.Dd June 6, 2022 .Dt POUDRIERE-PKGCLEAN 8 .Os .Sh NAME @@ -44,6 +44,18 @@ .Op Ar origin2 Op Ar ... .Sh DESCRIPTION This command is used to delete all packages not specified to build. +By default packages +.Em not listed +will be deleted; +Listed packages, and their dependencies, will be kept. +.Pp +If +.Fl C +is specified then packages listed on the command line will be deleted +rather than kept. +Their orphaned dependencies will not be deleted. +A second run with a full list of wanted packages is needed to +cleanup orphaned dependencies. .Pp Either a subcommand or a list of port origins must be supplied. .Sh SUBCOMMANDS @@ -63,6 +75,12 @@ arguments may be specified at once. .El .Sh OPTIONS .Bl -tag -width "-f conffile" +.It Fl C +Delete the listed packages rather than keep them. +This can be used to delete specific packages that need to be rebuilt +while keeping them in the port list file. +.Fl r +can be specified to delete reverse dependencies as well. .It Fl J Ar number This argument specifies how many .Ar number @@ -80,12 +98,18 @@ Multiple arguments may be specified to stack them. .Pp These overlays should be setup with -.Xr poudriere-ports(8) . +.Xr poudriere-ports 8 . .It Fl p Ar tree Specifies which ports .Ar tree to use. .Pq Default: Dq Li default +.It Fl r +When +.Fl C +is specified then all reverse dependencies will be deleted as well. +This can be used to later force rebuild anything depending on the listed +packages. .It Fl R Also clean restricted packages. .It Fl v diff --git a/src/man/poudriere-testport.8 b/src/man/poudriere-testport.8 index eab39e32..b99d6e4d 100644 --- a/src/man/poudriere-testport.8 +++ b/src/man/poudriere-testport.8 @@ -28,7 +28,7 @@ .\" .\" Note: The date here should be updated whenever a non-trivial .\" change is made to the manual page. -.Dd September 9, 2021 +.Dd April 29, 2022 .Dt POUDRIERE-TESTPORT 8 .Os .Sh NAME @@ -142,13 +142,12 @@ Dry run. Show what would be done, but do not actually build or delete any packages. .It Fl O Ar overlay -Specify an extra ports tree to use as an overlay. +Specify an extra +.Xr poudriere-ports 8 +tree to use as an overlay. Multiple .Fl O Ar overlay arguments may be specified to stack them. -.Pp -These overlays should be setup with -.Xr poudriere-ports(8) . .It Fl o Ar origin Specifies an origin in the ports tree. .It Fl P diff --git a/src/man/poudriere.8 b/src/man/poudriere.8 index dff13904..0eb146a2 100644 --- a/src/man/poudriere.8 +++ b/src/man/poudriere.8 @@ -153,7 +153,7 @@ for bulk build packages. First you have to create a jail, which will hold all the building infrastructure needs. .Pp -.Dl "poudriere jail -c -v 8.2-RELEASE -a amd64 -j 82amd64" +.Dl "poudriere jail -c -v 13.1-RELEASE -a amd64 -j 131amd64" .Pp A jail will take approximately 3GB of space. .Pp @@ -163,7 +163,7 @@ regardless of what version you are running. amd64 users can choose i386 arch like in this example: .Pp -.Dl "poudriere jail -c -v 8.1-RELEASE -a i386 -j 81i386" +.Dl "poudriere jail -c -v 13.0-RELEASE -a i386 -j 130i386" .Pp This command will fetch and install a minimal jail, small (~400MB) so you can create a lot of them. @@ -193,15 +193,15 @@ Any line starting with the hash sign will be treated as a comment. Now you can launch the bulk build. At minimum the jail and list of packages to build must be specified. .Pp -.Dl "poudriere bulk -f ~/pkglist -j 81i386" +.Dl "poudriere bulk -f ~/pkglist -j 130i386" .Pp .Bq Find your packages .Pp Once the bulk build is over, you can meet your shiny new packages here: .Pp -.Dl Pa /usr/local/poudriere/data/packages/81i386 +.Dl Pa /usr/local/poudriere/data/packages/130i386 .Pp -with 81i386 as the name of the jail. +with 130i386 as the name of the jail. .Ss Test a single port This second example show how to use .Nm diff --git a/src/share/poudriere/common.sh b/src/share/poudriere/common.sh index a26e9aac..84c35c18 100755 --- a/src/share/poudriere/common.sh +++ b/src/share/poudriere/common.sh @@ -150,7 +150,7 @@ _msg_n() { fi case "${COLOR_ARROW-}${1}" in *$'\033'"["*) - printf "${COLOR_ARROW}${elapsed}${DRY_MODE-}${arrow:+${COLOR_ARROW}${arrow} }${COLOR_RESET}%s${COLOR_RESET}${NL}" "$*" + printf "${COLOR_ARROW-}${elapsed}${DRY_MODE-}${arrow:+${COLOR_ARROW-}${arrow} }${COLOR_RESET}%s${COLOR_RESET}${NL}" "$*" ;; *) printf "${elapsed}${DRY_MODE-}${arrow:+${arrow} }%s${NL}" "$*" @@ -1281,6 +1281,7 @@ sig_handler() { exit_handler() { exit_status="$?" + set +u case "${SHFLAGS}" in *x*) ;; *) local -; set +x ;; @@ -7692,6 +7693,26 @@ originspec_is_needed_and_not_ignored() { }' "${MASTER_DATADIR}/all_pkgs" } +# Port was listed to be built +originspec_is_listed() { + [ $# -eq 1 ] || eargs originspec_is_listed originspec + local originspec="$1" + + if [ "${ALL}" -eq 1 ]; then + return 0 + fi + + awk -voriginspec="${originspec}" ' + $3 == "listed" && $2 == originspec { + found=1 + exit 0 + } + END { + if (found != 1) + exit 1 + }' "${MASTER_DATADIR}/all_pkgs" +} + get_porttesting() { [ $# -eq 1 ] || eargs get_porttesting pkgname local pkgname="$1" @@ -8349,18 +8370,18 @@ read_packages_from_params() { if [ $# -eq 0 -o -z "$1" ]; then [ -n "${LISTPKGS}" -o ${ALL} -eq 1 ] || - err 1 "No packages specified" + err ${EX_USAGE} "No packages specified" if [ ${ALL} -eq 0 ]; then for listpkg_name in ${LISTPKGS}; do [ -r "${listpkg_name}" ] || - err 1 "No such list of packages: ${listpkg_name}" + err ${EX_USAGE} "No such list of packages: ${listpkg_name}" done fi else [ ${ALL} -eq 0 ] || - err 1 "command line arguments and -a cannot be used at the same time" + err ${EX_USAGE} "command line arguments and -a cannot be used at the same time" [ -z "${LISTPKGS}" ] || - err 1 "command line arguments and list of ports cannot be used at the same time" + err ${EX_USAGE} "command line arguments and list of ports cannot be used at the same time" LISTPORTS="$@" fi } diff --git a/src/share/poudriere/image.sh b/src/share/poudriere/image.sh index bfa5b0da..bb7b3600 100644 --- a/src/share/poudriere/image.sh +++ b/src/share/poudriere/image.sh @@ -28,6 +28,7 @@ . ${SCRIPTPREFIX}/common.sh . ${SCRIPTPREFIX}/image_dump.sh . ${SCRIPTPREFIX}/image_firmware.sh +. ${SCRIPTPREFIX}/image_hybridiso.sh . ${SCRIPTPREFIX}/image_iso.sh . ${SCRIPTPREFIX}/image_mfs.sh . ${SCRIPTPREFIX}/image_rawdisk.sh @@ -44,7 +45,7 @@ poudriere image [parameters] [options] Parameters: -j jail -- Jail -t type -- Type of image can be one of - -- iso, iso+mfs, iso+zmfs, usb, usb+mfs, usb+zmfs, + -- hybridiso, iso, iso+mfs, iso+zmfs, usb, usb+mfs, usb+zmfs, rawdisk, zrawdisk, tar, firmware, rawfirmware, dump, zfs+[raw|gpt|send[+full[+be]]], zsnapshot @@ -353,7 +354,7 @@ while getopts "A:bB:c:f:h:i:j:m:n:o:p:P:R:s:S:t:vw:X:z:" FLAG; do t) MEDIATYPE=${OPTARG} case ${MEDIATYPE} in - iso|iso+mfs|iso+zmfs|usb|usb+mfs|usb+zmfs) ;; + hybridiso|iso|iso+mfs|iso+zmfs|usb|usb+mfs|usb+zmfs) ;; rawdisk|zrawdisk|tar|firmware|rawfirmware) ;; dump|zsnapshot) ;; zfs|zfs+gpt|zfs+raw) ;; @@ -395,7 +396,7 @@ post_getopts : ${SWAPSIZE:=0} : ${PTNAME:=default} : ${ZFS_SEND_FLAGS:=-Rec} -: ${ZFS_POOL_NAME:=${IMAGENAME}root} +: ${ZFS_POOL_NAME:=zroot} : ${ZFS_BEROOT_NAME:=ROOT} : ${ZFS_BOOTFS_NAME:=default} @@ -406,6 +407,8 @@ MEDIAREMAINDER=${MEDIATYPE#*+} SUBMEDIATYPE=${MEDIAREMAINDER%%+*} MEDIAREMAINDER=${MEDIAREMAINDER#*+} +TMP_ZFS_POOL_NAME="${ZFS_POOL_NAME}.$(jot -r 1 1000000000)" + if [ "${MEDIATYPE}" = "none" ]; then err 1 "Missing -t option" fi @@ -432,6 +435,7 @@ mkdir -p ${WRKDIR}/out WORLDDIR="${WRKDIR}/world" [ -z "${EXCLUDELIST}" ] || cat ${EXCLUDELIST} > ${excludelist} cat >> ${excludelist} << EOF +.poudriere-snap-* usr/src var/db/freebsd-update var/db/etcupdate diff --git a/src/share/poudriere/image_hybridiso.sh b/src/share/poudriere/image_hybridiso.sh new file mode 100644 index 00000000..34a37c47 --- /dev/null +++ b/src/share/poudriere/image_hybridiso.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# +# Copyright (c) 2022 Christer Edwards <christer.edwards@gmail.com> +# Copyright (c) 2021 Emmanuel Vadot <manu@FreeBSD.org> +# Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +hybridiso_check() +{ + + # Limitation on isos + case "${IMAGENAME}" in + ''|*[!A-Za-z0-9]*) + err 1 "Name can only contain alphanumeric characters" + ;; + esac + + [ -f "${mnt}/boot/kernel/kernel" ] || \ + err 1 "The ${MEDIATYPE} media type requires a jail with a kernel" +} + +hybridiso_prepare() +{ +} + +hybridiso_build() +{ + + imageupper=$(echo ${IMAGENAME} | tr '[:lower:]' '[:upper:]') + cat >> ${WRKDIR}/world/etc/fstab <<-EOF + /dev/iso9660/${imageupper} / cd9660 ro 0 0 + tmpfs /tmp tmpfs rw,mode=1777 0 0 + EOF + do_clone -r ${WRKDIR}/world/boot ${WRKDIR}/out/boot +} + +hybridiso_generate() +{ + + FINALIMAGE=${IMAGENAME}.iso + espfilename=$(mktemp /tmp/efiboot.XXXXXX) + make_esp_file ${espfilename} 10 ${WRKDIR}/world/boot/loader.efi + + # Make ISO image. + makefs -t cd9660 -o rockridge -o label=${IMAGENAME} \ + -o publisher="poudriere" \ + -o bootimage="i386;${WRKDIR}/out/boot/cdboot" \ + -o bootimage="i386;${espfilename}" \ + -o platformid=efi \ + -o no-emul-boot "${OUTPUTDIR}/${FINALIMAGE}" ${WRKDIR}/world + + # Find the EFI System Partition on the ISO. + for entry in $(etdump --format shell ${OUTPUTDIR}/${FINALIMAGE}); do + eval $entry + if [ "$et_platform" = "efi" ]; then + espstart=$(expr $et_lba \* 2048) + espsize=$(expr $et_sectors \* 512) + espparam="-p efi::$espsize:$espstart" + break + fi + done + + # Create a GPT image with the partitions needed for hybrid boot. + imgsize=$(stat -f %z "${OUTPUTDIR}/${FINALIMAGE}") + mkimg -s gpt \ + --capacity $imgsize \ + -b "$WRKDIR/out/boot/pmbr" \ + -p freebsd-boot:="$WRKDIR/out/boot/isoboot" \ + $espparam \ + -o "${OUTPUTDIR}/hybridiso.img" + + # Drop the PMBR, GPT, and boot code into the System Area of the ISO. + dd if="${OUTPUTDIR}/hybridiso.img" of="${OUTPUTDIR}/${FINALIMAGE}" bs=32k count=1 conv=notrunc + rm -f "${OUTPUTDIR}/hybridiso.img" +} diff --git a/src/share/poudriere/image_zfs.sh b/src/share/poudriere/image_zfs.sh index d788f088..7b2271e7 100644 --- a/src/share/poudriere/image_zfs.sh +++ b/src/share/poudriere/image_zfs.sh @@ -41,8 +41,8 @@ zfs_check() [ -n "${IMAGESIZE}" ] || err 1 "Please specify the imagesize" [ -n "${ZFS_POOL_NAME}" ] || err 1 "Please specify a pool name" - zpool list -Ho name ${ZFS_POOL_NAME} >/dev/null 2>&1 && \ - err 1 "Target pool name already exists" + zpool list -Ho name ${TMP_ZFS_POOL_NAME} >/dev/null 2>&1 && \ + err 1 "Temporary pool name already exists" case "${IMAGENAME}" in ''|*[!A-Za-z0-9]*) err 1 "Name can only contain alphanumeric characters" @@ -62,6 +62,7 @@ zfs_prepare() truncate -s ${IMAGESIZE} ${WRKDIR}/raw.img md=$(/sbin/mdconfig ${WRKDIR}/raw.img) zroot=${ZFS_POOL_NAME} + tmpzroot=${TMP_ZFS_POOL_NAME} msg "Creating temporary ZFS pool" zpool create \ @@ -70,27 +71,28 @@ zfs_prepare() -O checksum=sha512 \ -O compression=on \ -O atime=off \ + -t ${tmpzroot} \ -R ${WRKDIR}/world ${zroot} /dev/${md} || exit if [ -n "${ORIGIN_IMAGE}" ]; then msg "Importing previous ZFS Datasets" - zfs recv -F ${zroot} < "${ORIGIN_IMAGE}" + zfs recv -F ${tmpzroot} < "${ORIGIN_IMAGE}" else msg "Creating ZFS Datasets" - zfs create -o mountpoint=none ${zroot}/${ZFS_BEROOT_NAME} - zfs create -o mountpoint=/ ${zroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME} - zfs create -o mountpoint=/tmp -o exec=on -o setuid=off ${zroot}/tmp - zfs create -o mountpoint=/usr -o canmount=off ${zroot}/usr - zfs create ${zroot}/usr/home - zfs create -o setuid=off ${zroot}/usr/ports - zfs create ${zroot}/usr/src - zfs create ${zroot}/usr/obj - zfs create -o mountpoint=/var -o canmount=off ${zroot}/var - zfs create -o exec=off -o setuid=off ${zroot}/var/audit - zfs create -o exec=off -o setuid=off ${zroot}/var/crash - zfs create -o exec=off -o setuid=off ${zroot}/var/log - zfs create -o atime=on ${zroot}/var/mail - zfs create -o setuid=off ${zroot}/var/tmp + zfs create -o mountpoint=none ${tmpzroot}/${ZFS_BEROOT_NAME} + zfs create -o mountpoint=/ ${tmpzroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME} + zfs create -o mountpoint=/tmp -o exec=on -o setuid=off ${tmpzroot}/tmp + zfs create -o mountpoint=/usr -o canmount=off ${tmpzroot}/usr + zfs create ${tmpzroot}/usr/home + zfs create -o setuid=off ${tmpzroot}/usr/ports + zfs create ${tmpzroot}/usr/src + zfs create ${tmpzroot}/usr/obj + zfs create -o mountpoint=/var -o canmount=off ${tmpzroot}/var + zfs create -o exec=off -o setuid=off ${tmpzroot}/var/audit + zfs create -o exec=off -o setuid=off ${tmpzroot}/var/crash + zfs create -o exec=off -o setuid=off ${tmpzroot}/var/log + zfs create -o atime=on ${tmpzroot}/var/mail + zfs create -o setuid=off ${tmpzroot}/var/tmp chmod 1777 ${WRKDIR}/world/tmp ${WRKDIR}/world/var/tmp fi } @@ -115,11 +117,12 @@ zfs_generate() : ${SNAPSHOT_NAME:=$IMAGENAME} FINALIMAGE=${IMAGENAME}.img zroot="${ZFS_POOL_NAME}" - zpool set bootfs=${zroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME} ${zroot} - zpool set autoexpand=on ${zroot} - zfs set canmount=noauto ${zroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME} + tmpzroot="${TMP_ZFS_POOL_NAME}" + zpool set bootfs=${tmpzroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME} ${tmpzroot} + zpool set autoexpand=on ${tmpzroot} + zfs set canmount=noauto ${tmpzroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME} - SNAPSPEC="${zroot}@${SNAPSHOT_NAME}" + SNAPSPEC="${tmpzroot}@${SNAPSHOT_NAME}" msg "Creating snapshot(s) for image generation" zfs snapshot -r "$SNAPSPEC" @@ -137,7 +140,7 @@ zfs_generate() esac case "${MEDIAREMAINDER}" in *be*) - BESNAPSPEC="${zroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME}@${SNAPSHOT_NAME}" + BESNAPSPEC="${tmpzroot}/${ZFS_BEROOT_NAME}/${ZFS_BOOTFS_NAME}@${SNAPSHOT_NAME}" _zfs_writereplicationstream "${BESNAPSPEC}" "${IMAGENAME}.be.zfs" ;; esac @@ -145,7 +148,7 @@ zfs_generate() esac ## When generating a disk image, we need to export the pool first. - zpool export ${zroot} + zpool export ${tmpzroot} zroot= /sbin/mdconfig -d -u ${md#md} md= diff --git a/src/share/poudriere/include/pkg.sh b/src/share/poudriere/include/pkg.sh index 995d89fc..f9beeea3 100644 --- a/src/share/poudriere/include/pkg.sh +++ b/src/share/poudriere/include/pkg.sh @@ -27,7 +27,7 @@ pkg_get_origin() { [ $# -lt 2 ] && eargs pkg_get_origin var_return pkg [origin] local var_return="$1" local pkg="$2" - local _origin=$3 + local _origin="${3-}" local SHASH_VAR_PATH SHASH_VAR_PREFIX= get_pkg_cache_dir SHASH_VAR_PATH "${pkg}" @@ -150,15 +150,15 @@ pkg_get_dep_origin_pkgnames() { while [ $# -ne 0 ]; do origin="$1" pkgname="$2" - compiled_dep_origins="${compiled_dep_origins}${compiled_dep_origins:+ }${origin}" - compiled_dep_pkgnames="${compiled_dep_pkgnames}${compiled_dep_pkgnames:+ }${pkgname}" + compiled_dep_origins="${compiled_dep_origins:+${compiled_dep_origins} }${origin}" + compiled_dep_pkgnames="${compiled_dep_pkgnames:+${compiled_dep_pkgnames} }${pkgname}" shift 2 done if [ -n "${var_return_origins}" ]; then - setvar "${var_return_origins}" "${compiled_dep_origins}" + setvar "${var_return_origins}" "${compiled_dep_origins-}" fi if [ -n "${var_return_pkgnames}" ]; then - setvar "${var_return_pkgnames}" "${compiled_dep_pkgnames}" + setvar "${var_return_pkgnames}" "${compiled_dep_pkgnames-}" fi } @@ -177,14 +177,14 @@ pkg_get_options() { off|false) key="-${key}" ;; on|true) key="+${key}" ;; esac - _compiled_options="${_compiled_options}${_compiled_options:+ }${key}" + _compiled_options="${_compiled_options:+${_compiled_options} }${key}" done <<-EOF $(injail ${PKG_BIN} query -F "/packages/All/${pkg##*/}" '%Ok %Ov' | sort) EOF - shash_set 'pkg' 'options2' "${_compiled_options}" + shash_set 'pkg' 'options2' "${_compiled_options-}" fi if [ -n "${var_return}" ]; then - setvar "${var_return}" "${_compiled_options}" + setvar "${var_return}" "${_compiled_options-}" fi } diff --git a/src/share/poudriere/jail.sh b/src/share/poudriere/jail.sh index 3374bb86..ab464730 100755 --- a/src/share/poudriere/jail.sh +++ b/src/share/poudriere/jail.sh @@ -709,7 +709,7 @@ install_from_ftp() { case $(echo "${FREEBSD_HOST}" | \ tr '[:upper:]' '[:lower:]') in *download.freebsd.org) - URL="${FREEBSD_HOST}/ftp/${type}/${ARCH}/${V}" + URL="${FREEBSD_HOST}/${type}/${ARCH}/${V}" ;; *) URL="${FREEBSD_HOST}/pub/FreeBSD/${type}/${ARCH}/${V}" @@ -773,7 +773,7 @@ install_from_ftp() { case $(echo "${FREEBSD_HOST}" | \ tr '[:upper:]' '[:lower:]') in *download.freebsd.org) - URL="${FREEBSD_HOST}/ftp/${type}/${ARCH%%.*}/${ARCH##*.}/${V}" + URL="${FREEBSD_HOST}/${type}/${ARCH%%.*}/${ARCH##*.}/${V}" ;; *) URL="${FREEBSD_HOST}/pub/FreeBSD/${type}/${ARCH%%.*}/${ARCH##*.}/${V}" diff --git a/src/share/poudriere/pkgclean.sh b/src/share/poudriere/pkgclean.sh index 99a6f7e5..4f3ec505 100755 --- a/src/share/poudriere/pkgclean.sh +++ b/src/share/poudriere/pkgclean.sh @@ -37,6 +37,7 @@ Parameters: [ports...] -- List of ports to keep on the command line Options: + -C -- Delete packages listed on command line rather than keep -j jail -- Which jail to use for packages -J n -- Run n jobs in parallel (Defaults to the number of CPUs times 1.25) @@ -45,6 +46,7 @@ Options: -N -- Do not build the package repository when clean completed -O overlays -- Specify extra ports trees to overlay -p tree -- Which ports tree to use for packages + -r -- With -C delete reverse dependencies too -R -- Clean RESTRICTED packages after building -v -- Be verbose; show more information. Use twice to enable debug output @@ -60,10 +62,12 @@ DRY_RUN=0 DO_ALL=0 BUILD_REPO=1 OVERLAYS="" +CLEAN_LISTED=0 +CLEAN_RDEPS=0 [ $# -eq 0 ] && usage -while getopts "Aaj:J:f:nNO:p:Rvyz:" FLAG; do +while getopts "AaCj:J:f:nNO:p:rRvyz:" FLAG; do case "${FLAG}" in A) DO_ALL=1 @@ -71,6 +75,9 @@ while getopts "Aaj:J:f:nNO:p:Rvyz:" FLAG; do a) ALL=1 ;; + C) + CLEAN_LISTED=1 + ;; j) jail_exists ${OPTARG} || err 1 "No such jail: ${OPTARG}" JAILNAME=${OPTARG} @@ -101,6 +108,9 @@ while getopts "Aaj:J:f:nNO:p:Rvyz:" FLAG; do err 2 "No such ports tree: ${OPTARG}" PTNAME=${OPTARG} ;; + r) + CLEAN_RDEPS=1 + ;; R) NO_RESTRICTED=1 ;; @@ -127,6 +137,13 @@ post_getopts [ -z "${JAILNAME}" ] && \ err 1 "Don't know on which jail to run please specify -j" +if [ "${CLEAN_LISTED}" -eq 1 -a -n "${LISTPKGS}" ]; then + err ${EX_USAGE} "-C and -f should not be used together" +fi +if [ "${CLEAN_LISTED}" -eq 0 -a "${CLEAN_RDEPS}" -eq 1 ]; then + err ${EX_USAGE} "-r only works with -C" +fi + MASTERNAME=${JAILNAME}-${PTNAME}${SETNAME:+-${SETNAME}} _mastermnt MASTERMNT @@ -158,8 +175,16 @@ PKG_EXT='*' package_dir_exists_and_has_packages || maybe_run_queued "${saved_argv}" msg "Gathering all expected packages" +if [ "${CLEAN_LISTED}" -eq 0 ]; then + msg_warn "Will delete anything not listed. To delete listed use -C." +else + msg_warn "Will delete anything listed. To keep listed do not use -C." +fi jail_start "${JAILNAME}" "${PTNAME}" "${SETNAME}" prepare_ports +if ! ensure_pkg_installed; then + err 1 "pkg must be built before this command can be used" +fi msg "Looking for unneeded packages" bset status "pkgclean:" @@ -176,40 +201,97 @@ pkgclean_cleanup() { BADFILES_LIST=$(mktemp -t poudriere_pkgclean) FOUND_ORIGINS=$(mktemp -t poudriere_pkgclean) +should_delete() { + [ $# -eq 1 ] || eargs should_delete pkgfile + local pkgfile="$1" + local pkgname origin ret + + pkgname="${pkgfile##*/}" + pkgname="${pkgname%.*}" + ret=0 + + if ! pkg_get_origin origin "${pkgfile}"; then + msg_verbose "Found corrupt package: ${pkgfile}" + return 0 # delete + fi + if [ "${CLEAN_LISTED}" -eq 0 ]; then + should_delete_unlisted "${pkgfile}" "${origin}" "${pkgname}" || + ret="$?" + elif [ "${CLEAN_LISTED}" -eq 1 ]; then + should_delete_listed "${pkgfile}" "${origin}" "${pkgname}" || + ret="$?" + else + echo "${pkgfile} ${origin}" >> "${FOUND_ORIGINS}" + fi + return "${ret}" +} + +# Handle NO -C +should_delete_unlisted() { + [ $# -eq 3 ] || eargs should_delete_unlisted pkgfile origin pkgname + local pkgfile="$1" + local origin="$2" + local pkgname="$3" + local forbidden + + if shash_remove pkgname-forbidden "${pkgname}" forbidden; then + msg_verbose "Found forbidden package (${COLOR_PORT}${origin}${COLOR_RESET}) (${forbidden}): ${pkgfile}" + return 0 # delete + elif ! pkgbase_is_needed "${pkgname}"; then + msg_verbose "Found unwanted package (${COLOR_PORT}${origin}${COLOR_RESET}): ${pkgfile}" + return 0 # delete + fi + return 1 # keep +} + +# Handle -C and -r +should_delete_listed() { + [ $# -eq 3 ] || eargs should_delete_listed pkgfile origin pkgname + local pkgfile="$1" + local origin="$2" + local pkgname="$3" + local dep_origin compiled_deps + + if originspec_is_listed "${origin}"; then + msg_verbose "Found specified package (${COLOR_PORT}${origin}${COLOR_RESET}): ${pkgfile}" + return 0 # delete + elif ! pkg_get_dep_origin_pkgnames compiled_deps '' "${pkgfile}"; then + msg_verbose "Found corrupt package (${COLOR_PORT}${origin}${COLOR_RESET}) (deps): ${pkgfile}" + return 0 # delete + fi + if [ "${CLEAN_RDEPS}" -eq 1 ]; then + for dep_origin in ${compiled_deps}; do + if originspec_is_listed "${dep_origin}"; then + msg_verbose "Found specified package (${COLOR_PORT}${dep_origin}${COLOR_RESET}) rdep: ${pkgfile}" + return 0 # delete + fi + done + fi + return 1 # keep +} + for file in ${PACKAGES}/All/*; do case ${file} in - *.${PKG_EXT}) - pkgname="${file##*/}" - pkgname="${pkgname%.*}" - if ! pkg_get_origin origin "${file}"; then - msg_verbose "Found corrupt package: ${file}" - echo "${file}" >> ${BADFILES_LIST} - elif shash_remove pkgname-forbidden "${pkgname}" \ - forbidden; then - msg_verbose "Found forbidden package (${forbidden}): ${file}" - echo "${file}" >> ${BADFILES_LIST} - elif ! pkgbase_is_needed "${pkgname}"; then - msg_verbose "Found unwanted package: ${file}" - echo "${file}" >> ${BADFILES_LIST} - else - echo "${file} ${origin}" >> ${FOUND_ORIGINS} - fi - ;; - *.txz) - if [ -L "${file}" ]; then - # Ignore txz symlinks as they otherwise - # cuase spam and confusion. If we delete - # a package it points to then it will be - # removed later by - # delete_stale_symlinks_and_empty_dirs(). - continue - fi - # FALLTHROUGH - ;& - *) - msg_verbose "Found incorrect format file: ${file}" - echo "${file}" >> ${BADFILES_LIST} - ;; + *.${PKG_EXT}) + if should_delete "${file}"; then + echo "${file}" >> "${BADFILES_LIST}" + fi + ;; + *.txz) + if [ -L "${file}" ]; then + # Ignore txz symlinks as they otherwise + # cause spam and confusion. If we delete + # a package it points to then it will be + # removed later by + # delete_stale_symlinks_and_empty_dirs(). + continue + fi + # FALLTHROUGH + ;& + *) + msg_verbose "Found incorrect format file: ${file}" + echo "${file}" >> ${BADFILES_LIST} + ;; esac done |