Add the necessary code to install packages (uninstall and re-install still

pending). Both scripted access (packageAdd) and UI access have been tested
successfully with a variation of different situations including:
+ Install a package with no dependencies
+ Install a package with dependencies that are already installed
+ Install a package with dependencies where some are already installed
+ Repeat each of the above from FTP and local Directory
+ Purposefully do things like try to install a package that does not exist
+ Try to install a package for which a dependency could not be loaded
+ Try to install a package that is in the INDEX bot not on the media
+ And many more.
This commit is contained in:
Devin Teske 2013-07-05 01:44:59 +00:00
parent f687c95d86
commit 31185df0d3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=252745
4 changed files with 290 additions and 1 deletions

View File

@ -34,6 +34,8 @@ hline_arrows_tab_punc_enter="Use arrows, TAB, punctuation, ENTER"
hline_choose_help_for_more_information_on_media_types="Choose Help for more information on the various media types"
msg_accept_continue="Accept/Continue"
msg_accessibility_desc="Ports to help disabled users."
msg_adding_package_as_a_dependency_from_media="Adding %s (as a dependency) from %s"
msg_adding_package_from_media="Adding %s from %s"
msg_afterstep_desc="Ports to support the AfterStep window manager."
msg_all="All"
msg_all_desc="All available packages in all categories."
@ -174,6 +176,7 @@ msg_invalid_ipv4_address="Invalid IPv4 address"
msg_invalid_name_server_ip_address_specified="Invalid name server IP address specified"
msg_invalid_netmask_value="Invalid netmask value"
msg_invalid_nfs_path_specification="Invalid NFS path specification. Must be of the form:\nhost:/full/pathname/to/FreeBSD/distdir"
msg_io_error_while_reading_in_the_package="I/O error while reading in the %s package."
msg_io_or_format_error_on_index_file="I/O or format error on %s file.\nPlease verify media (or path to media) and try again."
msg_ipv4_address="IPv4 Address"
msg_ipv4_gateway="IPv4 Gateway"
@ -196,6 +199,7 @@ msg_length_of_specified_url_is_too_long="Length of specified URL is %u character
msg_linux_desc="Linux programs that can run under binary compatibility."
msg_lisp_desc="Software related to the Lisp language."
msg_lithuania="Lithuania"
msg_loading_of_dependent_package_failed="Loading of dependent package %s failed"
msg_located_index_now_reading_package_data_from_it="Located INDEX, now reading package data from it..."
msg_logging_in_to_user_at_host="Logging in to %s@%s.."
msg_looking_up_host="Looking up host %s"
@ -238,6 +242,7 @@ msg_no_dos_primary_partitions_found="No DOS primary partitions found! This inst
msg_no_floppy_devices_found="No floppy devices found! Please check that your system's configuration\nis correct. For more information, consult the hardware guide in the Doc\nmenu."
msg_no_gateway_has_been_set="No gateway has been set. You will be unable to access hosts\nnot on your local network"
msg_no_network_devices="No network devices available!"
msg_no_package_name_passed_in_package_variable="No package name passed in package variable"
msg_no_packages_were_selected_for_extraction="No packages were selected for extraction."
msg_no_such_file_or_directory="%s: %s: No such file or directory"
msg_no_usb_devices_found="No USB devices found (try Options/Re-scan Devices)"
@ -250,7 +255,9 @@ msg_ok="OK"
msg_options="Options"
msg_options_editor="Options Editor"
msg_other="other"
msg_package_read_successfully_waiting_for_pkg_add="Package %s read successfully - waiting for pkg_add(1)"
msg_package_temp="Package Temp"
msg_package_was_added_successfully="Package %s was added successfully"
msg_packages="packages"
msg_page_of_npages="(Page %s of %s)"
msg_palm_desc="Software support for the Palm(tm) series."
@ -258,6 +265,7 @@ msg_parallel_desc="Applications dealing with parallelism in computing."
msg_pear_desc="Software related to the Pear PHP framework."
msg_perl5_desc="Utilities/modules for the PERL5 language."
msg_permission_denied="%s: %s: Permission denied"
msg_pkg_add_apparently_did_not_like_the_package="pkg_add(1) apparently did not like the %s package."
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):"
@ -301,6 +309,7 @@ msg_quick_start_how_to_use_this_menu_system="Quick start - How to use this menu
msg_reinstall="Reinstall"
msg_reinstall_desc="Mark this package for reinstall"
msg_release_name="Release Name"
msg_required_package_not_found="Warning: %s is a required package but was not found."
msg_rerun_bsdconfig_initial_device_probe="Re-run bsdconfig initial device probe"
msg_rescan_devices="Re-scan Devices"
msg_reset="RESET!"
@ -334,6 +343,7 @@ msg_slovenia="Slovenia"
msg_snapshots_server_japan="Snapshots Server Japan"
msg_snapshots_server_sweden="Snapshots Server Sweden"
msg_sorry_invalid_url="Sorry, %s is an invalid URL!"
msg_sorry_package_was_not_found_in_the_index="Sorry, package %s was not found in the INDEX."
msg_sorry_try_again="Sorry, try again."
msg_south_africa="South Africa"
msg_spain="Spain"
@ -358,8 +368,10 @@ msg_uk="UK"
msg_ukraine="Ukraine"
msg_ukrainian_desc="Ported software for the Ukrainian market."
msg_unable_to_configure_device="Unable to configure the %s interface!\nThis installation method cannot be used."
msg_unable_to_fetch_package_from_selected_media="Unable to fetch package %s from selected media.\nNo package add will be done."
msg_unable_to_get_file_from_selected_media="Unable to get %s file from selected media.\n\nThis may be because the packages collection is not available\non the distribution media you've chosen, most likely an FTP site\nwithout the packages collection mirrored. Please verify that\nyour media, or your path to the media, is correct and try again."
msg_unable_to_get_proper_ftp_path="Unable to get proper FTP path. FTP media not initialized."
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_uninstall="Uninstall"

