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

Basic first-order delegation support #1074

Merged
merged 19 commits into from
Feb 1, 2019
Merged

Basic first-order delegation support #1074

merged 19 commits into from
Feb 1, 2019

Conversation

pattivacek
Copy link
Collaborator

Yes, it's really here! However, there are still open questions and more work to be done:

  1. Nested delegations are not yet supported. It's probably not that much more work, but that wasn't my goal at this time.
  2. This has been tested with aktualizr-repo but not with the real ota-tuf on the server.
  3. tuf-test-vectors should really be updated with delegation cases.
  4. I'm open to more unit test suggestions.
  5. The delegation_basic test I wrote is mostly a copy of the full_no_correlation_id. Should these be combined?
  6. There is some inconsistency in using Role objects vs. just their names. This could probably be improved.

Anything else missing or wrong?

@codecov-io
Copy link

codecov-io commented Jan 29, 2019

Codecov Report

Merging #1074 into master will decrease coverage by 31.47%.
The diff coverage is 41.11%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master    #1074       +/-   ##
===========================================
- Coverage   75.32%   43.84%   -31.48%     
===========================================
  Files         157      158        +1     
  Lines        9137     9258      +121     
===========================================
- Hits         6882     4059     -2823     
- Misses       2255     5199     +2944
Impacted Files Coverage Δ
src/libaktualizr/storage/invstorage.h 5.12% <ø> (-92.31%) ⬇️
src/libaktualizr/primary/aktualizr.h 5% <ø> (-95%) ⬇️
src/libaktualizr/storage/sqlstorage.h 50% <ø> (ø) ⬆️
...libaktualizr/package_manager/packagemanagerfake.cc 2.43% <0%> (-90.25%) ⬇️
src/libaktualizr/uptane/imagesrepository.h 0% <0%> (-100%) ⬇️
src/aktualizr_secondary/aktualizr_secondary.cc 4.25% <0%> (-18.33%) ⬇️
src/libaktualizr/primary/sotauptaneclient.cc 0.12% <0%> (-87.15%) ⬇️
src/libaktualizr/storage/sqlstorage.cc 2.31% <0%> (-71.59%) ⬇️
src/libaktualizr/uptane/directorrepository.cc 8.33% <0%> (-91.67%) ⬇️
src/libaktualizr/uptane/imagesrepository.cc 1.16% <0%> (-83.69%) ⬇️
... and 81 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14ccc71...e51c532. Read the comment docs.

@pattivacek pattivacek force-pushed the feat/OTA-678/delegation branch 2 times, most recently from 05618c6 to bca0cc5 Compare January 30, 2019 08:33
config/sql/migration/migrate.15.sql Outdated Show resolved Hide resolved
src/libaktualizr/storage/invstorage.h Outdated Show resolved Hide resolved
return;
}

