summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorLauri Aarnio <Lauri.Aarnio@iki.fi>2008-03-12 08:45:19 +0200
committerLauri Leukkunen <lle@rahina.org>2008-03-14 07:41:00 +0200
commit6e880fd4c8c8deaafc00a8bc0030f0307cbc9164 (patch)
treeed1d977e849b5b4b444cc1e0b5b179e0960e8ae7 /utils
parenta272c2848d168cddab58709fa4d89f0cac575031 (diff)
Refactored sb2's dpkg-checkbuilddeps wrapper.
- not perfect, but with these modifications "dpkg-checkbuilddeps" becomes finally usable in "maemo" mode (this needs mode-specific configuration, which is currently available only for "maemo") - dpkg-buildpackage can now be used without the "-d" option. - see comments in utils/dpkg-checkbuilddeps for list of missing features
Diffstat (limited to 'utils')
-rwxr-xr-xutils/dpkg-checkbuilddeps284
-rw-r--r--utils/sb2-check-pkg-mappings134
-rw-r--r--utils/sb2-show.c100
3 files changed, 472 insertions, 46 deletions
diff --git a/utils/dpkg-checkbuilddeps b/utils/dpkg-checkbuilddeps
index e87f9f2..2651d05 100755
--- a/utils/dpkg-checkbuilddeps
+++ b/utils/dpkg-checkbuilddeps
@@ -1,59 +1,177 @@
#!/bin/bash
#
# Copyright (C) 2007 Lauri Leukkunen <lle@rahina.org>
+#
+# Redesigned/refactored by Lauri T. Aarnio;
+# Portion Copyright (c) 2008 Nokia Corporation.
+# All rights reserved.
+#
# Licensed under GPL version 2
#
-# Idea behind operation is to use debian package tags to identify
-# libraries, headers and other such "obviously" target stuff from
-# build tools (gcc, doxygen, etc). This means that the build dependencies
-# need to be checked against both target and host debian package databases
-# and irrelevant failures need to be filtered from the results.
-# This is far from ideal, but hopefully adequate for now.
-
+# -------------------
+# Idea behind operation is to first check target's package db,
+# then check if missing packages are tools that could be used
+# from the host (or SBOX_TOOLS_ROOT, if that has been set)
+#
+# FIXME: This implementation is still incomplete, as this does not
+# check package versions while checking host/tools_root tools.
+# Also, it would be a good idea to do a "visibility check" for host packages,
+# too (see how sb2-check-pkg-mappings does it for target's pkg db)
args="$*"
-function run_dpkg_checkbuilddeps()
-{
- missing_deps=$(/usr/bin/dpkg-checkbuilddeps $args 2>&1 | \
- grep "^dpkg-checkbuilddeps: Unmet build dependencies:" | \
- sed 's/dpkg-checkbuilddeps: Unmet build dependencies: //')
-}
+# Target's real package db:
+TARGET_DPKG_ADMINDIR_ALL_PKGS=$SBOX_TARGET_ROOT/var/lib/dpkg
-# takes two lists, one containing packages which are ok to miss,
-# the other the list of packages that are missing
-function check_missing_deps()
+# Host (or built env.) package db:
+HOST_DPKG_ADMINDIR=$SBOX_TOOLS_ROOT/var/lib/dpkg
+
+# A generated, temporary package db which only contains packages that
+# are usable thru the current mapping mode:
+SB2_TEMP_DPKG_ADMIN_DIR=$HOME/.scratchbox2/$SBOX_TARGET.tmp-pkg-db.$SBOX_MAPMODE
+TARGET_DPKG_ADMINDIR_USABLE_PKGS=$SB2_TEMP_DPKG_ADMIN_DIR
+
+cfgfile_host_accepted_pkgs=$SBOX_DIR/share/scratchbox2/modeconf/host-accepted-packages.$SBOX_MAPMODE
+cfgfile_host_ignored_pkgs=$SBOX_DIR/share/scratchbox2/modeconf/host-ignored-packages.$SBOX_MAPMODE
+
+# Check if a named package exists of the host.
+# Returns result in three variables:
+# - $installed_to_host is either "yes" or "no"
+# - $check_result_msg and $check_result_msg2 return a more detailed
+# explanation of the result (strings).
+# This must be called with SBOX_DISABLE_MAPPING=1!!
+function check_host_pkg()
{
- ok_list="$1"
- missing_list="$2"
- list_ok=0
- not_ok_missing_list=""
-
- for m in $(echo $missing_list | sed 's/([^)]\+)//g') ; do
- m_ok=1
- for o in $ok_list ; do
- if [ "$m" == "$o" ]; then
- m_ok=0
+ pkgname=$1
+
+ installed_to_host="no" # default
+ check_result_msg="'$pkgname' not found."
+ check_result_msg2=""
+
+ # Check if it can be accepted from the host:
+ g=`grep "^$pkgname\$" $cfgfile_host_accepted_pkgs`
+ if [ -z "$g" ]
+ then
+ # No, the package has not been aproved to be used from the host.
+
+ # first check if this requirement should be ignored completely:
+ if [ -f $cfgfile_host_ignored_pkgs ]
+ then
+ # ignorelist exists
+ g=`grep "^$pkgname\$" $cfgfile_host_ignored_pkgs`
+ if [ -z "$g" ]
+ then
+ check_result_msg="'$pkgname' is missing (must be installed to the rootstrap)"
+ else
+ check_result_msg="'$pkgname' is missing, but this is ignored by configuration"
+ installed_to_host="yes"
+ return
fi
- printf "Problem with: %s\n" $m
- done
- if [ $m_ok != 0 ]; then
- list_ok=1
fi
- done
+
+ pkg_stat_tmp=/tmp/dpkg.$$.tmp
+ # next check again if the package exists on the target,
+ # just to be able to give a better error message.
+ if dpkg-query -s --admindir=$TARGET_DPKG_ADMINDIR_ALL_PKGS \
+ "$pkgname" >$pkg_stat_tmp 2>&1
+ then
+ if grep -q "ok installed" $pkg_stat_tmp
+ then
+ rm $pkg_stat_tmp
+ check_result_msg="'$pkgname': OOPS. Needed from the the rootstrap (installed there),"
+ check_result_msg2=" but unusable (not fully visible due to SB2 mapping rules)"
+ return
+ fi
+ fi
+ rm $pkg_stat_tmp
+
+ check_result_msg="'$pkgname' is missing, must be istalled to the rootstrap"
+ return
+ fi
+
+ # package is not present in the rootstrap, but
+ # it can be accepted from the host environment.
+ if dpkg-query -s --admindir=$HOST_DPKG_ADMINDIR "$pkgname" >/dev/null 2>&1
+ then
+ installed_to_host="yes"
+ check_result_msg="'$pkgname' found from the host environment"
+ return
+ fi
+
+ # not installed. Test if this can be ignored.
+ if [ -f $cfgfile_host_ignored_pkgs ]
+ then
+ g=`grep "^$pkgname\$" $cfgfile_host_ignored_pkgs`
+ if [ -n "$g" ]
+ then
+ check_result_msg="'$pkgname' is not available (ignored by configuration)"
+ return
+ fi
+ fi
+
+ check_result_msg="'$pkgname' is missing (can be installed to the host)"
+ return 1
}
function check_host_builddeps()
{
+ missing="$1"
ret=0
export SBOX_DISABLE_MAPPING=1
# do the magic here
- echo "SB2 Checking host build deps..."
- run_dpkg_checkbuilddeps
- check_missing_deps "crap" "$missing_deps"
+ echo "SB2 Checking host build deps.."
+
+ list_ok=1 # default to ok
+ # $m will be the package to test, or pkg/pkg[/...] if there are
+ # alternatives (unfortunately '|' has special meaning in shell's
+ # "case" statement, so we'll have to replace it by '/')
+ for m in $(echo $missing | sed -e 's/([^)]\+)//g' | \
+ sed -e 's:[ ]*|[ ]*:/:g')
+ do
+ ## echo " Testing $m:"
+ case "$m" in
+ */*) # alternatives..
+ has_one_alternative=0
+ for mmm in $(echo $m | sed -e 's:/: :')
+ do
+ echo " ...$mmm"
+ check_host_pkg $mmm
+ if [ $? == 0 ]
+ then
+ # nothing is missing = nothing needed from the host side
+ echo " $mmm = ok"
+ has_one_alternative=1
+ else
+ echo " no $mmm.."
+ fi
+ done
+ if [ $has_one_alternative == 0 ]
+ then
+ echo " Requirement $m failed; none of the alternatives were found."
+ list_ok=0
+ else
+ echo " '$m': At least one alternative found, ok."
+ fi
+ ;;
+
+ *) # No alternatives.
+ check_host_pkg $m
+ echo " $check_result_msg"
+ if [ -n "$check_result_msg2" ]
+ then
+ echo " $check_result_msg2"
+ fi
+ if [ "$installed_to_host" = "no" ]
+ then
+ list_ok=0
+ fi
+ esac
+
+ done
+
unset SBOX_DISABLE_MAPPING
- if [ $list_ok != 0 ]; then
+ if [ $list_ok == 0 ]; then
# somethings missing
false
else
@@ -65,28 +183,106 @@ function check_target_builddeps()
{
ret=0
echo "SB2 Checking target build deps..."
- run_dpkg_checkbuilddeps
- check_missing_deps "crap2" "$missing_deps"
- if [ $list_ok != 0 ]; then
- echo "failing target deps"
- false
+
+ # call dpkg-checkbuilddeps with mapping disabled, because the
+ # version which is available in /usr/bin may not know about the
+ # --admindir option. Can't use a pipeline here, we want to the
+ # dpkg-checkbuilddeps' return status.
+ SBOX_DISABLE_MAPPING=1 /usr/bin/dpkg-checkbuilddeps \
+ --admindir=$TARGET_DPKG_ADMINDIR_USABLE_PKGS $args \
+ > /tmp/missing_deps.$$ 2>&1
+ if [ $? == 0 ]
+ then
+ # real dpkg-checkbuilddeps says "all ok"
+ rm /tmp/missing_deps.$$
+ return 0
+ fi
+
+ # else real dpkg-checkbuilddeps failed.
+ sed -e 's/^/ /' < /tmp/missing_deps.$$
+ missing_deps=$(egrep \
+ "^dpkg-checkbuilddeps: Unmet build dependencies:" \
+ /tmp/missing_deps.$$ | \
+ sed 's/dpkg-checkbuilddeps: Unmet build dependencies: //')
+ rm /tmp/missing_deps.$$
+
+ if [ -n "$missing_deps" ]; then
+ # failing target deps, and missing packages are listed
+ # in $missing_deps = continue by checking if those are
+ # available on the host environment
+ return 1
else
- echo "target deps ok"
- true
+ # failing target deps, but $missing_deps is empty. Something
+ # is fatally wrong.
+ exit 1
fi
}
+# First, make sure we are in a correct directory:
+if [ ! -f debian/control ]
+then
+ echo "Error: Can't find file debian/control"
+ exit 1
+fi
+
+# Next, check that the list of usable packages exists and is up-to-date.
+# That list is really a temporary package database, which contains only
+# packages that are usable thru this mapping mode.
+
+if [ ! -f $TARGET_DPKG_ADMINDIR_USABLE_PKGS/status ]
+then
+ echo "$TARGET_DPKG_ADMINDIR_USABLE_PKGS/status does not exist."
+ echo "going to create it now. This is going to take a while.."
+ echo
+ sb2-check-pkg-mappings -a
+elif [ $TARGET_DPKG_ADMINDIR_USABLE_PKGS/status -ot \
+ $TARGET_DPKG_ADMINDIR_ALL_PKGS/status ]
+then
+ echo "Target's primary package database has been updated =>"
+ echo "$TARGET_DPKG_ADMINDIR_USABLE_PKGS/status is out of date."
+ echo "going to update it now. This is going to take a while.."
+ echo
+ sb2-check-pkg-mappings -a
+elif [ $TARGET_DPKG_ADMINDIR_USABLE_PKGS/status -ot \
+ $SBOX_DIR/share/scratchbox2/lua_scripts/pathmaps/$SBOX_MAPMODE/00_default.lua ]
+then
+ echo "SB2's mapping rules have been updated =>"
+ echo "$TARGET_DPKG_ADMINDIR_USABLE_PKGS/status might be out of date."
+ echo "going to update it now. This is going to take a while.."
+ echo
+ sb2-check-pkg-mappings -a
+fi
+
check_target_builddeps
-if [ $? != 0 ]; then
+if [ $? == 0 ]; then
+ # nothing is missing = nothing needed from the host side
+ echo "Target rootstrap => all dependencies OK"
+ exit 0
+fi
+
+echo "Build dependencies missing from the target environment:"
+echo " $missing_deps"
+
+# Something is missing. To be able to get the missing packages from the
+# host environment, at least the list of allowed packages is needed:
+#
+if [ ! -f $cfgfile_host_accepted_pkgs ]
+then
+ echo
+ echo "Configuration file $cfgfile_host_accepted_pkgs"
+ echo "does not exist. This means that no packages have been approved to be used"
+ echo "from the host environment in this mapping mode ($SBOX_MAPMODE)."
exit 1
fi
-check_host_builddeps
+check_host_builddeps "$missing_deps"
if [ $? != 0 ]; then
+ echo "Failed. Host environment did not meet all requirements."
exit 1
fi
# since we're here, everything is more or less ok
+echo "All OK."
exit 0
diff --git a/utils/sb2-check-pkg-mappings b/utils/sb2-check-pkg-mappings
new file mode 100644
index 0000000..f09dcd1
--- /dev/null
+++ b/utils/sb2-check-pkg-mappings
@@ -0,0 +1,134 @@
+#!/bin/bash
+#
+# This script checks which .deb packages can be used from the rootstrap.
+#
+# dpkg-checkbuilddeps uses this to builds a new temporary "status" file of
+# all usable packages.
+#
+# Copyright (c) 2008 Nokia Corporation. All rights reserved.
+# Author: Lauri T. Aarnio
+# Licensed under LGPL version 2.1, see top level LICENSE file for details.
+
+function usage()
+{
+ cat <<EOF
+sb2-check-pkg-mappings - check usability of target's .deb packages
+Usage:
+ sb2-check-pkg-mappings pkg1 [pkg2..]
+ sb2-check-pkg-mappings -a
+
+Options:
+ -a check all packages and write results to a temporary
+ database, to be used by sb2's dpkg-checkbuilddeps
+
+When started with list of package names, checks named packages and prints
+results, but does not create or modify the temporary database.
+EOF
+ exit 1
+}
+
+if [ -z "$*" ]; then
+ usage
+fi
+
+check_all_pkgs="no"
+status_file=""
+
+while getopts ah foo
+do
+ case $foo in
+ (a) check_all_pkgs="yes" ;;
+ (h) usage ;;
+ (*) usage ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+pkgs2check="$*"
+tstamp=`/bin/date +%Y%m%d-%H%M`
+
+if [ -z "$pkgs2check" -a "$check_all_pkgs" = "yes" ]
+then
+ # check all installed packages
+ pkgs2check=`dpkg --get-selections | grep 'install$' | sed -e 's/install$//'`
+ status_file=STATUS-NEW.$tstamp.$$
+elif [ "$check_all_pkgs" = "yes" ]
+then
+ # -a and package names - illegal
+ usage
+fi
+
+function remove_temp_files
+{
+ if [ -n "$status_file" -a -f "$status_file" ]
+ then
+ echo "removing temp file '$$status_file'"
+ rm $status_file
+ fi
+}
+trap remove_temp_files EXIT
+
+pkgnum=0
+num_ok=0
+num_failed=0
+
+# Read the mode-specific path ignore list.
+SB2_CHECK_PKG_MAPPINGS_IGNORE_LIST=""
+if [ -f $SBOX_DIR/share/scratchbox2/modeconf/sb2rc.$SBOX_MAPMODE ]
+then
+ . $SBOX_DIR/share/scratchbox2/modeconf/sb2rc.$SBOX_MAPMODE
+fi
+
+# for all installed packages..
+for pkg in $pkgs2check
+do
+ pkgnum=`expr $pkgnum + 1`
+ echo "=========== $pkgnum. Checking $pkg ==========="
+
+ # get list of files intalled by this package (dpkg -L),
+ # and feed it to sb2-show to be verified (-D causes directories
+ # to be ignored). Also ignore all files which are installed
+ # to these diretories listed in $SB2_CHECK_PKG_MAPPINGS_IGNORE_LIST.
+ dpkg -L $pkg >/tmp/sb2-pkg-chk.$tstamp.$$
+ if [ $? != 0 ]
+ then
+ num_failed=`expr $num_failed + 1`
+ echo " $pkg is not available"
+ else
+ sed < /tmp/sb2-pkg-chk.$tstamp.$$ \
+ -e 's/diverted by .* to: //' \
+ -e 's/package diverts others to: //' |
+ sb2-show -D verify-pathlist-mappings \
+ $SBOX_TARGET_ROOT $SB2_CHECK_PKG_MAPPINGS_IGNORE_LIST
+ if [ $? == 0 ]
+ then
+ echo " $pkg = OK"
+ num_ok=`expr $num_ok + 1`
+ if [ $check_all_pkgs = "yes" ]
+ then
+ if [ -f $status_file ]
+ then
+ echo >>$status_file
+ fi
+ dpkg -s $pkg >>$status_file
+ fi
+ else
+ num_failed=`expr $num_failed + 1`
+ echo " $pkg can not be used in this mode ($SBOX_MAPMODE)"
+ fi
+ fi
+ rm /tmp/sb2-pkg-chk.$tstamp.$$
+done
+
+echo "Checked $pkgnum packages: Ok=$num_ok, unusable=$num_failed"
+
+if [ $check_all_pkgs = "yes" ]
+then
+ SB2_TEMP_DPKG_ADMIN_DIR=$HOME/.scratchbox2/$SBOX_TARGET.tmp-pkg-db.$SBOX_MAPMODE
+ if [ ! -d $SB2_TEMP_DPKG_ADMIN_DIR ]
+ then
+ mkdir $SB2_TEMP_DPKG_ADMIN_DIR
+ fi
+ mv $status_file $SB2_TEMP_DPKG_ADMIN_DIR/status
+ echo "Results have been written to $SB2_TEMP_DPKG_ADMIN_DIR/status"
+fi
diff --git a/utils/sb2-show.c b/utils/sb2-show.c
index 45ae35b..a5cc6bf 100644
--- a/utils/sb2-show.c
+++ b/utils/sb2-show.c
@@ -1,5 +1,5 @@
/* sb2-show:
- * SB2 Mapping rule testingutility
+ * SB2 Mapping rule testing utility
*
* Copyright (c) 2008 Nokia Corporation. All rights reserved.
* Author: Lauri T. Aarnio
@@ -27,6 +27,8 @@ static void usage_exit(const char *progname, const char *errmsg, int exitstatus)
"\t-m mode\t\tshow using named mapping mode "
"(default=current mode)\n"
"\t-f function\tshow using 'function' as callers name\n"
+ "\t-D\tignore directories while verifying path lists\n"
+ "\t-v\tverbose.\n"
"\nCommands:\n"
"\tpath [path1] [path2].."
"\tShow mappings of pathnames\n"
@@ -36,6 +38,9 @@ static void usage_exit(const char *progname, const char *errmsg, int exitstatus)
"\tAdd an error message to the log\n"
"\tlog-warning 'message'"
"\tAdd a warning message to the log\n"
+ "\tverify-pathlist-mappings required-prefix [ignorelist]"
+ "\tread list of paths from stdin and/n"
+ "\t\tcheck that all paths will be mapped to required prefix/n"
"\n'%s' must be executed inside sb2 sandbox"
" (see the 'sb2' command)\n",
progname, progname, progname);
@@ -93,6 +98,89 @@ static void command_show_path(const char *binary_name,
}
}
+/* read paths from stdin, report paths that are not mapped to specified
+ * directory.
+ * returns 0 if all OK, 1 if one or more paths were not mapped.
+*/
+static int command_verify_pathlist_mappings(
+ const char *binary_name,
+ const char *mapping_mode,
+ const char *fn_name,
+ int ignore_directories,
+ int verbose,
+ const char *progname,
+ char **argv)
+{
+ int destination_prefix_len;
+ char path_buf[PATH_MAX + 1];
+ const char *required_destination_prefix = argv[0];
+ int result = 0;
+
+ if (!required_destination_prefix) {
+ usage_exit(progname, "'destination_prefix' is missing", 1);
+ }
+ destination_prefix_len = strlen(required_destination_prefix);
+
+ while (fgets(path_buf, sizeof(path_buf), stdin)) {
+ int len = strlen(path_buf);
+ char *mapped_path = NULL;
+ int readonly_flag;
+ int destination_prefix_cmp_result;
+ char **ignore_path;
+ int ignore_this = 0;
+
+ if ((len > 0) && (path_buf[len-1] == '\n')) {
+ path_buf[--len] = '\0';
+ }
+ if (len == 0) continue;
+
+ for (ignore_path = argv+1; *ignore_path; ignore_path++) {
+ int ign_len = strlen(*ignore_path);
+
+ if (!strncmp(path_buf, *ignore_path, ign_len)) {
+ ignore_this = 1;
+ if (verbose)
+ printf("IGNORED by prefix: %s\n",
+ path_buf);
+ break;
+ }
+ }
+
+ if (ignore_this) continue;
+
+ mapped_path = sb2show__map_path2__(binary_name, mapping_mode,
+ fn_name, path_buf, &readonly_flag);
+
+ if (ignore_directories) {
+ struct stat statbuf;
+
+ if ((stat(mapped_path, &statbuf) == 0) &&
+ S_ISDIR(statbuf.st_mode)) {
+ if (verbose)
+ printf("%s => %s: dir, ignored\n",
+ path_buf, mapped_path);
+ continue;
+ }
+ }
+
+ destination_prefix_cmp_result = strncmp(mapped_path,
+ required_destination_prefix, destination_prefix_len);
+ if (destination_prefix_cmp_result) {
+ result = 1;
+ printf("%s => %s%s: NOT OK\n",
+ path_buf, mapped_path,
+ (readonly_flag ? " (readonly)" : ""));
+ } else {
+ /* mapped OK. */
+ if (verbose)
+ printf("%s => %s%s: Ok\n",
+ path_buf, mapped_path,
+ (readonly_flag ? " (readonly)" : ""));
+ }
+ }
+ return (result);
+}
+
static void command_log(char **argv, int loglevel)
{
SB_LOG(loglevel, "%s", argv[0]);
@@ -105,6 +193,8 @@ int main(int argc, char *argv[])
char *mapping_mode = NULL;
char *function_name = "ANYFUNCTION";
char *binary_name = "ANYBINARY";
+ int ignore_directories = 0;
+ int verbose = 0;
#if 0 || defined(enable_this_after_sb2_preload_library_startup_has_been_fixed)
/* FIXME: this should be able to check if we are inside the sb2
@@ -122,12 +212,14 @@ int main(int argc, char *argv[])
}
#endif
- while ((opt = getopt(argc, argv, "hm:f:b:")) != -1) {
+ while ((opt = getopt(argc, argv, "hm:f:b:Dv")) != -1) {
switch (opt) {
case 'h': usage_exit(progname, NULL, 0); break;
case 'm': mapping_mode = optarg; break;
case 'f': function_name = optarg; break;
case 'b': binary_name = optarg; break;
+ case 'D': ignore_directories = 1; break;
+ case 'v': verbose = 1; break;
default: usage_exit(progname, "Illegal option", 1); break;
}
}
@@ -149,6 +241,10 @@ int main(int argc, char *argv[])
command_log(argv + optind + 1, SB_LOGLEVEL_ERROR);
} else if (!strcmp(argv[optind], "log-warning")) {
command_log(argv + optind + 1, SB_LOGLEVEL_WARNING);
+ } else if (!strcmp(argv[optind], "verify-pathlist-mappings")) {
+ return command_verify_pathlist_mappings(binary_name,
+ mapping_mode, function_name, ignore_directories,
+ verbose, progname, argv + optind + 1);
} else {
usage_exit(progname, "Unknown command", 1);
}