Skip to content

Commit 1975226

Browse files
committed
liteclient: Send TUF update event only if target list changes
Send the TUF update event only if a target list has changed. It helps to avoid sending the event if TUF meta is updated while the target list stays the same. It can happen if a customer updates target lists only for certain subset of tags. It leads to updating TUF meta for all tags while actual target list is updated only for the specified set of tag. Signed-off-by: Mike Sul <mike.sul@foundries.io>
1 parent 7cfb58d commit 1975226

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

src/liteclient.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ void LiteClient::notifyTufUpdateStarted() {
448448
auto& d = tuf_update_details_[role.ToString()];
449449
d.from = version;
450450
});
451+
targets_ = getTargetList(storage);
451452
}
452453

453454
void LiteClient::notifyTufUpdateFinished(const std::string& err, const Uptane::Target& t) {
@@ -468,6 +469,15 @@ void LiteClient::notifyTufUpdateFinished(const std::string& err, const Uptane::T
468469
was_updated = d.from != d.to;
469470
});
470471

472+
if (was_updated && targets_ && targets_->isInitialized()) {
473+
// If TUF meta was updated and the target list before the update is valid,
474+
// then check if the target list was updated too.
475+
const auto current_targets{getTargetList(storage)};
476+
if (current_targets && current_targets->isInitialized()) {
477+
was_updated = !Uptane::MatchTargetVector(current_targets->targets, targets_->targets);
478+
}
479+
}
480+
471481
if (!err.empty() || was_updated) {
472482
// Compose the "details" string with info about metadata if there is an error or metadata was updated
473483
for (const auto& d : tuf_update_details_) {
@@ -956,3 +966,26 @@ void LiteClient::forEachRoleVersion(std::shared_ptr<const INvStorage> storage,
956966
func(role, ver);
957967
}
958968
}
969+
970+
std::shared_ptr<Uptane::Targets> LiteClient::getTargetList(std::shared_ptr<const INvStorage> storage) {
971+
std::shared_ptr<Uptane::Targets> targets;
972+
std::string meta;
973+
bool loaded;
974+
975+
loaded = storage->loadNonRoot(&meta, Uptane::RepositoryType::Image(), Uptane::Role::Targets());
976+
if (!loaded) {
977+
return targets;
978+
}
979+
980+
const auto meta_json{Utils::parseJSON(meta)};
981+
if (meta_json.empty() || !meta_json.isObject()) {
982+
return targets;
983+
}
984+
985+
try {
986+
targets = std::make_shared<Uptane::Targets>(meta_json);
987+
} catch (const std::exception& exc) {
988+
LOG_DEBUG << "Failed to load targets meta: " << exc.what();
989+
}
990+
return targets;
991+
}

src/liteclient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ class LiteClient {
124124
static void forEachRoleVersion(std::shared_ptr<const INvStorage> storage,
125125
const std::function<void(const Uptane::Role&, int)>& func);
126126

127+
static std::shared_ptr<Uptane::Targets> getTargetList(std::shared_ptr<const INvStorage> storage);
128+
127129
boost::filesystem::path callback_program;
128130
std::unique_ptr<KeyManager> key_manager_;
129131
std::shared_ptr<PackageManagerInterface> package_manager_;
@@ -146,6 +148,7 @@ class LiteClient {
146148
Type type_{Type::Undefined};
147149

148150
TufUpdateDetails tuf_update_details_;
151+
std::shared_ptr<Uptane::Targets> targets_;
149152
};
150153

151154
#endif // AKTUALIZR_LITE_CLIENT_H_

0 commit comments

Comments
 (0)