aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2013-05-24 22:12:45 -0700
committerAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2013-05-27 10:20:08 -0700
commitd34636a1dc4f422aeb868e49447a0503c303f0a2 (patch)
tree744eaca3276801c0b22429a46ace39372c74fba0
parent450c0331aca4600729216b9bff5d3e1b4e203871 (diff)
downloadpaludis-d34636a1dc4f422aeb868e49447a0503c303f0a2.tar.gz
paludis-d34636a1dc4f422aeb868e49447a0503c303f0a2.tar.xz
e repository: perform additional expart validation
When contents are partitioned, ensure that the partition name supplied has been declared previously. This will help identify packages which do not correctly indicate valid partition names. Signed-off-by: Saleem Abdulrasool <compnerd@compnerd.org>
-rw-r--r--paludis/repositories/e/e_choices_key.cc32
-rw-r--r--paludis/repositories/e/eapi.cc3
-rw-r--r--paludis/repositories/e/eapi.hh2
-rw-r--r--paludis/repositories/e/eapis/exheres-0.conf1
-rw-r--r--paludis/repositories/e/exndbam_repository_TEST.cc51
-rwxr-xr-xpaludis/repositories/e/exndbam_repository_TEST_setup.sh28
-rw-r--r--paludis/repositories/e/pipe_command_handler.cc35
7 files changed, 143 insertions, 9 deletions
diff --git a/paludis/repositories/e/e_choices_key.cc b/paludis/repositories/e/e_choices_key.cc
index 6e07762..063303d 100644
--- a/paludis/repositories/e/e_choices_key.cc
+++ b/paludis/repositories/e/e_choices_key.cc
@@ -303,13 +303,15 @@ EChoicesKey::populate_myoptions() const
{
Context local_context("When using raw_myoptions_key to populate choices:");
+ const auto & eapi = _imp->id->eapi()->supported();
+
std::shared_ptr<Choice> options(std::make_shared<Choice>(make_named_values<ChoiceParams>(
n::consider_added_or_changed() = true,
n::contains_every_value() = false,
n::hidden() = false,
- n::human_name() = _imp->id->eapi()->supported()->ebuild_environment_variables()->env_use(),
+ n::human_name() = eapi->ebuild_environment_variables()->env_use(),
n::prefix() = ChoicePrefixName(""),
- n::raw_name() = _imp->id->eapi()->supported()->ebuild_environment_variables()->env_use(),
+ n::raw_name() = eapi->ebuild_environment_variables()->env_use(),
n::show_with_no_prefix() = true
)));
_imp->value->add(options);
@@ -353,6 +355,32 @@ EChoicesKey::populate_myoptions() const
}
}
+ if (auto parts_prefix = eapi->parts_prefix())
+ {
+ const ChoicePrefixName prefix(parts_prefix->value());
+
+ auto parts = std::make_shared<Choice>(make_named_values<ChoiceParams>(
+ n::consider_added_or_changed() = true,
+ n::contains_every_value() = true,
+ n::hidden() = false,
+ n::human_name() = parts_prefix->value(),
+ n::prefix() = prefix,
+ n::raw_name() = parts_prefix->value(),
+ n::show_with_no_prefix() = false
+ ));
+ _imp->value->add(parts);
+
+ const auto pi = myoptions.prefixes.find(prefix);
+ if (pi != myoptions.prefixes.end())
+ {
+ for (const auto & part : pi->second)
+ parts->add(make_myoption(_imp->id, parts, part.first,
+ part.second.description, indeterminate,
+ co_explicit, part.second.presumed));
+ myoptions.prefixes.erase(pi);
+ }
+ }
+
MyOptionsFinder::Prefixes::iterator p(myoptions.prefixes.find(ChoicePrefixName("")));
if (myoptions.prefixes.end() != p)
{
diff --git a/paludis/repositories/e/eapi.cc b/paludis/repositories/e/eapi.cc
index da5979e..c86b2ba 100644
--- a/paludis/repositories/e/eapi.cc
+++ b/paludis/repositories/e/eapi.cc
@@ -20,6 +20,7 @@
#include <paludis/repositories/e/eapi.hh>
#include <paludis/name.hh>
+#include <paludis/choice.hh>
#include <paludis/dep_spec.hh>
#include <paludis/util/attributes.hh>
@@ -377,6 +378,8 @@ namespace
n::iuse_flag_parse_options() = iuse_flag_parse_options,
n::merger_options() = merger_options,
n::package_dep_spec_parse_options() = package_dep_spec_parse_options,
+ n::parts_prefix() =
+ std::make_shared<ChoicePrefixName>(check_get(k, "parts_prefix")),
n::permitted_directories() = check_get(k, "permitted_directories"),
n::pipe_commands() = make_pipe_commands(k),
n::profile_options() = make_profile_options(k),
diff --git a/paludis/repositories/e/eapi.hh b/paludis/repositories/e/eapi.hh
index f33a72d..34f22df 100644
--- a/paludis/repositories/e/eapi.hh
+++ b/paludis/repositories/e/eapi.hh
@@ -176,6 +176,7 @@ namespace paludis
typedef Name<struct name_no_slot_or_repo> no_slot_or_repo;
typedef Name<struct name_non_empty_variables> non_empty_variables;
typedef Name<struct name_package_dep_spec_parse_options> package_dep_spec_parse_options;
+ typedef Name<struct name_parts_prefix> parts_prefix;
typedef Name<struct name_pdepend> pdepend;
typedef Name<struct name_permitted_directories> permitted_directories;
typedef Name<struct name_pipe_commands> pipe_commands;
@@ -314,6 +315,7 @@ namespace paludis
NamedValue<n::iuse_flag_parse_options, IUseFlagParseOptions> iuse_flag_parse_options;
NamedValue<n::merger_options, MergerOptions> merger_options;
NamedValue<n::package_dep_spec_parse_options, ELikePackageDepSpecOptions> package_dep_spec_parse_options;
+ NamedValue<n::parts_prefix, std::shared_ptr<ChoicePrefixName>> parts_prefix;
NamedValue<n::permitted_directories, std::string> permitted_directories;
NamedValue<n::pipe_commands, std::shared_ptr<const EAPIPipeCommands> > pipe_commands;
NamedValue<n::profile_options, std::shared_ptr<const EAPIProfileOptions> > profile_options;
diff --git a/paludis/repositories/e/eapis/exheres-0.conf b/paludis/repositories/e/eapis/exheres-0.conf
index 8f56d4f..d17a134 100644
--- a/paludis/repositories/e/eapis/exheres-0.conf
+++ b/paludis/repositories/e/eapis/exheres-0.conf
@@ -37,6 +37,7 @@ has_expensive_tests = true
fs_location_name = EXHERES
fs_location_description = Exheres Location
allow_tokens_in_mask_files = true
+parts_prefix = parts
permitted_directories = \
-/ +/bin +/sbin +/lib +/var -/var/run -/var/lock -/var/tmp/paludis +/usr -/usr/local -/usr/libexec/udev/rules.d \
diff --git a/paludis/repositories/e/exndbam_repository_TEST.cc b/paludis/repositories/e/exndbam_repository_TEST.cc
index 0809628..5189787 100644
--- a/paludis/repositories/e/exndbam_repository_TEST.cc
+++ b/paludis/repositories/e/exndbam_repository_TEST.cc
@@ -44,6 +44,8 @@ namespace
{
const auto exndbam_repository_TEST_dir =
FSPath::cwd() / "exndbam_repository_TEST_dir";
+ const auto exndbam_repository_TEST_root =
+ exndbam_repository_TEST_dir / "root";
void do_uninstall(const std::shared_ptr<const PackageID> & id, const UninstallActionOptions & u)
{
@@ -111,6 +113,31 @@ namespace
std::bind(from_keys,
keys, _1));
}
+
+ std::shared_ptr<Repository>
+ make_exheres_0_repository(Environment & env, const FSPath & root,
+ const std::string & name)
+ {
+ using namespace std::placeholders;
+
+ auto keys = std::make_shared<Map<std::string, std::string>>();
+
+ keys->insert("eapi_when_unknown", "exheres-0");
+ keys->insert("eapi_when_unspecified", "exheres-0");
+ keys->insert("format", "e");
+ keys->insert("layout", "exheres");
+ keys->insert("location", stringify(root / name));
+ keys->insert("names_cache", "/var/empty");
+ keys->insert("profile_eapi", "exheres-0");
+ keys->insert("profiles", stringify(root / name / "profiles" / "profile"));
+ keys->insert("root", stringify(root / "root"));
+
+ keys->insert("builddir", stringify(root / "build"));
+ keys->insert("distdir", stringify(root / "distdir"));
+
+ return ERepository::repository_factory_create(&env, std::bind(from_keys,
+ keys, _1));
+ }
}
TEST(ExndbamRepository, RepoName)
@@ -122,7 +149,7 @@ TEST(ExndbamRepository, RepoName)
TEST(ExndbamRepository, PhaseOrdering)
{
- TestEnvironment env(exndbam_repository_TEST_dir / "root");
+ TestEnvironment env(exndbam_repository_TEST_root);
std::shared_ptr<Map<std::string, std::string> > keys(std::make_shared<Map<std::string, std::string>>());
keys->insert("format", "e");
keys->insert("names_cache", "/var/empty");
@@ -213,3 +240,25 @@ TEST(ExndbamRepository, PhaseOrdering)
}
}
+TEST(ExndbamRepository, UnlistedPartsFails)
+{
+ const auto partitioned(QualifiedPackageName("category/partitioned"));
+
+ TestEnvironment env(exndbam_repository_TEST_root);
+
+ auto parts(make_exheres_0_repository(env, exndbam_repository_TEST_dir,
+ "parts"));
+ auto installed(make_exndbam_repository(env, exndbam_repository_TEST_dir,
+ "installed"));
+ env.add_repository(0, installed);
+ env.add_repository(1, parts);
+
+ EXPECT_TRUE(installed->package_ids(partitioned, { })->empty());
+ EXPECT_TRUE(!parts->package_ids(partitioned, { })->empty());
+
+ ASSERT_THROW(install(env, installed, "=category/partitioned-0::parts", ""),
+ paludis::ActionFailedError);
+
+ EXPECT_TRUE(installed->package_ids(partitioned, { })->empty());
+}
+
diff --git a/paludis/repositories/e/exndbam_repository_TEST_setup.sh b/paludis/repositories/e/exndbam_repository_TEST_setup.sh
index 3f0244e..4d2311f 100755
--- a/paludis/repositories/e/exndbam_repository_TEST_setup.sh
+++ b/paludis/repositories/e/exndbam_repository_TEST_setup.sh
@@ -10,6 +10,8 @@ mkdir -p root/etc
mkdir -p repo1/ || exit 1
+mkdir -p installed || exit 1
+mkdir -p parts/{metadata,profiles/profile,packages/category/partitioned} || exit 1
mkdir -p postinsttest postinsttest_src1/{eclass,profiles/profile,cat/pkg} || exit 1
cat <<END > postinsttest_src1/profiles/profile/make.defaults
@@ -58,3 +60,29 @@ sed -i -e 's/EAPI=1/EAPI=paludis-1/' postinsttest_src1/cat/pkg/pkg-1.ebuild
cp postinsttest_src1/cat/pkg/pkg-{1,1.1}.ebuild
cp postinsttest_src1/cat/pkg/pkg-{1,2}.ebuild
+echo '*/* PLATFORM: (test)' > parts/profiles/profile/options.conf
+cat <<- EOF > parts/profiles/profile/make.defaults
+CHOST="i686-pc-linux-gnu"
+EOF
+echo parts > parts/profiles/repo_name
+echo category > parts/metadata/categories.conf
+
+cat <<- EOF > parts/packages/category/partitioned/partitioned-0.exheres-0
+PLATFORMS="test"
+MYOPTIONS="parts: binaries"
+
+SLOT="0"
+
+src_unpack() {
+ edo mkdir -p "\${WORK}"
+}
+
+src_install() {
+ edo mkdir -p "\${IMAGE}"/usr/{bin,lib,share/man/man1}
+ edo touch "\${IMAGE}"/usr/{bin/binary,lib/library.{so,a},share/man/man1/expart.1}
+
+ expart binaries /usr/bin
+ expart libraries /usr/lib
+}
+EOF
+
diff --git a/paludis/repositories/e/pipe_command_handler.cc b/paludis/repositories/e/pipe_command_handler.cc
index 2476af9..d6cd986 100644
--- a/paludis/repositories/e/pipe_command_handler.cc
+++ b/paludis/repositories/e/pipe_command_handler.cc
@@ -570,8 +570,7 @@ paludis::erepository::pipe_command_handler(const Environment * const environment
else if (tokens[0] == "PARTITION")
{
bool exclude(false);
- std::shared_ptr<const EAPI> eapi =
- EAPIData::get_instance()->eapi_from_string(tokens[1]);
+ auto eapi = EAPIData::get_instance()->eapi_from_string(tokens[1]);
if (! eapi->supported())
return "EPARTITION EAPI " + tokens[1] + " unsupported";
@@ -601,13 +600,37 @@ paludis::erepository::pipe_command_handler(const Environment * const environment
<< "parts not supported by destination repository";
return "EPARTITION EXPART not supported by destination repository";
}
- else
+
+ if (! package_id->choices_key())
+ return "EPARTITION ID " + stringify(*package_id) + " has no choices";
+
+ if (! exclude)
{
- maybe_partitioning->mark(contents,
- exclude ? PartName("")
- : PartName(partition_id));
+ bool specified(false);
+
+ auto prefix = package_id->eapi()->supported()->parts_prefix();
+ auto choices = package_id->choices_key()->parse_value();
+
+ auto parts = choices->find(ChoicePrefixName(prefix->value()));
+ if (parts == choices->end())
+ return "EPARTITION ID " + stringify(*package_id) + " has no partitions";
+
+ for (const auto & part : **parts)
+ if ((specified = part->unprefixed_name().value() == partition_id))
+ break;
+
+ if (! specified)
+ {
+ Log::get_instance()->message("e.pipe_commands.partitioning.invalid_package",
+ ll_warning, lc_context)
+ << "'" << partition_id << "' is not specified by the package as a partition identifier";
+ return "EPARTITION ID " + stringify(*package_id) + " has no partition named '" + partition_id + "'";
+ }
}
+ maybe_partitioning->mark(contents,
+ exclude ? PartName("")
+ : PartName(partition_id));
return "O0;";
}
catch (const Exception & e)