View File

@ -242,6 +242,44 @@ f_index_extract_pages()
)"
}
# f_index_search $var_to_get $name [$var_to_set]
#
# Search the package INDEX ($PACKAGE_INDEX by default if/when $var_to)get is
# NULL; but should not be missing) for $name, returning the first match.
# Matches are strict (not regular expressions) and must match the beginning
# portion of the package name to be considered a match. If $var_to_set is
# missing or NULL, output is sent to standard output. If a match is found,
# returns success; otherwise failure.
#
f_index_search()
{
local __var_to_get="${1:-PACKAGE_INDEX}" __pkg_basename="$2"
local __var_to_set="$3"
f_dprintf "f_index_search: Searching package data (in %s) for %s" \
"$__var_to_get" "$__pkg_basename"
local __pkg=
__pkg=$( debug= f_getvar "$__var_to_get" |
awk -F'|' -v basename="$__pkg_basename" '
BEGIN { n = length(basename) }
substr($1, 0, n) == basename { print $1; exit }
' )
if [ ! "$__pkg" ]; then
f_dprintf "f_index_search: No packages matching %s found" \
"$__pkg_basename"
return $FAILURE
fi
f_dprintf "f_index_search: Found package %s" "$__pkg"
if [ "$__var_to_set" ]; then
setvar "$__var_to_set" "$__pkg"
else
echo "$__pkg"
fi
return $SUCCESS
}
############################################################ MAIN
f_dprintf "%s: Successfully loaded." packages/index.subr

View File

@ -32,6 +32,8 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
. $BSDCFG_SHARE/common.subr || exit 1
f_dprintf "%s: loading includes..." "$0"
f_include $BSDCFG_SHARE/dialog.subr
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/strings.subr
@ -48,9 +50,15 @@ f_include_lang $BSDCFG_LIBE/include/messages.subr
############################################################ GLOBALS
#
# Package extensions to try
#
PACKAGE_EXTENSIONS=".tbz .tbz2 .tgz"
#
# Variables used to track runtime states
#
PACKAGES_DETECTED= # Boolean (NULL/non-NULL); detected installed packages?
PACKAGE_CATEGORIES= # List of package categories parsed from INDEX
SELECTED_PACKAGES= # Packages selected by user in [X]dialog(1) interface
@ -629,7 +637,7 @@ f_package_review()
f_str2varname "$package" varpkg
f_getvar _mark_$varpkg mark
[ "$mark" = "I" ] || continue
# XXX Install package
f_package_add "$package" || continue
f_package_deselect "$package"
done
for package in $SELECTED_PACKAGES; do
@ -812,6 +820,236 @@ f_package_config()
done
}
# f_package_add $package_name [$depended]
#
# Like f_package_extract(), but assumes current media device and chases deps.
# Note that $package_name should not contain the archive suffix (e.g., `.tbz').
# If $depended is present and non-NULL, the package is treated as a dependency
# (in this function, dependencies are not handled any differently, but the
# f_package_extract() function is passed this value and it displays a different
# message when installing a dependency versus non-dependency).
#
f_package_add()
{
local name="$1" depended="$2" status=$SUCCESS retval
local alert=f_show_msg no_confirm=
f_getvar $VAR_NO_CONFIRM no_confirm
[ "$no_confirm" ] && alert=f_show_info
if ! { [ "$name" ] || { f_getvar $VAR_PACKAGE name && [ "$name" ]; }; }
then
f_dprintf "packageAdd: %s" \
"$msg_no_package_name_passed_in_package_variable"
return $FAILURE
fi
{ # Verify and initialize device media if-defined
f_media_verify &&
f_device_init media &&
f_index_initialize packages/INDEX
} || return $FAILURE
# Now we have (indirectly via f_index_read()):
# CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg}
# PACKAGE_CATEGORIES _npkgs
local varpkg
f_str2varname "$name" varpkg
# Just as-in the user-interface (opposed to scripted-use), only allow
# packages with at least one category to be recognized.
#
local pkgcat=
if ! f_getvar _categories_$varpkg pkgcat || [ ! "$pkgcat" ]; then
# $pkg may be a partial name, search the index (this is slow)
f_index_search PACKAGE_INDEX $name name
if [ ! "$name" ]; then
f_show_msg \
"$msg_sorry_package_was_not_found_in_the_index" \
"$name"
return $FAILURE
fi
f_str2varname "$name" varpkg
fi
# If invoked through the scripted interface, we likely have not yet
# detected the installed packages -- something we should do only once.
#
if [ ! "$PACKAGES_DETECTED" ]; then
f_package_detect_installed
export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[]
fi
# Now we have: _mark_{varpkg}=X for all installed packages
#
# Since we're maintaining data structures for installed packages,
# short-circuit the package dependency checks if the package is already
# installed. This prevents wasted cycles, minor delays between package
# extractions, and worst-case an infinite loop with a certain faulty
# INDEX file.
#
local mark=
f_getvar _mark_$varpkg mark && [ "$mark" = "X" ] && return $SUCCESS
local dep vardep rundeps=
f_getvar _rundeps_$varpkg rundeps
for dep in $rundeps; do
f_str2varname "$dep" vardep
# Skip dependency if already installed
mark=
f_getvar _mark_$vardep mark && [ "$mark" = "X" ] && continue
# Just as-in the user-interface (opposed to scripted-use), only
# allow packages with at least one category to be recognized.
#
local depcat=
if ! f_getvar _categories_$vardep depcat || [ ! "$depcat" ]
then
$alert "$msg_required_package_not_found" "$dep"
[ "$no_confirm" ] && sleep 2
fi
f_package_add "$dep"
retval=$?
if [ $retval -ne $SUCCESS ]; then
status=$(( $status | $retval ))
# XXX package could be on a future disc volume
# XXX (not supporting multiple disc volumes yet)
$alert "$msg_loading_of_dependent_package_failed" \
"$dep"
[ "$no_confirm" ] && sleep 2
fi
done
[ $status -eq $SUCCESS ] || return $status
#
# Done with the deps? Try to load the real m'coy.
#
f_package_extract media "$name" "$depended"
retval=$?
if [ $retval -ne $SUCCESS ]; then
status=$(( $status | $retval ))
else
setvar _mark_$varpkg X
fi
return $status
}
# f_package_extract $device $name [$depended]
#
# Extract a package based on a namespec and media device. If $depended is
# present and non-NULL, the notification displayed while installing the package
# has "as a dependency" appended.
#
f_package_extract()
{
local device="$1" name="$2" depended="$3"
# Check to make sure it's not already there
local varpkg mark=
f_str2varname "$name" varpkg
f_getvar _mark_$varpkg mark
[ "$mark" = "X" ] && return $SUCCESS
if ! f_device_init $device; then
f_show_msg \
"$msg_unable_to_initialize_media_type_for_package_extract"
return $FAILURE
fi
# If necessary, initialize the ldconfig hints
[ -f "/var/run/ld-elf.so.hints" ] ||
f_quietly ldconfig /usr/lib /usr/lib/compat /usr/local/lib
# Make a couple paranoid locations for temp
# files to live if user specified none
local tmpdir
f_getvar $VAR_PKG_TMPDIR:-/var/tmp tmpdir
f_quietly mkdir -p -m 1777 "$tmpdir"
local path
case "$name" in
*/*) path="$name" ;;
*)
case "$name" in
*-*|*_*) path="packages/All/$name" ;;
*) path="packages/Latest/$name"
esac
esac
local fname=f_package_extract
# We have a path, call the device strategy routine to get the file
local pkg_ext probe_only=1 found=
for pkg_ext in "" $PACKAGE_EXTENSIONS; do
if f_device_get $device "$path$pkg_ext" $probe_only; then
path="$path$pkg_ext"
f_dprintf "%s: found path=[%s] dev=[%s]" \
$fname "$path" "$device"
found=1
break
fi
done
local alert=f_show_msg no_confirm=
f_getvar $VAR_NO_CONFIRM no_confirm
[ "$no_confirm" ] && alert=f_show_info
if [ ! "$found" ]; then
f_dprintf "%s: No such %s file on %s device" \
$fname "$path" "$device"
$alert "$msg_unable_to_fetch_package_from_selected_media" \
"$name"
[ "$no_confirm" ] && sleep 2
return $FAILURE
fi
local devname=
f_struct device_$device get name devname
if [ "$depended" ]; then
f_show_info "$msg_adding_package_as_a_dependency_from_media" \
"$name" "$devname"
else
f_show_info "$msg_adding_package_from_media" "$name" "$devname"
fi
# Get package data and pipe into pkg_add(1) while providing feedback
{
if ! f_device_get $device "$path"; then
$alert "$msg_io_error_while_reading_in_the_package" \
"$name" \
>&$DIALOG_TERMINAL_PASSTHRU_FD 2> /dev/null
[ "$no_confirm" ] && sleep 2
else
f_show_info \
"$msg_package_read_successfully_waiting_for_pkg_add" \
"$name" >&$DIALOG_TERMINAL_PASSTHRU_FD 2> /dev/null
fi
} | {
if f_debugging; then
/usr/sbin/pkg_add -v -
else
f_quietly /usr/sbin/pkg_add -
fi
}
if [ $? -ne $SUCCESS ]; then
$alert "$msg_pkg_add_apparently_did_not_like_the_package" \
"$name"
[ "$no_confirm" ] && sleep 2
else
f_show_info "$msg_package_was_added_successfully" "$name"
sleep 1
fi
return $SUCCESS
}
############################################################ MAIN
f_dprintf "%s: Successfully loaded." packages/packages.subr

View File

@ -190,6 +190,7 @@ f_resword_new mediaSetHTTPProxy f_media_set_http_proxy
# packages/packages.subr
f_resword_new configPackages f_package_config
f_resword_new packageAdd f_package_add
# variable.subr
f_resword_new installVarDefaults f_variable_set_defaults