Hash Store, in-project and sketch SDKs#511
Merged
Merged
Conversation
d180762 to
a6ed87b
Compare
a6ed87b to
e2fee2f
Compare
Contributor
Author
|
Marking this as ready now, but I will try to make the local SDK changes more back-compatible |
There was a problem hiding this comment.
Pull Request Overview
This PR introduces hashing for Store, in-project, and sketch SDKs, bringing them in line with the existing Try SDK hashing mechanism. The changes enable caching SDK snapshots across multiple workshops and add comprehensive validation of SDK definitions before installation.
Key changes:
- Store SDKs now support MD5 hashing (with SHA3 planned for future Store migration)
- Local SDKs are hashed using SHA3-384, with content-addressable storage replacing direct copies
- SDK validation is performed early in the launch/refresh process to catch configuration issues before deployment
Reviewed Changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/sdk/store.go | Updates SdkResult structure to include hash fields and modifies download interface to return SDK metadata |
| internal/sdk/local.go | Implements content-addressable storage for local SDKs using SHA3-384 hashes with symlinked revisions |
| internal/fakestore/store.go | Adds MD5 hash computation and caching for Store SDK downloads |
| internal/workshop/workshop.go | Introduces ValidateSdkInfo function for early SDK definition validation |
| internal/overlord/workshopstate/request.go | Integrates SDK validation into launch and refresh workflows |
| internal/overlord/sdkstate/handlers.go | Updates download handlers to process and validate SDK metadata |
| internal/osutil/hash.go | Implements git-compatible directory hashing algorithm |
| internal/osutil/sys/syscall.go | Adds Lchtimes function for updating symlink timestamps without following |
| internal/testutil/symlinktargetchecker.go | Provides test utilities for verifying symlink targets |
dmitry-lyfar
approved these changes
Oct 21, 2025
dmitry-lyfar
approved these changes
Oct 21, 2025
Adds checks for base and architecture that non-Store SDKs were previously able to bypass. Checks the SDK name earlier as well.
The current Store has a couple of issues: - Only supports MD5 hashes - Only stores one revision at a time For now, we'll use MD5 for Store SDKs but continue using SHA3 for other SDKs, in line with the Snap Store. Since the SDK we download may have been updated after the initial query, we also compute the hash during the download. We still need *a* hash to plan a launch or refresh, but once we've used it to decide to download a new SDK the original value can be discarded.
The goal is to hash sketch and in-project SDK contents, for caching purposes. We can also use it to compare the source files (e.g. from the project directory) to the committed SDK revisions. Since we ignore unusual files (anything that's not a regular file, directory or symlink), and only preserve data + permissions, we reuse git's metadata format, which consists of a "blob <length>\0" prefix for files and symlinks, and a sequence of "<mode> <filename>\0<hash>", prefixed by "tree <length>\0", for directories. We only match git in simple cases, because it uses SHA1 (which we'd rather avoid) and only supports 644 and 755 permissions.
f7a2e54 to
6a298a1
Compare
TICS Quality Gate✔️ PassedworkshopAll conditions passedSee the results in the TICS Viewer The following files have been checked for this project
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
We already hash SDKs published using
sdkcraft try. This brings the other types of SDKs in line with that, with a view towards caching SDK snapshots across multiple workshops.For Store SDKs, the GCS server only supports MD5 hashes and there's no easy way to download a specific SDK revision. Until we switch to the actual Store, SDKs will have either an MD5 or SHA3 hash. The hash is recomputed when downloading the SDK, since it might have changed since the initial query. Both the hash and SDK YAML are cached alongside the download, similar to try SDKs.
I added a validation step for all SDKs, which happens just before planning a launch or refresh. It checks that every SDK in the workshop has a hash and a valid
sdk.yaml. Previouslysdk.yamlwas only parsed this early for Store SDKs. If the downloaded SDK differs from the plan, we validate the new version before installing it in the workshop.For local SDKs, on launch/refresh the SDK files are copied to a temporary directory, to make them immutable. Instead of comparing this directory with others, we now compute a hash of the contents. The temporary directory is renamed to the hex digest (unless it already exists). If needed, a revision number is allocated, as a symlink (e.g.
x42 -> abcdef1234567890). Otherwise the timestamp of the revision is bumped, using a new functionLchtimesto avoid following the link.I fixed a minor bug in the previous local SDK logic: if a user deletes a file within an SDK just before it's copied to the temporary directory, Workshop now ignores the file instead of raising an error.
The hash of a directory is recursive. It accounts for filenames, contents, permissions and doesn't follow symlinks. The exact format is based on
git:blob <file size>\0<file contents>.blob <target length in bytes>\0<link target>.tree <entries length>\0<entries>, whereentriesis a sequence of items like<file mode> <file name>\0<hash>.Self-review quick check
Docs
Or: