summaryrefslogtreecommitdiffstats
path: root/src/etc
diff options
context:
space:
mode:
authorstilez <stilez@users.noreply.github.com>2017-01-22 10:33:37 +0000
committerRenato Botelho <renato@netgate.com>2017-01-30 13:33:26 -0200
commit5e446a2510683917bb3c5079bb217211b16fd6a8 (patch)
tree2ca6c283543357eaee0fe8f8c70f041c7acb283c /src/etc
parent129a43703414ef81e95db39fe5e8762d1218e9b2 (diff)
downloadpfsense-5e446a2510683917bb3c5079bb217211b16fd6a8.zip
pfsense-5e446a2510683917bb3c5079bb217211b16fd6a8.tar.gz
get_pkg_info() fallback using pkg info if no local copy of repo catalog (resubmit)
Resubmit of PR #3157 with fix. The issue in #3157 was that `pkg info` and `pkg search`, undocumented in man pages, seem to handle things differently if no packages match the pattern string. `pkg search` gives an error "No packages match [$pkgs]", whereas `pkg search` doesn't give an error. I didn't come across this because it's not stated in the man pages for pkg info, and because I tested it with a bare install but at least one pkg, while @NYOB used it on a bare install. The fix which I've tested and seems to work nicely, is to test using `pkg info -e` whether the pkg info call will hit a "no packages exist" issue or not. If `pkg info -e` returns 0 then it's safe as there's at least one matching pkg (any other errors are allowed to occur and be detected as usual). If it returns anything else, then there's no matching pkgs, so the main `pkg info` is skipped leaving $out and other variables at the correct values they need anyway, showing a null match/none found. For details of the underlying issue being fixed, and the issue that this resubmit fixes, see the original PR. (cherry picked from commit 587988f6df7e1d3b1a369b93a5634620129e3d9d)
Diffstat (limited to 'src/etc')
-rw-r--r--src/etc/inc/pkg-utils.inc40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/etc/inc/pkg-utils.inc b/src/etc/inc/pkg-utils.inc
index 0e13e88..6420925 100644
--- a/src/etc/inc/pkg-utils.inc
+++ b/src/etc/inc/pkg-utils.inc
@@ -372,11 +372,13 @@ function get_package_internal_name($package_data) {
}
// Get information about packages.
-function get_pkg_info($pkgs = 'all', $only_local = false) {
+function get_pkg_info($pkgs = 'all', $local_only = false, $installed_only = false) {
+
global $g, $input_errors;
$out = '';
$err = '';
+ $rc = 0;
unset($pkg_filter);
if (is_array($pkgs)) {
@@ -385,7 +387,7 @@ function get_pkg_info($pkgs = 'all', $only_local = false) {
}
if ($pkgs == 'all') {
- $pkgs = $g['pkg_prefix'];
+ $pkgs = $g['pkg_prefix'] . '*'; // Allows same prefix to work with both pkg search + pkg info
}
if (!function_exists('is_subsystem_dirty')) {
@@ -394,21 +396,46 @@ function get_pkg_info($pkgs = 'all', $only_local = false) {
/* Do not run remote operations if pkg has a lock */
if (is_subsystem_dirty('pkg')) {
- $only_local = true;
+ $local_only = true;
$lock = false;
} else {
$lock = true;
}
$extra_param = "";
- if ($only_local) {
+ if ($local_only) {
$extra_param = "-U ";
}
if ($lock) {
mark_subsystem_dirty('pkg');
}
- $rc = pkg_exec("search {$extra_param}-R --raw-format json-compact " . $pkgs, $out, $err);
+
+ if (!$installed_only) {
+ // repo catalog search (either remote or local_only)
+ $rc = pkg_exec("search {$extra_param}-R --raw-format json-compact " . $pkgs, $out, $err);
+ }
+ if ($installed_only || ($local_only && $rc != 0)) {
+ /* use pkg info if (1) installed pkg search or (2) local catalog copy search requested + failed.
+ *
+ * The local repo catalog copy may be cleared if a previous call to pkg search couldn't get the
+ * remote repo catalog.
+ *
+ * If the calling code would have accepted local copy info (which isn't assumed up to date) then it
+ * makes sense to fall back on pkg info to at least return the known info about installed pkgs (pkg
+ * info should still work), instead of failing and returning no info at all. For example, this
+ * enables offline view + management of installed pkgs.
+ */
+
+ // pkg info errors if none match, unlike pkg search, so test it will work beforehand...
+ $tmp1 = $tmp2 = '';
+ $tmprc = pkg_exec("info -e -R --raw-format json-compact " . $pkgs, $tmp1, $tmp2);
+
+ if ($tmprc == 0) {
+ // ok, packages match, so pkg info can be safely called
+ $rc = pkg_exec("info -R --raw-format json-compact " . $pkgs, $out, $err);
+ } // else we already have empty values for $out etc which are correct if none matched
+ }
if ($lock) {
clear_subsystem_dirty('pkg');
}
@@ -488,7 +515,8 @@ function get_pkg_info($pkgs = 'all', $only_local = false) {
function register_all_installed_packages() {
global $g, $config, $pkg_interface;
- $pkg_info = get_pkg_info('all', true);
+ $pkg_info = get_pkg_info('all', true, true);
+
foreach ($pkg_info as $pkg) {
if (!isset($pkg['installed'])) {
OpenPOWER on IntegriCloud