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

Commit

Permalink
Cache secondary manifest when not available
Browse files Browse the repository at this point in the history
Signed-off-by: Laurent Bonnans <laurent.bonnans@here.com>
  • Loading branch information
lbonn committed Jan 24, 2020
1 parent 1f8b571 commit 3f22919
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 2 deletions.
1 change: 1 addition & 0 deletions config/sql/migration/migrate.23.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ SAVEPOINT MIGRATION;
ALTER TABLE ecu_serials ADD COLUMN sec_type TEXT NOT NULL DEFAULT "";
ALTER TABLE ecu_serials ADD COLUMN public_key_type TEXT NOT NULL DEFAULT "";
ALTER TABLE ecu_serials ADD COLUMN public_key TEXT NOT NULL DEFAULT "";
ALTER TABLE ecu_serials ADD COLUMN manifest TEXT NOT NULL DEFAULT "";

DELETE FROM version;
INSERT INTO version VALUES(23);
Expand Down
2 changes: 1 addition & 1 deletion config/sql/schema.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CREATE TABLE version(version INTEGER);
INSERT INTO version(rowid,version) VALUES(1,23);
CREATE TABLE device_info(unique_mark INTEGER PRIMARY KEY CHECK (unique_mark = 0), device_id TEXT, is_registered INTEGER NOT NULL DEFAULT 0 CHECK (is_registered IN (0,1)));
CREATE TABLE ecu_serials(id INTEGER PRIMARY KEY, serial TEXT UNIQUE, hardware_id TEXT NOT NULL, is_primary INTEGER NOT NULL DEFAULT 0 CHECK (is_primary IN (0,1)), sec_type TEXT NOT NULL DEFAULT "", public_key_type TEXT NOT NULL DEFAULT "", public_key TEXT NOT NULL DEFAULT "");
CREATE TABLE ecu_serials(id INTEGER PRIMARY KEY, serial TEXT UNIQUE, hardware_id TEXT NOT NULL, is_primary INTEGER NOT NULL DEFAULT 0 CHECK (is_primary IN (0,1)), sec_type TEXT NOT NULL DEFAULT "", public_key_type TEXT NOT NULL DEFAULT "", public_key TEXT NOT NULL DEFAULT "", manifest TEXT NOT NULL DEFAULT "");
CREATE TABLE misconfigured_ecus(serial TEXT UNIQUE, hardware_id TEXT NOT NULL, state INTEGER NOT NULL CHECK (state IN (0,1)));
CREATE TABLE installed_versions(id INTEGER PRIMARY KEY, ecu_serial TEXT NOT NULL, sha256 TEXT NOT NULL, name TEXT NOT NULL, hashes TEXT NOT NULL, length INTEGER NOT NULL DEFAULT 0, correlation_id TEXT NOT NULL DEFAULT '', is_current INTEGER NOT NULL CHECK (is_current IN (0,1)) DEFAULT 0, is_pending INTEGER NOT NULL CHECK (is_pending IN (0,1)) DEFAULT 0, was_installed INTEGER NOT NULL CHECK (was_installed IN (0,1)) DEFAULT 0, custom_meta TEXT NOT NULL DEFAULT "");
CREATE TABLE primary_keys(unique_mark INTEGER PRIMARY KEY CHECK (unique_mark = 0), private TEXT, public TEXT);
Expand Down
19 changes: 18 additions & 1 deletion src/libaktualizr/primary/sotauptaneclient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,27 @@ Json::Value SotaUptaneClient::AssembleManifest() {
version_manifest[primary_ecu_serial.ToString()] = uptane_manifest->sign(primary_manifest, report_counter);

for (auto it = secondaries.begin(); it != secondaries.end(); it++) {
const Uptane::EcuSerial &ecu_serial = it->first;
Uptane::Manifest secmanifest = it->second->getManifest();

bool from_cache = false;
if (secmanifest == Json::Value()) {
// could not get the secondary manifest, a cached value will be provided
std::string cached;
if (storage->loadCachedEcuManifest(ecu_serial, &cached)) {
LOG_WARNING << "Could not reach secondary " << ecu_serial << ", sending a cached version of its manifest";
secmanifest = Utils::parseJSON(cached);
from_cache = true;
} else {
LOG_ERROR << "Could not fetch a valid secondary manifest from cache";
}
}

if (secmanifest.verifySignature(it->second->getPublicKey())) {
version_manifest[it->first.ToString()] = secmanifest;
version_manifest[ecu_serial.ToString()] = secmanifest;
if (!from_cache) {
storage->storeCachedEcuManifest(ecu_serial, Utils::jsonToCanonicalStr(secmanifest));
}
} else {
// TODO: send a corresponding event/report in this case, https://saeljira.it.here.com/browse/OTA-4305
LOG_ERROR << "Secondary manifest is corrupted or not signed, or signature is invalid manifest: " << secmanifest;
Expand Down
3 changes: 3 additions & 0 deletions src/libaktualizr/storage/invstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ class INvStorage {
virtual bool loadEcuSerials(EcuSerials* serials) = 0;
virtual void clearEcuSerials() = 0;

virtual void storeCachedEcuManifest(const Uptane::EcuSerial& ecu_serial, const std::string& manifest) = 0;
virtual bool loadCachedEcuManifest(const Uptane::EcuSerial& ecu_serial, std::string* manifest) = 0;

virtual void storeMisconfiguredEcus(const std::vector<MisconfiguredEcu>& ecus) = 0;
virtual bool loadMisconfiguredEcus(std::vector<MisconfiguredEcu>* ecus) = 0;
virtual void clearMisconfiguredEcus() = 0;
Expand Down
37 changes: 37 additions & 0 deletions src/libaktualizr/storage/sqlstorage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,43 @@ void SQLStorage::clearEcuSerials() {
}
}

void SQLStorage::storeCachedEcuManifest(const Uptane::EcuSerial& ecu_serial, const std::string& manifest) {
SQLite3Guard db = dbConnection();

auto statement = db.prepareStatement<std::string, std::string>(
"UPDATE ecu_serials SET manifest = ? WHERE (serial = ? AND is_primary = 0);", manifest, ecu_serial.ToString());
if (statement.step() != SQLITE_DONE || sqlite3_changes(db.get()) != 1) {
LOG_ERROR << "Can't save secondary manifest " << db.errmsg();
return;
}
}

bool SQLStorage::loadCachedEcuManifest(const Uptane::EcuSerial& ecu_serial, std::string* manifest) {
SQLite3Guard db = dbConnection();

std::string stmanifest;

bool empty = false;

auto statement = db.prepareStatement<std::string>(
"SELECT manifest FROM ecu_serials WHERE (serial = ? AND is_primary = 0);", ecu_serial.ToString());

if (statement.step() != SQLITE_ROW) {
LOG_WARNING << "Could not find manifest for ecu " << ecu_serial;
return false;
} else {
stmanifest = statement.get_result_col_str(0).value();

empty = stmanifest == "";
}

if (manifest != nullptr) {
*manifest = std::move(stmanifest);
}

return !empty;
}

void SQLStorage::storeMisconfiguredEcus(const std::vector<MisconfiguredEcu>& ecus) {
if (ecus.size() >= 1) {
SQLite3Guard db = dbConnection();
Expand Down
2 changes: 2 additions & 0 deletions src/libaktualizr/storage/sqlstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class SQLStorage : public SQLStorageBase, public INvStorage {
void storeEcuSerials(const EcuSerials& serials) override;
bool loadEcuSerials(EcuSerials* serials) override;
void clearEcuSerials() override;
void storeCachedEcuManifest(const Uptane::EcuSerial& ecu_serial, const std::string& manifest) override;
bool loadCachedEcuManifest(const Uptane::EcuSerial& ecu_serial, std::string* manifest) override;
void storeMisconfiguredEcus(const std::vector<MisconfiguredEcu>& ecus) override;
bool loadMisconfiguredEcus(std::vector<MisconfiguredEcu>* ecus) override;
void clearMisconfiguredEcus() override;
Expand Down

0 comments on commit 3f22919

Please sign in to comment.