auto del_statement = db.prepareStatement<std::string>("DELETE FROM delegations WHERE role_name=?;", role.ToString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could be replace by a single "INSERT OR REPLACE"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I copied the style of the NonRoot functions. Why don't those do the same?

Copy link
Contributor

@lbonn lbonn Jan 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meta has a UNIQUE(repo, meta_type, version) but the delete is DELETE FROM meta WHERE (repo=? AND meta_type=?);.

With the current schema, INSERT OR REPLACE would allow multiple versions to accumulate while the current storeNonRoot only keep the last updated version. To be honest, I'm not sure which would be the preferred semantics, knowing that loadNonRoot only takes the last version (with ORDER BY and LIMIT 1). @OYTIS, any input?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lbonn Yes, the preferred semantics was to only keep the last version. Again ORDER BY and LIMIT are just for precaution, also known as defensive programming, which is not always considered a good style. We can delete them if you feel like it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not necessarily against defensive programming. Thing is, in this case the schema doesn't protect against multiple version. So should the unique constraint be only UNIQUE(repo, meta_type)? I find it weird that we keep this constraint in code only.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so after discussion with @OYTIS, it results from the old behavior where different versions could accumulate. The schema migration from UNIQUE(repo, meta_type, version) to UNIQUE(repo, meta_type) was postponed because it requires a bit of care: only the last version should be migrated, otherwise it would trigger db conflicts.

if (it == targets.targets.cend()) {
return std::unique_ptr<Uptane::Target>(nullptr);
} else {
// Search for the target in the top-level targets metadata.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice (but I can try after this is merged) to turn this logic into an iterator. Then I think the logic of this function would become a std::find call to the new iterator

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds feasible. But just so you know, I'm expecting this particular function to get reworked again when we actually get around to supporting nested delegations. It may also get more complex if/when we support prioritization and/or TAP 3 (multi-role delegations).

@pattivacek pattivacek force-pushed the feat/OTA-678/delegation branch 2 times, most recently from 58b2cec to 161d95b Compare January 31, 2019 11:05
@@ -1,3 +1,4 @@
-- Don't modify this! Create a new migration instead--see docs/schema-migrations.adoc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

This matches my understanding of the expected behavior for directory
structures in target names.

Signed-off-by: Patrick Vacek <[email protected]>
Delegated targets do not have their hashes stored in their parent.

Signed-off-by: Patrick Vacek <[email protected]>
Signed-off-by: Patrick Vacek <[email protected]>
Based on clang-tidy's advice.

Signed-off-by: Patrick Vacek <[email protected]>
* Simplify SQL logic for delegations.
* Reduce if/for nesting for target searching.

Signed-off-by: Patrick Vacek <[email protected]>
last_exception = Uptane::ExpiredMetadata("repo", "targets");
return false;
}
}

// Update Images delegated Targets Metadata
for (const std::string &delegation : images_repo.delegations("targets")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC @heartsucker had an idea that the delegation tree can be huge and we only want to download what is relevant on this particular update. Also one of the drivers to add support for delegations now was the idea to save space/bandwidth on potentially huge targets.json for maps by splitting them by region.

So something like an optional (to also support tuf-only scenario) parameter specifying list of targets from director would be useful. Or as an alternative (and probably closer to the spirit of TUF spec) solution, we could only download delegations when intending to download a target or are explicitly asked to.

It may better be left for a next PR though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recall the same conversations and had similar concerns. For the moment, we've "avoided" the problem by only processing first-order delegations. On one hand, I'm not sure how likely it really is that we will have more than a couple layers of delegation in the automotive world, but on the other hand I think it makes sense to be flexible with our design goals and thus careful and efficient in our implementation.

I agree that we probably shouldn't download all delegations and instead only get what we need. However, that would require a fairly substantial refactoring and I wasn't willing to do it for this PR. Perhaps that should be a requirement for the nested delegation support, though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patrickvacek
I think these issues somewhat correlate, but we can also run into bandwidth problems with simple non-nested delegations. For the aforementioned example of region-based delegation for maps, these don't necessarily need to be nested.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. Sounds like a higher-priority chunk of work than nesting, then. It shouldn't be too hard, but since I'm unlikely to be able to get it done in the next week or so, would it be possible to merge this as it is and then do that as a follow-up? Others are welcome to contribute; I'm just a bit loathe to let this languish for a week while I'm away.

In other news, it sounds like the backend puts delegated_targets.json into a special delegations/ subdirectory in the images repo.

@pattivacek
Copy link
Collaborator Author

These Travis errors are pretty annoying. It's failing to download an Ubuntu package in Docker. Not related to my PR; every Travis run is currently failing in a similar manner.

By the way, I've gotten as far as testing this PR against the server to the point that aktualizr goes looking for the delegated_targets.json, but it gets a 404.

@lbonn lbonn merged commit 49bc10b into master Feb 1, 2019
@lbonn lbonn deleted the feat/OTA-678/delegation branch February 1, 2019 11:23
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants