From 1f3d4050fd6d3fb4147f6d1ce3ffa404413f3ccb Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Thu, 15 Feb 2018 15:27:30 +0100 Subject: [PATCH] Partial fix for PRO-4872 This is a partial fix that makes self-update on Aktualizr work, although we should build a proper solution soon. It does at least work end-to-end, and unblocks the remaining testing. Change-Id: I03d8c1dd461fd21c244145f641d808e8bbdfd450 --- src/deb.cc | 25 +++++++++++++------ tests/packagemanager_deb_tests.cc | 6 ++--- .../test_data/fake_dpkg/{dpkg => systemd-run} | 3 +-- 3 files changed, 21 insertions(+), 13 deletions(-) rename tests/test_data/fake_dpkg/{dpkg => systemd-run} (72%) diff --git a/src/deb.cc b/src/deb.cc index 960049f3b3..8839d8204f 100644 --- a/src/deb.cc +++ b/src/deb.cc @@ -30,16 +30,25 @@ Json::Value DebianManager::getInstalledPackages() { data::InstallOutcome DebianManager::install(const Uptane::Target &target) const { LOG_INFO << "Installing " << target.filename() << " as Debian package..."; - std::string cmd = "dpkg -i "; - std::string output; - TemporaryDirectory package_dir("deb_dir"); - std::stringstream sstr; - sstr << *storage_->openTargetFile(target.filename()); - boost::filesystem::path deb_path = package_dir / target.filename(); - Utils::writeFile(deb_path, sstr.str()); - int status = Utils::shell(cmd + deb_path.string(), &output, true); + // Install the new package. This is complicated by the fact that it needs to + // support self-update, where aktualizr installs a new aktualzr Debian + // package. Removing the old package stops the Aktualizr systemd service, + // which causes Aktualizr to get killed. Therefore we perform the + // installation in a separate cgroup, using systemd-run. + // This is a temporary solution--in the future we should juggle things to + // report the installation status correctly. + const std::string tmp_deb_file("/tmp/incoming-package.deb", std::ofstream::trunc); // TODO Make this secure + std::ofstream package(tmp_deb_file); + package << *storage_->openTargetFile(target.filename()); + package.close(); + + std::string cmd = "systemd-run --no-ask-password dpkg -i " + tmp_deb_file; + + std::string output; + int status = Utils::shell(cmd, &output, true); if (status == 0) { + // This is only checking the result of the systemd-run command LOG_INFO << "... Installation of Debian package successful"; storage_->saveInstalledVersion(target); return data::InstallOutcome(data::OK, "Installing debian package was successful"); diff --git a/tests/packagemanager_deb_tests.cc b/tests/packagemanager_deb_tests.cc index 9133e126f4..a514e641fa 100644 --- a/tests/packagemanager_deb_tests.cc +++ b/tests/packagemanager_deb_tests.cc @@ -26,12 +26,12 @@ TEST(PackageManagerFactory, Debian_Install_Good) { Json::Value target_json_test; target_json_test["hashes"]["sha256"] = "hash_old"; - target_json_test["length"] = 0; + target_json_test["length"] = 5; Uptane::Target target_test("test.deb", target_json_test); storage->saveInstalledVersion(target_test); - std::unique_ptr fhandle = storage->allocateTargetFile(false, "good.deb", 2); - std::stringstream("ab") >> *fhandle; + std::unique_ptr fhandle = storage->allocateTargetFile(false, "good.deb", 5); + std::stringstream("GOOD\n") >> *fhandle; EXPECT_EQ(pacman->install(target).first, data::OK); std::map versions_loaded; diff --git a/tests/test_data/fake_dpkg/dpkg b/tests/test_data/fake_dpkg/systemd-run similarity index 72% rename from tests/test_data/fake_dpkg/dpkg rename to tests/test_data/fake_dpkg/systemd-run index c73419a0cd..432e0233be 100755 --- a/tests/test_data/fake_dpkg/dpkg +++ b/tests/test_data/fake_dpkg/systemd-run @@ -1,8 +1,7 @@ #!/usr/bin/env bash set -e -if [[ "$2" == */good.deb ]] -then +if grep -q GOOD "${@: -1}"; then exit 0 else echo -ne "Error installing"