Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Add a simple autoclean feature for aktualizr daemon
Browse files Browse the repository at this point in the history
Put it in a separate source so it can be more easily tested and
won't pollute aktualizr_primary's main too much.

Signed-off-by: Laurent Bonnans <[email protected]>
  • Loading branch information
lbonn committed Sep 5, 2019
1 parent e6e1e5e commit eb510df
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/aktualizr_primary/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "config/config.h"
#include "logging/logging.h"
#include "primary/aktualizr.h"
#include "primary/aktualizr_helpers.h"
#include "secondary.h"
#include "utilities/aktualizr_version.h"
#include "utilities/utils.h"
Expand Down Expand Up @@ -157,6 +158,9 @@ int main(int argc, char *argv[]) {
aktualizr.SendDeviceData().get();
aktualizr.UptaneCycle();
} else {
boost::signals2::connection ac_conn =
aktualizr.SetSignalHandler(std::bind(targets_autoclean_cb, std::ref(aktualizr), std::placeholders::_1));

aktualizr.RunForever().get();
}
r = EXIT_SUCCESS;
Expand Down
5 changes: 3 additions & 2 deletions src/libaktualizr/primary/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
set(SOURCES aktualizr.cc
aktualizr_helpers.cc
initializer.cc
reportqueue.cc
sotauptaneclient.cc)

set(HEADERS secondary_config.h
aktualizr.h
aktualizr_helpers.h
events.h
initializer.h
reportqueue.h
Expand Down Expand Up @@ -32,8 +34,7 @@ if (BUILD_OSTREE)
LABELS "noptest")
target_link_libraries(t_download_nonostree virtual_secondary)
else (BUILD_OSTREE)
aktualizr_source_file_checks(aktualizr_fullostree_test.cc)
aktualizr_source_file_checks(download_nonostree_test.cc)
aktualizr_source_file_checks(aktualizr_fullostree_test.cc download_nonostree_test.cc)
endif (BUILD_OSTREE)

add_aktualizr_test(NAME reportqueue SOURCES reportqueue_test.cc PROJECT_WORKING_DIRECTORY LIBRARIES PUBLIC uptane_generator_lib)
Expand Down
2 changes: 1 addition & 1 deletion src/libaktualizr/primary/aktualizr.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef AKTUALIZR_H_
#define AKTUALIZR_H_

#include <atomic>
#include <future>
#include <memory>

#include <boost/signals2.hpp>
Expand Down
33 changes: 33 additions & 0 deletions src/libaktualizr/primary/aktualizr_helpers.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "aktualizr_helpers.h"

void targets_autoclean_cb(Aktualizr &aktualizr, const std::shared_ptr<event::BaseEvent> &event) {
if (!event->isTypeOf<event::AllInstallsComplete>()) {
return;
}

const auto targets_event = dynamic_cast<event::AllInstallsComplete *>(event.get());

std::vector<Uptane::Target> installed_targets = aktualizr.GetStoredTargets();
std::vector<bool> to_remove(installed_targets.size(), true);

// do not remove targets that were just installed
for (const result::Install::EcuReport &er : targets_event->result.ecu_reports) {
const Uptane::Target t = er.update;
auto it = std::find_if(installed_targets.begin(), installed_targets.end(),
[&t](const Uptane::Target &t2) { return t.sha256Hash() == t2.sha256Hash(); });
if (it == installed_targets.end()) {
continue;
}

size_t rem_idx = static_cast<size_t>(it - installed_targets.begin());
to_remove[rem_idx] = false;
}

// TODO: more specific check

for (size_t k = 0; k < installed_targets.size(); k++) {
if (to_remove[k]) {
aktualizr.DeleteStoredTarget(installed_targets[k]);
}
}
}
11 changes: 11 additions & 0 deletions src/libaktualizr/primary/aktualizr_helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef AKTUALIZR_HELPERS_H_
#define AKTUALIZR_HELPERS_H_

#include <memory>
#include "aktualizr.h"

// add as a signal handler to remove old targets just after an installation
// completes
void targets_autoclean_cb(Aktualizr &aktualizr, const std::shared_ptr<event::BaseEvent> &event);

#endif // AKTUALIZR_HELPERS_H_
57 changes: 57 additions & 0 deletions src/libaktualizr/primary/aktualizr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "config/config.h"
#include "httpfake.h"
#include "primary/aktualizr.h"
#include "primary/aktualizr_helpers.h"
#include "primary/events.h"
#include "primary/sotauptaneclient.h"
#include "uptane_test_common.h"
Expand Down Expand Up @@ -1331,6 +1332,62 @@ TEST(Aktualizr, DownloadListRemove) {
EXPECT_EQ(targets.size(), 0);
}

TEST(Aktualizr, TargetAutoremove) {
TemporaryDirectory temp_dir;
const boost::filesystem::path local_metadir = temp_dir / "metadir";
Utils::createDirectories(local_metadir, S_IRWXU);
auto http = std::make_shared<HttpFake>(temp_dir.Path(), "", local_metadir / "repo");

UptaneRepo repo{local_metadir, "2021-07-04T16:33:27Z", "id0"};
repo.generateRepo(KeyType::kED25519);
const std::string hwid = "primary_hw";
repo.addImage(fake_meta_dir / "fake_meta/primary_firmware.txt", "primary_firmware.txt", hwid, "", {});
repo.addTarget("primary_firmware.txt", hwid, "CA:FE:A6:D2:84:9D", "");
repo.signTargets();

Config conf = UptaneTestCommon::makeTestConfig(temp_dir, http->tls_server);
auto storage = INvStorage::newStorage(conf.storage);
UptaneTestCommon::TestAktualizr aktualizr(conf, storage, http);

// attach the autoclean handler
boost::signals2::connection ac_conn =
aktualizr.SetSignalHandler(std::bind(targets_autoclean_cb, std::ref(aktualizr), std::placeholders::_1));
aktualizr.Initialize();

{
result::UpdateCheck update_result = aktualizr.CheckUpdates().get();
aktualizr.Download(update_result.updates).get();

EXPECT_EQ(aktualizr.GetStoredTargets().size(), 1);

result::Install install_result = aktualizr.Install(update_result.updates).get();
EXPECT_TRUE(install_result.dev_report.success);

EXPECT_EQ(aktualizr.GetStoredTargets().size(), 1);
}

// second install
repo.emptyTargets();
repo.addImage(fake_meta_dir / "fake_meta/dummy_firmware.txt", "dummy_firmware.txt", hwid, "", {});
repo.addTarget("dummy_firmware.txt", hwid, "CA:FE:A6:D2:84:9D", "");
repo.signTargets();

{
result::UpdateCheck update_result = aktualizr.CheckUpdates().get();
aktualizr.Download(update_result.updates).get();

EXPECT_EQ(aktualizr.GetStoredTargets().size(), 2);

result::Install install_result = aktualizr.Install(update_result.updates).get();
EXPECT_TRUE(install_result.dev_report.success);

// first target was removed
std::vector<Uptane::Target> targets = aktualizr.GetStoredTargets();
ASSERT_EQ(targets.size(), 1);
EXPECT_EQ(targets[0].filename(), "dummy_firmware.txt");
}
}

/*
* Initialize -> Install -> nothing to install.
*
Expand Down

0 comments on commit eb510df

Please sign in to comment.