Add example script `add_some_packages.sh', demonstrating how to install

a list of packages using the bsdconfig(8) API, providing dialog(8) based
user experience (versus plain console output were you to use pkg(8)
directly to install the same list of packages).

Remove example script `browse_packages_ftp.sh', made obsolete because
the digests.txz and packagesite.txz databases for pkg(8) are not
available via FTP (HTTP only to pkg.freebsd.org SRV hosts).

Update example script `browse_packages_http.sh', made to work with new
pkg(8) demonstrating how to generate a local package repository.

Fix a bug in `bsdconfig packages' where packages were listed twice. This
fix requires pkg(8) version 1.2.7_4 or higher.

NB: It is the introduction of pkg(8) 1.2.7_4 wherein I am also able to
drastically reduce the generation time of package dependencies prior to
the dialog display (by utilizing the new `-I' flag to pkg-rquery(8)).

While here, fix a positional argument nit for f_index_initialize() of
`packages/index.subr' include (the one and only argument is positional
argument 1 to state the by-ref handle, indicating the variable to set
in the caller's namespace; the nit I'm fixing here is that we were
querying positional argument 2 for this information incorrectly; caused
by a missing hunk back around SVN r257795).

Fix a bug in sysrc(8) described by PR bin/187458 "sysrc(8) silently and
unexpectedly bootstraps pkg". This was caused by an explicit entry in
`/usr/share/bsdconfig/common.subr' (used by sysrc(8)) that called pkg(8)
to populate the $PKG_ABI global (called in a way that allows implicit
bootstrap of pkg(8)). The solution to which was to find every place in
bsdconfig(8) that requires the $PKG_ABI global and add a layer of
protection by way of introducing the new API call f_musthavepkg_init()
(provided by new include, `/usr/share/bsdconfig/packages/musthavepkg.subr'
intented to mirror `/usr/share/bsdconfig/mustberoot.subr'). When the
$PKG_ABI global is required, you can use `f_musthavepkg_init' to cause
graceful premature termination in the event that pkg(8) has not yet been
bootstrapped, and thus cannot be used to populate $PKG_ABI.

NB: If running interactively ($nonInteractive is NULL or unset), the
f_musthavepkg_init() API call will attempt to bootstrap pkg(8), but only
if the user chooses "Yes" to a Yes/No dialog confirming it is ok to
bootstrap.

While here, simplify an if-conditional in `media/http.subr' include to
use sh(1) inline assignment-with-break.

Also, fix a bug in `media/http.subr' and `media/httpproxy.subr' wherein
the error messages for various HTTP failures were not finding their way
to the console (needed to pass stdout to pass-thru descriptor).

While here, remove the executable bit from `packages/categories.subr',
`packages/index.subr', and `packages/packages.subr' includes.

Fix issues where pkg(8) complains about PACKAGESITE being defined.
Previously, we would set $PACKAGESITE and export it. Now we only set
$PACKAGESITE for invocations of "pkg update" -- getting rid of all the
spurious warnings about PACKAGESITE being deprecated (it's still used
in the case of "pkg update" for simplicity versus having to configure
a config-file).

