-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add remote file handling #30
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO downloading the artifact when creating a new DB entry to get the hashes is a reasonable approach.
I’ve only skimmed over the changes as reviewing on the phone is not that fun.
goosebit/models.py
Outdated
hw_revision = fields.CharField(max_length=255) | ||
|
||
|
||
class FirmwareUpdate(Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just call it Firmware
as it does not have to be an update, it could technically also be a downgrade (if we would start to allow that) or the initial image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rollout model needs to be adjusted as well - instead of hw_model, hw_revision, fw_file it only should reference a firmware.
This then also means work in Manager.get_rollout to query the correct firmware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rollout model needs to be adjusted as well - instead of hw_model, hw_revision, fw_file it only should reference a firmware.
This then also means work in Manager.get_rollout to query the correct firmware.
This can get really tricky, if I link Firmware
directly then all the stuff that wants to check for rollout that uses the device as a backup need to return Firmware
, which means fw_file
on Device
needs to be replaced with Firmware
, but then that gets rid of latest
and pinned
, which can make things pretty complicated. Let me know what you guys think here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it triggers a few follow-up changes. I have a branch where I introduced update_mode
on Device (enum with latest
, rollout
, assigned
, and pinned
), so that fw_file
could be changed to firmware
on Device.
Will re-implement those changes on top of this branch to see if it makes sense.
Oh, and please note this comment: c553176#r144602289 |
I think we should slow down somewhat: as there are no automatic test in the code base, every PR breaks some functionality. Manual testing (what I was doing so far) takes forever. So we better ensure to have tests for the existing functionality before adding / refactoring code. I created automated API integration tests (focus on the DDI) yesterday - and currently adjust the test code to match this PR. Ideally I could finish these tests (few of them will fail as the code is broken), integrate them into this PR and ensure that everything passes before merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few things I saw while writing tests. Some if them cause my current tests to fail.
goosebit/models.py
Outdated
hw_revision = fields.CharField(max_length=255) | ||
|
||
|
||
class FirmwareUpdate(Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rollout model needs to be adjusted as well - instead of hw_model, hw_revision, fw_file it only should reference a firmware.
This then also means work in Manager.get_rollout to query the correct firmware.
goosebit/db.py
Outdated
@@ -22,6 +23,10 @@ async def init(): | |||
await command.migrate() | |||
await command.upgrade(run_in_transaction=True) | |||
await Tortoise.generate_schemas(safe=True) | |||
for update in await FirmwareUpdate.all(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of all()
better to filter on db using filter()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what to filter by here, I suppose maybe uri
starts with file
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought about using await Firmware.filter(url__startswith='file').all()
. Debatable if a good idea, as logic of local
is the implemented in two different places. On the upside: with a lot of remote firmware it will be very fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I finished a first set of integration test - they can be found at https://github.com/husqvarnagroup/goosebit/tree/mm/add_simple_ddi_integration_tests
Besides the commit adding the tests there is an additional one that makes the tests pass. Most of the things are also annotated in this PR.
Note: poetry run pytest
does not pass all the tests. Single execution of tests work (I do it using PyCharm). Will look into this soon (but not today)
swdesc_attrs["version"] = semver.Version.parse(swdesc["software"]["version"]) | ||
swdesc_attrs["size"] = file.stat().st_size | ||
swdesc_attrs["hash"] = sha1_hash_file(file) | ||
swdesc_attrs["compatibility"] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parsing does not work for our images. Our swdesc looks (shortened) like the following:
{
"software": {
"version": "8.8.1-12-g302f635+189128",
"description": "Linux System Firmware (hawkbit) for the GARDENA smart Gateway gardena-sg-mt7688",
"smart-gateway-mt7688": {
"hardware-compatibility": [
"0.5",
"1.0",
"1.1.0",
"1.2.0",
"1.2.1"
],
"stable": {
"bootslot0": {
"images": [
{
"filename": "gardena-image-hawkbit-gardena-sg-mt7688.squashfs-xz",
"volume": "rootfs1",
"sha256": "a7fd6b6b3416efc3a58993280f7335f84826af6a73164624e9cb6b5201499c18",
"hook": "check_version_and_leds",
"installed-directly": true
}
],
"bootenv": [
]
},
"bootslot1": {
"images": [
{
"filename": "gardena-image-hawkbit-gardena-sg-mt7688.squashfs-xz",
"volume": "rootfs0",
"sha256": "a7fd6b6b3416efc3a58993280f7335f84826af6a73164624e9cb6b5201499c18",
"hook": "check_version_and_leds",
"installed-directly": true
}
],
"bootenv": [
]
}
}
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a standard on how this is supposed to be set? We use loadsync.v1
here, but I'm not sure if there is any standard here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not my area of expertise. Maybe @easybe can provide information once he is back.
I'll try to take a look at this later tonight, at a conference this week so I don't have a ton of time, but I'll fix what I can ASAP.
Agreed, but I really want to get the important core functionality we want figured out ASAP. I'm not a big tests guy personally, I think it's definitely a good idea in this case, I just struggle with the differences between trying to finish important functionality and stabilizing the code/API. There seem to be a lot of cases where the dev API needs to change for important things to happen, so I wasn't sure if we wanted to wait to write tests until after that. |
Implemented these, and fixed your issue with pytest not working properly. Just need to add |
I think this PR is ready to be merged - great stuff. Follow-up work can be done in a new branch / PR. Will look replacing fw_file with firmware. |
Adds remote firmware handling for files. Based on #29. Closes #28. Closes #29.
Adding independently so they can be merged independently if there are concerns on this PR.
Main concern here is that I don't have a better way to get the hash of the upgrade file (required for swupdate artifact) without just downloading the file when the link is added.