A content-addressable store for WASM modules
- Built-in WASM validation
- History management, branching and merging
- Command-line interface
- HTTP interface
- Simple authentication with roles based on HTTP request methods
- Optional SSL
- WebAssembly modules are identified by their
hashand are associated with apath, similar to a path on disk- Storing modules based on their hashes allows wasmstore to de-duplicate identical modules
- Paths make it possible to give modules custom names
- Any time the store is modified a
commitis created- Commits can be identified by a hash and represent a checkpoint of the store
- Contains some additional metadata: author, message and timestamp
- Every time an existing
pathis updated a newversionis created automaticallyrollbackreverts a path to the previous versionrestorereverts to any priorcommitversionslists the history for a path, including module hashses and commit hashes
- A
branchcan be helpful for testing, to update several paths at once or for namespacing- The
mainbranch is the default, but it's possible to create branches with any name snapshotgets the currentcommithashmergeis used to merge abranchinto another
- The
There is a Dockerfile at the root of the repository that can be used to build and run the wasmstore server:
$ docker build -t wasmstore .
$ docker run -it -p 6384:6384 wasmstore$ docker pull dylibso/wasmstore
$ docker run --rm -it -p 6384:6384 dylibso/wasmstoreThe wasmstore executable contains the command-line interface and the server, to build it you will need opam
installed.
$ opam install . --deps-only
$ dune build
$ dune exec ./bin/main.exe --helpwasmstore can also be built using opam-monorepo:
$ opam repository add dune-universe git+https://github.com/dune-universe/opam-overlays.git
$ opam install opam-monorepo
$ opam monorepo pull
$ dune build ./bin
$ dune exec ./bin/main.exe --helpOnce wasmstore has been built it can be installed with:
$ make PREFIX=/usr/local installThe server can be started using the wasmstore executable:
$ wasmstore serveror docker-compose:
$ docker-compose upAll endpoints except the /branch endpoints accept a header named Wasmstore-Branch
that will cause the call to modify the specified branch instead of the default
branch.
GET /api/v1/modules/*- Returns a JSON object mapping module paths to their hashes for the specified path
- Example:
curl http://127.0.0.1:6384/api/v1/modules
GET /api/v1/module/*- Get a single module by hash or path, the module hash will also be stored in
the
Wasmstore-Hashheader in the response. - Example:
curl http://127.0.0.1:6384/api/v1/module/mymodule.wasm
- Get a single module by hash or path, the module hash will also be stored in
the
HEAD /api/v1/module/*- Returns
200status code if the path exists, otherwise404
- Returns
POST /api/v1/module/*- Add a new module, the request body should contain the WASM module
- Example:
curl --data-binary @mymodule.wasm http://127.0.0.1:6384/api/v1/module/mymodule.wasm
DELETE /api/v1/module/*- Delete a module by hash or path
GET /api/v1/hash/*- Get the hash of the module stored at a specific path
POST /api/v1/hash/:hash/*- Set the path to point to the provided hash (the hash should already exist in the store)
PUT /api/v1/branch/:branch- Switch the default branch
POST /api/v1/branch/:branch- Create a new branch
DELETE /api/v1/branch/:branch- Delete a branch
GET /api/v1/branch- Return the name of the default branch
GET /api/v1/branches- Return a JSON array of active branch names
POST /api/v1/gc- Run garbage collection
POST /api/v1/merge/:branch- Merge the specified branch into the default branch
POST /api/v1/restore/:hash/*- Revert to the specified commit hash
- It's possible to revert the entire tree or a single path
POST /api/v1/rollback/*- Revert to the last commit
- This can also be used to revert the entire tree or a single path
GET /api/v1/snapshot- Returns the latest commit hash
GET /api/v1/commit/:hash- Returns a JSON object with information about a commit
GET /api/v1/versions/*- Returns an array of pairs (module hash, commit hash) of all previous modules stored at the provided path
GET /api/v1/version/:index/*- Returns a previous version of a module at the provided path
GET /api/v1/watch- A WebSocket endpoint that sends updates about changes to the store to the client
* /api/v1/auth- This endpoint can be used with any method to check capabilities for an authentication secret
There are existing clients for Rust, Javascript Python and Go
Using the wasmstore server --auth flag or the WASMSTORE_AUTH environment variable you can restrict certain authentication keys
to specific request methods:
$ wasmstore server --auth "MY_SECRET_KEY:GET,POST;MY_SECRET_READONLY_KEY:GET"
$ WASMSTORE_AUTH="MY_SECRET_KEY:GET,POST;MY_SECRET_READONLY_KEY:GET" wasmstore serverOn the client side you should supply the key using the Wasmstore-Auth header
See the output of wasmstore --help for a full list of commands
Add a file from disk
$ wasmstore add /path/to/myfile.wasmGet module using hash:
$ wasmstore find <MODULE HASH>Get module using path:
$ wasmstore find myfile.wasmCreate a new branch:
$ wasmstore branch my-branchAdd module to non-default branch
$ wasmstore add --branch my-branch /path/to/another-file.wasmMerge a branch into the main branch
$ wasmstore merge my-branchDelete a branch
$ wasmstore branch my-branch --deleteGet the current commit hash:
$ wasmstore snapshotRestore to a prior commit:
$ wasmstore restore <COMMIT HASH>Run garbage collection:
$ wasmstore gcExport the main branch to a directory on disk:
$ wasmstore export -o ./wasm-modulesBackup the entire database:
$ wasmstore backup backup.tar.gzTo create a new store from a backup:
$ mkdir $WASMSTORE_ROOT
$ cd $WASMSTORE_ROOT
$ tar xzf /path/to/backup.tar.gzWhen the gc is executed for a branch all prior commits are squashed into one
and all non-reachable objects are removed. For example, if an object is still
reachable from another branch it will not be deleted. Because of this, running
the garbage collector may purge prior commits, potentially causing restore
to fail.