Remove the leading argument from invocations of f_index_initialize() in
`packages/packages.subr' include. The leading argument no longer means
what it used to, pre SVN r257995).

PR:		bin/187458
Reviewed by:	nwhitehorn
MFC after:	1 week
X-MFC-to:	stable/10, stable/9
This commit is contained in:
Devin Teske 2014-07-22 23:10:12 +00:00
parent bad752d40f
commit 95d45410b5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268999
13 changed files with 147 additions and 133 deletions

View File

@ -3,7 +3,7 @@
NO_OBJ=
FILESDIR= ${SHAREDIR}/examples/bsdconfig
FILES= browse_packages_ftp.sh browse_packages_http.sh bsdconfigrc
FILES= add_some_packages.sh browse_packages_http.sh bsdconfigrc
beforeinstall:
mkdir -p ${DESTDIR}${FILESDIR}

View File

@ -0,0 +1,13 @@
#!/bin/sh
# $FreeBSD$
#
# This sample installs a short list of packages from the main HTTP site.
#
[ "$_SCRIPT_SUBR" ] || . /usr/share/bsdconfig/script.subr || exit 1
nonInteractive=1
_httpPath=http://pkg.freebsd.org
mediaSetHTTP
mediaOpen
for package in wget bash rsync; do
packageAdd
done

View File

@ -1,25 +0,0 @@
#!/bin/sh
# $FreeBSD$
#
# This sample downloads the package INDEX file from FTP to /tmp (if it doesn't
# already exist) and then displays the package configuration/management screen
# using the local INDEX file (results in faster browsing of packages from-start
# since the INDEX can be loaded from local media).
#
# NOTE: Packages cannot be installed unless staged to /tmp/packages/All
#
. /usr/share/bsdconfig/script.subr
nonInteractive=1
TMPDIR=/tmp
if [ ! -e "$TMPDIR/packages/INDEX" ]; then
[ -d "$TMPDIR/packages" ] || mkdir -p "$TMPDIR/packages" || exit 1
_ftpPath=ftp://ftp.freebsd.org
# For older releases, use ftp://ftp-archive.freebsd.org
mediaSetFTP
mediaOpen
f_show_info "Downloading packages/INDEX from\n %s" "$_ftpPath"
f_device_get device_media packages/INDEX > $TMPDIR/packages/INDEX
fi
_directoryPath=$TMPDIR
mediaSetDirectory
configPackages

View File

@ -1,25 +1,32 @@
#!/bin/sh
# $FreeBSD$
#
# This sample downloads the package INDEX file from HTTP to /tmp (if it doesn't
# already exist) and then displays the package configuration/management screen
# using the local INDEX file (results in faster browsing of packages from-start
# since the INDEX can be loaded from local media).
# This sample downloads the package digests.txz and packagesite.txz files from
# HTTP to /tmp (if they don't already exist) and then displays the package
# configuration/management screen using the local files (resulting in faster
# browsing of packages from-start since digests.txz/packagesite.txz can be
# loaded from local media).
#
# NOTE: Packages cannot be installed unless staged to /tmp/packages/All
# NOTE: Packages cannot be installed unless staged to
# /tmp/packages/$PKG_ABI/All
#
. /usr/share/bsdconfig/script.subr
[ "$_SCRIPT_SUBR" ] || . /usr/share/bsdconfig/script.subr || exit 1
nonInteractive=1
f_musthavepkg_init # Make sure we have a usable pkg(8) with $PKG_ABI
TMPDIR=/tmp
if [ ! -e "$TMPDIR/packages/INDEX" ]; then
[ -d "$TMPDIR/packages" ] || mkdir -p "$TMPDIR/packages" || exit 1
_httpPath=http://ftp.freebsd.org
# For older releases, use http://ftp-archive.freebsd.org
mediaSetHTTP
mediaOpen
f_show_info "Downloading packages/INDEX from\n %s" "$_httpPath"
f_device_get device_media packages/INDEX > $TMPDIR/packages/INDEX
fi
PKGDIR=$TMPDIR/packages/$PKG_ABI
[ -d "$PKGDIR" ] || mkdir -p "$PKGDIR" || exit 1
for file in digests.txz packagesite.txz; do
[ -s "$PKGDIR/$file" ] && continue
if [ ! "$HTTP_INITIALIZED" ]; then
_httpPath=http://pkg.freebsd.org
mediaSetHTTP
mediaOpen
fi
f_show_info "Downloading %s from\n %s" "$file" "$_httpPath"
f_device_get device_media "/$PKG_ABI/latest/$file" > $PKGDIR/$file ||
exit 1
done
_directoryPath=$TMPDIR
mediaSetDirectory
configPackages

View File

@ -57,6 +57,7 @@ msg_back="Back"
msg_becoming_root_via_sudo="Becoming root via sudo(8)..."
msg_benchmarks_desc="Utilities for measuring system performance."
msg_biology_desc="Software related to biology."
msg_bootstrapping_pkg="Bootstrapping pkg(8)..."
msg_brazil="Brazil"
msg_building_package_menus="Building package menu(s)..."
msg_cad_desc="Computer Aided Design utilities."
@ -142,8 +143,6 @@ msg_generating_index_from_pkg_database="Generating INDEX from pkg(8) database\n(
msg_geography_desc="Geography-related software."
msg_german_desc="Ported software for Germanic countries."
msg_germany="Germany"
msg_getting_package_categories_via_pkg_rquery="Getting package categories via pkg-rquery(8)..."
msg_getting_package_dependencies_via_pkg_rquery="Getting package dependencies via pkg-rquery(8)\n(this can take a while)..."
msg_gnome_desc="Components of the Gnome Desktop environment."
msg_gnustep_desc="Software for GNUstep desktop environment."
msg_graphics_desc="Graphics libraries and utilities."
@ -219,6 +218,7 @@ msg_misc_desc="Miscellaneous utilities."
msg_missing_ftp_host_or_directory="Missing FTP host or directory specification. FTP media not initialized."
msg_multimedia_desc="Multimedia software."
msg_must_be_root_to_execute="%s: must be root to execute"
msg_must_have_pkg_to_execute="%s: must have pkg(8) to execute"
msg_must_specify_a_host_name_of_some_sort="Must specify a host name of some sort!"
msg_name_server="Name server"
msg_net_desc="Networking utilities."
@ -274,6 +274,7 @@ msg_perl5_desc="Utilities/modules for the PERL5 language."
msg_permission_denied="%s: %s: Permission denied"
msg_pkg_delete_failed="Warning: pkg-delete(8) of %s failed.\n Run with debugging for details."
msg_pkg_install_apparently_did_not_like_the_package="pkg-install(8) apparently did not like the %s package."
msg_pkg_not_yet_installed_install_now="pkg(8) not yet installed. Install now?"
msg_plan9_desc="Software from the Plan9 operating system."
msg_please_check_the_url_and_try_again="No such directory: %s\nplease check the URL and try again.\n"
msg_please_enter_password="Please enter your password for sudo(8):"
@ -376,15 +377,13 @@ msg_unable_to_get_proper_ftp_path="Unable to get proper FTP path. FTP media not
msg_unable_to_initialize_media_type_for_package_extract="Unable to initialize media type for package extract."
msg_unable_to_make_directory_mountpoint="Unable to make %s directory mountpoint for %s!"
msg_unable_to_open="Unable to open %s"
msg_unable_to_pkg_rquery_package_categories="Unable to pkg-rquery(8) package categories!"
msg_unable_to_pkg_rquery_package_dependencies="Unable to pkg-rquery(8) package dependencies!"
msg_unable_to_update_pkg_from_selected_media="Unable to update pkg(8) from selected media."
msg_uninstall="Uninstall"
msg_uninstall_desc="Mark this package for deletion"
msg_uninstalling_package_waiting_for_pkg_delete="Uninstalling %s package - waiting for pkg-delete(8)"
msg_unknown="unknown"
msg_unknown_user="Unknown user: %s"
msg_url_was_not_found="%s was not found, maybe directory or release-version are wrong?"
msg_url_was_not_found="%s was not found,\nmaybe directory or release-version are wrong?"
msg_usa="USA"
msg_usage="Usage"
msg_usb="USB"

View File

@ -62,12 +62,6 @@ export UNAME_S="$( uname -s )" # Operating System (i.e. FreeBSD)
export UNAME_P="$( uname -p )" # Processor Architecture (i.e. i386)
export UNAME_M="$( uname -m )" # Machine platform (i.e. i386)
export UNAME_R="$( uname -r )" # Release Level (i.e. X.Y-RELEASE)
if [ ! "${PKG_ABI+set}" ]; then
export PKG_ABI="$(
ASSUME_ALWAYS_YES=1 pkg -vv 2> /dev/null |
awk '$1=="ABI"{print $3;exit}'
)"
fi
#
# Default behavior is to call f_debug_init() automatically when loaded.

View File

@ -515,10 +515,7 @@ f_media_init_http()
fi
esac
if [ $http_found -eq $SUCCESS ]; then
HTTP_INITIALIZED=YES
break
fi
[ $http_found -eq $SUCCESS ] && HTTP_INITIALIZED=YES break
f_getvar $VAR_HTTP_PATH http_path
f_show_msg "$msg_please_check_the_url_and_try_again" \
@ -668,7 +665,7 @@ f_media_get_http()
44) f_show_msg "$msg_url_was_not_found" "$url" ;;
4) f_show_msg "$msg_client_error" ;;
*) f_show_msg "$msg_error_when_requesting_url" "$url" ;;
esac
esac 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
return $FAILURE
}

View File

@ -452,7 +452,7 @@ f_media_get_http_proxy()
44) f_show_msg "$msg_url_was_not_found" "$url" ;;
4) f_show_msg "$msg_client_error" ;;
*) f_show_msg "$msg_error_when_requesting_url" "$url" ;;
esac
esac 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
return $FAILURE
}

View File

@ -3,7 +3,7 @@
NO_OBJ=
FILESDIR= ${SHAREDIR}/bsdconfig/packages
FILES= categories.subr index.subr packages.subr
FILES= categories.subr index.subr musthavepkg.subr packages.subr
beforeinstall:
mkdir -p ${DESTDIR}${FILESDIR}

0
usr.sbin/bsdconfig/share/packages/categories.subr Executable file → Normal file
View File

81
usr.sbin/bsdconfig/share/packages/index.subr Executable file → Normal file
View File

@ -33,6 +33,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
f_dprintf "%s: loading includes..." packages/index.subr
f_include $BSDCFG_SHARE/device.subr
f_include $BSDCFG_SHARE/media/common.subr
f_include $BSDCFG_SHARE/packages/musthavepkg.subr
f_include $BSDCFG_SHARE/strings.subr
BSDCFG_LIBE="/usr/libexec/bsdconfig"
@ -53,27 +54,6 @@ SQLITE_REPO="/var/db/pkg/repo-packagesite.sqlite"
#
PACKAGES_INDEX_CACHEFILE="/var/run/bsdconfig/packages_INDEX.cache"
#
# INDEX format for FreeBSD-6.0 or higher:
#
# package|port-origin|install-prefix|comment|port-desc-file|maintainer|
# categories|build-deps|run-deps|www-site|reserve|reserve|reserve|disc
#
INDEX_FORMAT="%n-%v" # package
INDEX_FORMAT="$INDEX_FORMAT|/usr/ports/%o" # port-origin
INDEX_FORMAT="$INDEX_FORMAT|%p" # install-prefix
INDEX_FORMAT="$INDEX_FORMAT|%c" # comment
INDEX_FORMAT="$INDEX_FORMAT|/usr/ports/%o/pkg-descr" # port-desc-file
INDEX_FORMAT="$INDEX_FORMAT|%m" # maintainer
INDEX_FORMAT="$INDEX_FORMAT|@CATEGORIES@" # place-holder
INDEX_FORMAT="$INDEX_FORMAT|" # build-deps
INDEX_FORMAT="$INDEX_FORMAT|@RUNDEPS@" # place-holder
INDEX_FORMAT="$INDEX_FORMAT|%w" # www-site
INDEX_FORMAT="$INDEX_FORMAT|" # reserved
INDEX_FORMAT="$INDEX_FORMAT|" # reserved
INDEX_FORMAT="$INDEX_FORMAT|" # reserved
INDEX_FORMAT="$INDEX_FORMAT|" # disc
############################################################ FUNCTIONS
# f_index_initialize [$var_to_set]
@ -87,13 +67,16 @@ INDEX_FORMAT="$INDEX_FORMAT|" # disc
f_index_initialize()
{
local __funcname=f_index_initialize
local __var_to_set="${2:-PACKAGE_INDEX}"
local __var_to_set="${1:-PACKAGE_INDEX}"
[ "$_INDEX_INITTED" ] && return $SUCCESS
# Got any media?
f_media_verify || return $FAILURE
# Make sure we have a usable pkg(8) with $PKG_ABI
f_musthavepkg_init
# Does it move when you kick it?
f_device_init device_media || return $FAILURE
@ -126,9 +109,10 @@ f_index_initialize()
__site="file://$MOUNTPOINT/packages/$PKG_ABI"
esac
export PACKAGESITE="$__site"
f_dprintf "PACKAGESITE=[%s]" "$PACKAGESITE"
if ! f_eval_catch $__funcname pkg "pkg update"; then
f_dprintf "PACKAGESITE=[%s]" "$__site"
if ! f_eval_catch $__funcname pkg \
'PACKAGESITE="%s" pkg update' "$__site"
then
f_show_err "$msg_unable_to_update_pkg_from_selected_media"
f_device_shutdown device_media
return $FAILURE
@ -195,53 +179,8 @@ f_index_initialize()
# If we reach this point, we need to generate the data from scratch
#
f_show_info "$msg_getting_package_categories_via_pkg_rquery"
if ! eval "$( pkg rquery "%n-%v %C" | awk '
{ categories[$1] = categories[$1] " " $2 }
END {
for (package in categories)
{
cats = categories[package]
sub(/^ /, "", cats)
gsub(/[^[:alnum:]_]/, "_", package)
printf "local _%s_categories=\"%s\";\n", package, cats
}
}' )"; then
f_show_err "$msg_unable_to_pkg_rquery_package_dependencies"
f_device_shutdown device_media
return $FAILURE
fi
f_show_info "$msg_getting_package_dependencies_via_pkg_rquery"
if ! eval "$( pkg rquery "%n-%v %dn-%dv" | awk '
{ rundeps[$1] = rundeps[$1] " " $2 }
END {
for (package in rundeps)
{
deps = rundeps[package]
sub(/^ /, "", deps)
gsub(/[^[:alnum:]_]/, "_", package)
printf "local _%s_rundeps=\"%s\";\n", package, deps
}
}' )"; then
f_show_err "$msg_unable_to_pkg_rquery_package_dependencies"
f_device_shutdown device_media
return $FAILURE
fi
f_show_info "$msg_generating_index_from_pkg_database"
eval "$__var_to_set"='$( pkg rquery "$INDEX_FORMAT" |
while read LINE; do
package="${LINE%%|*}";
f_str2varname "$package" varpkg;
eval f_replaceall \"\$LINE\" \"\|@CATEGORIES@\|\" \
\"\|\$_${varpkg}_categories\|\" LINE
eval f_replaceall \"\$LINE\" \"\|@RUNDEPS@\|\" \
\"\|\$_${varpkg}_rundeps\|\" LINE
echo "$LINE"
done
)' # always returns true (status of last item in pipe-chain)
eval "$__var_to_set"='$( debug= f_getvar "$__var_to_set" | sort )'
eval "$__var_to_set"='$( pkg rquery -I | sort )'
#
# Attempt to create the persistant on-disk cache

View File

@ -0,0 +1,87 @@
if [ ! "$_PACKAGES_MUSTHAVEPKG_SUBR" ]; then _PACKAGES_MUSTHAVEPKG_SUBR=1
#
# Copyright (c) 2014 Devin Teske
# 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.
#
# $FreeBSD$
#
############################################################ INCLUDES
BSDCFG_SHARE="/usr/share/bsdconfig"
. $BSDCFG_SHARE/common.subr || exit 1
f_dprintf "%s: loading includes..." packages/musthavepkg.subr
f_include $BSDCFG_SHARE/dialog.subr
f_include $BSDCFG_SHARE/mustberoot.subr
############################################################ FUNCTIONS
# f_musthavepkg_init
#
# Validate pkg(8) is installed and set $PKG_ABI global if not already set.
# Returns success unless pkg(8) is not installed and user refuses to install
# it (upon prompt when running interactively).
#
f_musthavepkg_init()
{
local funcname=f_musthavepkg_init
local pkg_abi_awk='$1~/^ABI/{print $NF; exit}'
if [ "$PKG_ABI" ]; then # Already set
f_dprintf "PKG_ABI=[%s]" "$PKG_ABI"
export PKG_ABI
f_quietly pkg -N -vv # return status (pkg(8) functional?)
return $?
fi
# Attempt to get PKG_ABI without prematurely bootstrapping pkg(8)
if f_eval_catch -k PKG_ABI $funcname pkg \
"pkg -N -vv | awk '%s'" "$pkg_abi_awk"
then
f_dprintf "PKG_ABI=[%s]" "$PKG_ABI"
export PKG_ABI
return $SUCCESS
fi
# pkg(8) not yet bootstrapped; ask for permission unless nonInteractive
f_dialog_yesno "$msg_pkg_not_yet_installed_install_now" ||
f_die 1 "$msg_must_have_pkg_to_execute" "$pgm"
f_mustberoot_init # Have to be root to install pkg(8)
# Bootstrap pkg(8)
f_dialog_info "$msg_bootstrapping_pkg"
f_eval_catch -k PKG_ABI $funcname pkg \
"ASSUME_ALWAYS_YES=1 pkg -vv | awk '%s'" "$pkg_abi_awk" ||
f_die 1 "$msg_must_have_pkg_to_execute" "$pgm"
f_dprintf "PKG_ABI=[%s]" "$PKG_ABI"
export PKG_ABI
return $SUCCESS
}
############################################################ MAIN
f_dprintf "%s: Successfully loaded." packages/musthavepkg.subr
fi # ! $_PACKAGES_MUSTHAVEPKG_SUBR

9
usr.sbin/bsdconfig/share/packages/packages.subr Executable file → Normal file
View File

@ -36,6 +36,7 @@ f_include $BSDCFG_SHARE/device.subr
f_include $BSDCFG_SHARE/media/common.subr
f_include $BSDCFG_SHARE/packages/categories.subr
f_include $BSDCFG_SHARE/packages/index.subr
f_include $BSDCFG_SHARE/packages/musthavepkg.subr
f_include $BSDCFG_SHARE/strings.subr
BSDCFG_LIBE="/usr/libexec/bsdconfig"
@ -662,7 +663,7 @@ f_package_review()
f_package_config()
{
# Did we get an INDEX?
f_index_initialize packages/INDEX || return $FAILURE
f_index_initialize || return $FAILURE
# Creates following variables (indirectly via f_index_read())
# CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg}
# PACKAGE_CATEGORIES _npkgs
@ -839,7 +840,7 @@ f_package_add()
{ # Verify and initialize device media if-defined
f_media_verify &&
f_device_init device_media &&
f_index_initialize packages/INDEX
f_index_initialize
} || return $FAILURE
# Now we have (indirectly via f_index_read()):
@ -946,6 +947,8 @@ f_package_extract()
local device="$1" name="$2" depended="$3"
local devname=
f_musthavepkg_init # Make sure we have a usable pkg(8) with $PKG_ABI
$device get name devname
f_dprintf "$funcname: device=[%s] name=[%s] depended=[%s]" \
"$devname" "$name" "$depended"
@ -1065,7 +1068,7 @@ f_package_delete()
{ # Verify and initialize device media if-defined
f_media_verify &&
f_device_init device_media &&
f_index_initialize packages/INDEX
f_index_initialize
} || return $FAILURE
# Now we have (indirectly via f_index_read()):