Commit Graph

86 Commits

Author SHA1 Message Date
Bryan Oltman 4685789e59 feat: store patch signature on disk with patch metadata (#170)
* feat: store patch signature on disk with patch metadata

* add note about explicit lifetime

* fix tests
2024-05-22 10:00:36 -04:00
Bryan Oltman 5de07bb48a feat: store patch hash on disk (#169) 2024-05-21 14:38:37 -04:00
Bryan Oltman a2e9f5de54 feat: read public key from release yaml (#168) 2024-05-21 12:30:28 -04:00
Bryan Oltman d30931771b fix: Don't make network request while holding config lock (#161)
* Add test to demonstrate hang when attempting to init while waiting for a patch check request

* Fix thread contention when initing during patch check

* Clean up test

* revert change to fake_yaml

* reorg

* lower timeout in test
2024-05-14 10:05:38 -04:00
Bryan Oltman 7361089102 docs: update state machine description in readme (#151)
* docs: update state machine description in readme

* wording

* specify storage location

* add unimplemented note

* update file structure overview

* wording, remove reference to dart-bindings

* add assumptions re: PatchManager state
2024-04-25 09:53:05 -04:00
Bryan Oltman 9dc5f0e9c6 fix: delete all old patch artifacts on successful boot (#150)
* fix: verify failed patch is next_boot_patch before clearing

* add record_boot_start_for_patch now that it exists

* fix: delete all old patch artifacts on successful boot

* add comment

* additional docs on delete_patch_artifacts_older_than

* update comments

* delete unrecognized patch subdirectories

* error logging
2024-04-24 09:42:20 -04:00
Bryan Oltman dc7aea0c01 fix: verify failed patch is next_boot_patch before clearing (#149)
* fix: verify failed patch is next_boot_patch before clearing

* add record_boot_start_for_patch now that it exists

* add comment

* add comments

* cleanup
2024-04-23 17:34:40 -04:00
Bryan Oltman 435dc836a0 feat: update patch manager to only attempt to boot from a patch once (#138)
* feat: record the last patch we attempted to boot from to better capture failures

* add tests

* coverage

* update readme

* clarify comment

* comment feedback

* comment feedback

* refactor

* cleanup

* Update library/src/cache/patch_manager.rs

Co-authored-by: Eric Seidel <eric@shorebird.dev>

* Update library/src/cache/patch_manager.rs

Co-authored-by: Eric Seidel <eric@shorebird.dev>

---------

Co-authored-by: Eric Seidel <eric@shorebird.dev>
2024-04-22 16:21:30 -04:00
Eric Seidel fe465ea1b1 chore: remove unused package (#142) 2024-04-19 21:00:33 +00:00
Bryan Oltman 70d130ad64 format readme 2024-04-17 16:58:58 -04:00
Bryan Oltman c484e4a97d chore: improve error messages printed by updater (#121)
* fix: us OSLog framework for logging on iOS

* cleanup

* chore: improve error messages printed by updater

* remove println

* cleanup

* warn -> info

* update set_config to not return anything

* revert pub test struct

* Update library/src/config.rs

Co-authored-by: Eric Seidel <eric@shorebird.dev>

---------

Co-authored-by: Eric Seidel <eric@shorebird.dev>
2024-02-06 17:17:09 -05:00
Bryan Oltman d3b88ec4b6 fix: us OSLog framework for logging on iOS (#120)
* fix: us OSLog framework for logging on iOS

* cleanup
2024-02-06 16:52:04 -05:00
Bryan Oltman ed013eb257 feat: Update C API to consume Read+Seek callbacks (#111)
* Update C API to consume Read+Seek callbacks

* remove open and close functions

* update to reflect new interface

* Refactor posix file i/o to c_api (#113)

* Refactor posix file i/o to c_api

* fix comment

* rename ExternalFile to ReadSeek

* cleanup and comments

* Add SHOREBIRD_PATCH_BASE_FILENAME const

* fix lint

* add fake callbacks for c_api tests

* fix tests

* remove os_last_error

* remove todos, add comments

* cleanup

* remove params to open

* add c_api module, tests

* reorganize

* Return Err if CFileProvider open returns null

* add comments and docs
2024-01-16 14:28:04 -05:00
Eric Seidel c6f8b2933e refactor: remove client_id (#110)
We added client_id back when we had a different billing model
where we would bill customers based on number of unique devices
accepting an install in a given month (similar to what expo.dev
advertised as their pricing model at the time).

We moved to a differnet pricing model and never used client_id
so removing it.
2023-12-21 13:00:14 -05:00
Bryan Oltman a70fe54668 test: use mockito crate to test network-interfacing code (#106)
* test: use mockito crate to test network-interfacing code

* tweak
2023-11-17 10:30:25 -05:00
Bryan Oltman d785568094 chore: don't error log if patches_state.json doesn't exist (#97) 2023-10-05 17:51:37 +00:00
Bryan Oltman b02610370a refactor: move patch management functionality out of UpdaterState (#93)
* non-compiling WIP

* update

* add cfg test

* address clippy issues

* minor consistency

* introduce patch manager, delegate patch management functionality from updater state

* cleanup

* Restructure patch state on disk, adds patch validation

* Simplify patches state, move patches to subdirectories of patches/ instead of having the artifacts as immediate children

* Tests

* delete unused enum

* disk manager tests

* Tests, docs

* rename

* delete unused file

* fix todo

* error logging

* cleanup

* cleanup

* comments and cleanup

* cleanup

* debug log

* boot from previous patch if next patch is bad

* fallback logic and test

* fix log

* context -> with_context

* remove get from get_next_boot_patch

* Log patch state load error

* renaming

* coverage

* capitalization

* coverage

* Replace unwrap with ? in disk_io

* Fix record boot success

* eq none -> .is_none

* Move delete_patch_artifacts failure logging into function

* rename patch_install_success_fn to report_event_fn

* Fix patch install reporting

* update comment
2023-10-03 13:58:23 -04:00
Bryan Oltman 194fdc3220 refactor: create module directory for cache (#91) 2023-09-26 16:44:13 -04:00
Bryan Oltman 3f907de7c0 Revert "feat: treat iOS patches as diffs instead of full artifacts (#88)" (#90)
This reverts commit f4db98b759.
2023-09-26 15:41:01 -04:00
Bryan Oltman f4db98b759 feat: treat iOS patches as diffs instead of full artifacts (#88)
* feat: apply iOS patches from diffs

* Clean up imports

* fix lint

* Add iOS, tests

* refactor

* revert changes to shorebird_code_push

* remove unused debug trait

* coverage

* imports
2023-09-22 16:58:31 -04:00
Bryan Oltman bd86f617e1 fix: don't serialize UpdaterState cache_dir as it can change between app runs (#87)
* fix: don't serialize UpdaterState cache_dir as it can change between app runs

* tests

* update tests
2023-09-20 16:08:58 -04:00
Eric Seidel ebd721fea7 chore: print path create_dir_all fails at on failure (#86)
Co-authored-by: Bryan Oltman <bryanoltman@gmail.com>
2023-09-20 14:30:16 -04:00
Bryan Oltman b4024cf499 fix: add separate storage dir for state (#84) 2023-09-12 16:13:19 -04:00
Eric Seidel e4b182d75d chore: fix 30 of the 54 warnings from clippy pedantic. (#81)
I just ran `cargo clippy -- -W clippy::pedantic` and fixed things.

These are more invasive that the default set and the remaining
warnings are mostly about our (abysmal) public docs missing
Error and Panic sections to explain errors and panicks.
2023-09-08 17:51:07 +00:00
Eric Seidel 20b65f14c2 chore: run cargo clippy over our rust codebase (#80)
* chore: apply fixes from clippy

* Add a Safety section to appease clippy
2023-09-08 17:30:19 +00:00
Eric Seidel 15b2f6bfaa feat: report patch install failure events (#78)
* feat: report failure events to our servers

This doesn't tell us anything about the failure, just that it
happened.  Which at least will let us communicate that to customers.

This currently has no tests and will need some before landing.

* Address review comments

* Use use statements for config and events

* Add partial test

* Add comment about when save happens
2023-09-08 09:48:04 -07:00
Eric Seidel 9d4ce55c2b refactor: Prepare to have more than one event type (#77)
Refactored our PatchInstallEvent to be just PatchEvent
and allow us to have more than one event type.

I moved it into its own events.rs file and added privacy
warnings to both this and the network code (eventually
we may move all this into a separate privacy.rs file).

I also fixed our build.rs file to not panic when our build
is otherwise broken. For whatever reason that seems to
cause the rust-analyzer to stop and not show any future
warnings (thus it's hard to fix things).

I moved away from having a "new" method for PatchEvent
with a series of Strings (which could be confused in order)
and instead am now using just the normal default struct
construction which effectively has named args.

Since EventType is now an enum, it's easy to use the
right enum not have to call PatchInstallEvent::new to
get the right magic string for "identifier".

Also added a bit more documentation to c_api.rs
2023-09-07 12:31:32 -07:00
Bryan Oltman 292f978950 fix: don't regenerate client id if UpdaterState successfully loaded (#76)
* fix: don't regenerate client id if UpdaterState successfully loaded

* tests, cleanup

* comments
2023-09-07 10:48:43 -04:00
Eric Seidel ef268acaf6 fix: show patch check info in logs (#73) 2023-09-01 08:17:02 -07:00
Bryan Oltman 53072a9128 fix: put call to report launch success on bg thread. (#72)
* fix: use non-blocking http client when reporting launch success

* Make patch install report request on bg thread

* Pass client_id instead of state

* Convert client_id from &str to String
2023-08-17 14:55:26 -04:00
Bryan Oltman 7417429d91 fix: log more friendly error message in case of no internet connection (#67)
* fix: log more friendly error message in case of no internet connection

* fix typo

* coverage
2023-08-17 08:36:10 -04:00
Bryan Oltman 99f3005ff4 feat: add support for reporting patch install events (#71)
* feat: add client_id to UpdaterState

* feat: add support for reporting patch install events

* Ensure we save UpdaterState after it's created

* Save state if we assign it a client id on load

* Don't error in report_launch_success if no patch exists

* coverage

* Rename

* Minor refactor

* coverage

* coverage

* Update library/src/updater.rs

Co-authored-by: Felix Angelov <felix@shorebird.dev>

* restore debug logs

* make test serial

---------

Co-authored-by: Felix Angelov <felix@shorebird.dev>
2023-08-11 13:56:46 -04:00
Bryan Oltman d321ad02de feat: add client_id to UpdaterState (#70)
* feat: add client_id to UpdaterState

* Ensure we save UpdaterState after it's created

* Save state if we assign it a client id on load

* Rename
2023-08-11 11:23:13 -04:00
Bryan Oltman ffabae1ae6 chore: sort deps in Cargo.toml (#69)
* chore: sort deps in Cargo.toml

* more sorting

* even more sorting

* remove unused lib
2023-08-10 09:50:44 -04:00
Eric Seidel 1841f59b94 refactor: Use Result to indicate failure in mark_patch_bad (#66)
I'm not sure if this is better or worse, but it does make testing
a bit more clear.
2023-08-04 16:55:35 +00:00
Eric Seidel 15ab0f2295 feat: add support for parsing auto_update from shorebird.yaml (#65)
* feat: add support for parsing auto_update from shorebird.yaml

The actual support will be in the C++ engine, but this keeps
all yaml parsing in the Rust code for simplicity.

---------

Co-authored-by: Felix Angelov <felix@shorebird.dev>
2023-08-03 18:37:09 +00:00
Eric Seidel 5fcf97e3e0 test: improve rust coverage (#64)
Refactored our android code slightly so we could test all the
branches of our "find the right split apk" function.
2023-08-03 11:25:08 -05:00
Eric Seidel ae85cf5125 fix: Improve rust logging and error clarity (#63)
* Improve logging from our rust code.

Fixes https://github.com/shorebirdtech/updater/issues/56
and https://github.com/shorebirdtech/shorebird/issues/779
and https://github.com/shorebirdtech/updater/issues/61

I did not add a test for the log handling when starting a thread
(didn't see an easy way to do so, without mocking the update
call itself?)

I also did not add a test for changing the log verbosity.

Verified both by hand.

* Reduce logging.

Also removed unused assets.rs file.
Also silenced "file not found" error case on first boot.

* Improve coverage
2023-07-31 21:51:08 +00:00
Eric Seidel 3af4081f55 fix: Only allow one update attempt at a time (#44)
This is all for shorebirdtech/shorebird#695

I ended up fixing a lot of things in our Rust code while I was in there, including:

* Using PathBuf instead of Sting wherever we are holding onto Path objects (this removed a bunch of code which was converting in and out of these).
* Made a variety of functions private (the default) that were previously mistakenly pub.
* Moved the android hacks around libapp_paths closer to the C++ code. Previously we were storing all of the libapp_paths on ResolvedConfig and handling the android hacks during patch install. Now we're doing the android path hacks on init, eventually we'll remove them entirely by making the C++ code pass us in the android app_dir or even the resolved .apk we need instead of the libapp_paths.
* Fixed several tests to use /dir/lib/arch/libapp.so paths instead of 'libapp.so' now that the init code applies the android hacks an expects the deeper paths. Again, this will go away when we move the android hacks into c++.
* Added a test which confirms that if we init twice we log instead of trying to init again (this was one behavior which FCM was triggering as part of fix: ANR when using Firebase Cloud Messaging with Shorebird shorebird#695
* Add a test which confirms that further calls to update while an update is ongoing just fail out quickly instead of hanging.
* Moved to serial_test instead of a separate per-thread config system for testing. This makes our tests operate more like the code does in the wild, at the cost of needing to annotate a test as #[serial] any time it needs to use shorebird_init.
* Removed ResolvedConfig and now call it UpdateConfig. ResolvedConfig previously had a bool on it to tell if it was initialized, that's now represented as Option instead which is more rusty.
* Changed how we handle NetworkHooks from being compile-time test switched to using function pointers held off of UpdateConfig.network_hooks. I think this makes more sense? I did this to remove the special ThreadConfig object which was used during unit tests, but didn't exist in production. I think the way we mock networking could still be improved.
2023-06-22 12:45:55 -07:00
Eric Seidel c627ad79a1 chore: Remove dead UpdateStatus code (#42)
We never used UpdateDownloaded (and I'm not sure we need this enum at all), so at least removing the dead one.
2023-06-21 18:18:03 +00:00
Bryan Oltman 318d86e13f feat: add shorebird_current_boot_patch_number function (#36)
* feat: add shorebird_current_boot_patch_number function

* Continue support for next_patch_version

* rename, return null in case of 0
2023-06-20 16:45:43 -04:00
Bryan Oltman 0222f526a6 chore: use a number instead of a string for next boot patch number (#34) 2023-06-19 22:49:59 -04:00
Eric Seidel bce1508787 fix: remove more unwrap calls. (#24)
Each unwrap() is a potential crash.  Shorebird's updater code
should never crash.

There still are a couple, but I think we should set up coverage
first so we can track that we're testing all these changes.
2023-06-08 15:14:09 -07:00
Eric Seidel 50f0b022df feat: Support iOS (#23)
Adds support for iOS to the updater library.

Refactored the android-specific code into an android module.

The tests still mostly use the android code, rather than testing iOS paths too, but that can be fixed in a follow-up.

I had to change how "latest patch number" works to understand when patch files disappear from disk (which I thought was happening on iOS initially).

I also had to make status.json not store absolute paths to patch files (since the absolute path changes per-xcode run on iOS).
2023-06-08 17:34:10 -04:00
Eric Seidel 4d2ec2e148 feat: Make updater build on iOS (#22)
Doesn't work yet, but does at least build (and log).
2023-05-31 14:44:35 -05:00
Bryan Oltman 11d8c22805 fix: don't panic on missing shorebird.yaml (#18)
* fix: don't panic on missing shorebird.yaml

* fix next_boot_patch C api

* don't log error in updater

* Cleanup

* Remove anyhow::bail import
2023-05-16 16:21:43 -04:00
Eric Seidel 7809b5f6fe Remove mention of cbindgen manual step 2023-05-16 11:42:25 -07:00
Eric Seidel 226df7d08d test: Make our rust tests use per-thread config rather than global static (#14)
* Make our rust tests use per-thread config rather than global static

This lets our unit tests run in parallel.  I also moved our "integration"
tests back to be unit tests for now.

This also exposes a network mocking abstraction.

I've added an incomplete test of applying a full patch.  Still
needs some work to complete.

* Finish making the patch success test work

* Changed our test config to use println instead of info/error, etc. so that tests show output on failure (there might be a better way?)
Unfortunately macro_use (which is the way we were causing error!, info! etc to appear everywhere with only one global import before, only works on crates not on std, so I had to be explicit with my imports per-file.
* Add a function to build a fake zip file, because that's what the updater currently expects.  Better would be for us to move to a AssetManager system I suspect, then the updater would ask the asset manager for the libapp.so and we'd return it instead of having to go through writing out a zip file.
* Added a string_patch.rs tool and shared code between that and the patch tool.  This made it possible/easy for me to generate the necessary binary patches as well as needed hashes to pretend to be the patch server.
* Added one simple test of the patch tool core logic.

In total we're now above 80% coverage of our rust code after this.

* remove stray comment
2023-04-26 13:07:19 -05:00
Eric Seidel e4a883c8a7 Refactor C API to avoid using unwrap. (#12)
This removes another source of possible crashes from the rust code.

I also took this opportunity to try and test the C-api. I also
discovered rust "integration tests" as part of this and chose
to move some of the (new) c_api tests to an integration test
as well as the existing rust api (updater.rs) tests.
2023-04-25 15:39:33 -05:00
Eric Seidel 4ab78869b8 feat: Add start_updater_thread to update off the main thread (#11)
* feat: Add start_updater_thread to update off the main thread

This makes it so that clients can easily not block when wanting to
queue an update.

I have a separate patch which updates the Engine to use this new
API.

I also needed to split the concept of the "next_boot" patch
from the "current_boot" patch, previously refered to as
"current" or "active" patch.  This required adding a
report_launch_start api to let the updater library know
when to set current_boot patch from next_boot.

I also removed the rust updater/cli in this as well as the
vmpath argument to init.

I also exposed the report_launch_success api, but its not yet
used by the Engine.

I renamed report_failed_launch to report_launch_failure to match
report_launch_start which I introduced.

* Update naming per comments from Felix.

Also added a helper for char* allocation (not sure if it's better).

* Update library/src/updater.rs

---------

Co-authored-by: Felix Angelov <felix@shorebird.dev>
2023-04-25 09:06:40 -07:00