diff --git a/src/aktualizr_repo/director_repo.cc b/src/aktualizr_repo/director_repo.cc index 5b3248fbb1..282a853fee 100644 --- a/src/aktualizr_repo/director_repo.cc +++ b/src/aktualizr_repo/director_repo.cc @@ -44,4 +44,16 @@ void DirectorRepo::emptyTargets() { targets_unsigned = Utils::parseJSONFile(staging); targets_unsigned["targets"].clear(); Utils::writeFile(staging, Utils::jsonToCanonicalStr(targets_unsigned)); +} + +void DirectorRepo::oldTargets() { + const boost::filesystem::path current = path_ / "repo/director/targets.json"; + const boost::filesystem::path staging = path_ / "repo/director/staging/targets.json"; + + if (!boost::filesystem::exists(current)) { + throw std::runtime_error(std::string("targets.json not found at ") + current.c_str() + "!"); + } + Json::Value targets_current = Utils::parseJSONFile(current); + Json::Value targets_unsigned = targets_current["signed"]; + Utils::writeFile(staging, Utils::jsonToCanonicalStr(targets_unsigned)); } \ No newline at end of file diff --git a/src/aktualizr_repo/director_repo.h b/src/aktualizr_repo/director_repo.h index 6e349d7fce..f3e81b0c0d 100644 --- a/src/aktualizr_repo/director_repo.h +++ b/src/aktualizr_repo/director_repo.h @@ -11,6 +11,7 @@ class DirectorRepo : public Repo { const std::string &ecu_serial); void signTargets(); void emptyTargets(); + void oldTargets(); }; #endif // DIRECTOR_REPO_H_ diff --git a/src/aktualizr_repo/main.cc b/src/aktualizr_repo/main.cc index aa1470eed9..7c846acfd9 100644 --- a/src/aktualizr_repo/main.cc +++ b/src/aktualizr_repo/main.cc @@ -15,7 +15,7 @@ int main(int argc, char **argv) { // clang-format off desc.add_options() ("help,h", "print usage") - ("command", po::value(), "generate|sign|image|addtarget|emptytargets|signtargets") + ("command", po::value(), "generate|sign|image|addtarget|emptytargets|oldtargets|signtargets") ("path", po::value(), "path to the repository") ("filename", po::value(), "path to the image") ("hwid", po::value(), "target hardware identifier") @@ -81,6 +81,8 @@ int main(int argc, char **argv) { repo.signTargets(); } else if (command == "emptytargets") { repo.emptyTargets(); + } else if (command == "oldtargets") { + repo.oldTargets(); } else if (command == "sign") { if (vm.count("repotype") == 0 || vm.count("keyname") == 0) { std::cerr << "--repotype or --keyname is missing\n"; diff --git a/src/aktualizr_repo/repo_test.cc b/src/aktualizr_repo/repo_test.cc index 2998c8bd01..f3d782293a 100644 --- a/src/aktualizr_repo/repo_test.cc +++ b/src/aktualizr_repo/repo_test.cc @@ -190,6 +190,45 @@ TEST(aktualizr_repo, emptytargets) { EXPECT_EQ(empty_targets["targets"].size(), 0); } +TEST(aktualizr_repo, oldtargets) { + TemporaryDirectory temp_dir; + UptaneRepo repo(temp_dir.Path(), "", ""); + repo.generateRepo(key_type); + repo.addImage("target1", "8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6", 123); + repo.addImage("target2", "8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6", 321); + repo.addTarget("target1", "test-hw", "test-serial"); + repo.signTargets(); + repo.addTarget("target2", "test-hw", "test-serial"); + + Json::Value targets = Utils::parseJSONFile(temp_dir.Path() / "repo/director/staging/targets.json"); + EXPECT_EQ(targets["targets"].size(), 2); + EXPECT_EQ(targets["targets"]["target1"]["length"].asUInt(), 123); + EXPECT_EQ(targets["targets"]["target1"]["hashes"]["sha256"].asString(), + "8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6"); + EXPECT_EQ(targets["targets"]["target2"]["length"].asUInt(), 321); + EXPECT_EQ(targets["targets"]["target2"]["hashes"]["sha256"].asString(), + "8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6"); + + Json::Value targets_current = Utils::parseJSONFile(temp_dir.Path() / "repo/director/targets.json"); + EXPECT_EQ(targets_current["signed"]["targets"].size(), 1); + EXPECT_EQ(targets_current["signed"]["targets"]["target1"]["length"].asUInt(), 123); + EXPECT_EQ(targets_current["signed"]["targets"]["target1"]["hashes"]["sha256"].asString(), + "8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6"); + + std::string cmd = generate_repo_exec + " oldtargets " + temp_dir.Path().string(); + std::string output; + int retval = Utils::shell(cmd, &output); + if (retval) { + FAIL() << "'" << cmd << "' exited with error code\n" + << "output: " << output; + } + targets = Utils::parseJSONFile(temp_dir.Path() / "repo/director/staging/targets.json"); + EXPECT_EQ(targets["targets"].size(), 1); + EXPECT_EQ(targets["targets"]["target1"]["length"].asUInt(), 123); + EXPECT_EQ(targets["targets"]["target1"]["hashes"]["sha256"].asString(), + "8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6"); +} + #ifndef __NO_MAIN__ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/src/aktualizr_repo/uptane_repo.cc b/src/aktualizr_repo/uptane_repo.cc index 498a700771..b53f5f516c 100644 --- a/src/aktualizr_repo/uptane_repo.cc +++ b/src/aktualizr_repo/uptane_repo.cc @@ -24,4 +24,5 @@ void UptaneRepo::addImage(const std::string &name, const std::string &hash, uint void UptaneRepo::signTargets() { director_repo_.signTargets(); } -void UptaneRepo::emptyTargets() { director_repo_.emptyTargets(); } \ No newline at end of file +void UptaneRepo::emptyTargets() { director_repo_.emptyTargets(); } +void UptaneRepo::oldTargets() { director_repo_.oldTargets(); } \ No newline at end of file diff --git a/src/aktualizr_repo/uptane_repo.h b/src/aktualizr_repo/uptane_repo.h index 30cf01a3bb..c6d71932c3 100644 --- a/src/aktualizr_repo/uptane_repo.h +++ b/src/aktualizr_repo/uptane_repo.h @@ -13,6 +13,7 @@ class UptaneRepo { void addImage(const std::string &name, const std::string &hash, uint64_t length); void signTargets(); void emptyTargets(); + void oldTargets(); private: DirectorRepo director_repo_;