Repository: thangchung/webassembly-tour
Branch: main
Commit: 1d198945e4b4
Files: 39
Total size: 34.8 MB
Directory structure:
gitextract_hv3_bjyn/
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .vscode/
│ ├── C4.code-snippets
│ └── settings.json
├── LICENSE
├── README.md
├── assets/
│ ├── wasm_tour.puml
│ └── wasm_tour.xmind
├── docker-compose.yml
├── krustlet/
│ ├── README.md
│ ├── bootstrap.sh
│ └── greet-wasmcloud.yaml
├── restclient.http
├── wagi/
│ ├── functions/
│ │ ├── .cargo/
│ │ │ └── config.toml
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── get-todos/
│ │ │ ├── Cargo.toml
│ │ │ └── src/
│ │ │ └── main.rs
│ │ ├── modules.toml
│ │ └── wagi
│ └── server/
│ ├── .gitignore
│ ├── .vscode/
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.json
│ ├── modules/
│ │ ├── fibonacci.wasm
│ │ └── get-todos.wasm
│ └── server.csproj
└── wasmcloud/
├── README.md
├── docker-compose.yml
├── mini-store/
│ ├── Cargo.toml
│ ├── justfile
│ ├── manifest.yaml
│ └── src/
│ └── lib.rs
└── tools/
├── pf.sh
└── wasm-to-oci
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*.rs]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
================================================
FILE: .gitattributes
================================================
* text=auto
*.sh linguist-language=rust
================================================
FILE: .gitignore
================================================
# Generated by Cargo
# will have compiled files and executables
/target/
**/*/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
**/*/krustlet-config
================================================
FILE: .vscode/C4.code-snippets
================================================
{
"C4_Include_Context": {
"scope": "plantuml",
"prefix": "Include C4 Context Diagram",
"body": [
"!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml"
],
"description": "Include C4 Context Diagram"
},
"C4_Include_Container": {
"scope": "plantuml",
"prefix": "Include C4 Container Diagram",
"body": [
"!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml"
],
"description": "Include C4 Container Diagram"
},
"C4_Include_Component": {
"scope": "plantuml",
"prefix": "Include C4 Component Diagram",
"body": [
"!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml"
],
"description": "Include C4 Component Diagram"
},
"C4_Include_Deployment": {
"scope": "plantuml",
"prefix": "Include C4 Deployment Diagram",
"body": [
"!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Deployment.puml"
],
"description": "Include C4 Deployment Diagram"
},
"C4_Include_Dynamic": {
"scope": "plantuml",
"prefix": "Include C4 Dynamic Diagram",
"body": [
"!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml"
],
"description": "Include C4 Dynamic Diagram"
},
"C4_Person": {
"scope": "plantuml",
"prefix": "Person",
"body": [
"Person(${1:alias}, \"${2:label}\")"
],
"description": "Add Person to C4 diagram"
},
"C4_Person_Descr": {
"scope": "plantuml",
"prefix": "Person with Description",
"body": [
"Person(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add Person with Description to C4 diagram"
},
"C4_Person_Ext": {
"scope": "plantuml",
"prefix": [
"External Person",
"Person (External)"
],
"body": [
"Person_Ext(${1:alias}, \"${2:label}\")"
],
"description": "Add External Person to C4 diagram"
},
"C4_Person_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Person with Description",
"Person (External) with Description"
],
"body": [
"Person_Ext(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add External Person with Description to C4 diagram"
},
"C4_Container": {
"scope": "plantuml",
"prefix": "Container",
"body": [
"Container(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add Container to C4 diagram"
},
"C4_Container_Descr": {
"scope": "plantuml",
"prefix": "Container with Description",
"body": [
"Container(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add Container with Description to C4 diagram"
},
"C4_Container_Ext": {
"scope": "plantuml",
"prefix": [
"External Container",
"Container (External)"
],
"body": [
"Container_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add External Container to C4 diagram"
},
"C4_Container_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Container with Description",
"Container (External) with Description"
],
"body": [
"Container_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add External Container with Description to C4 diagram"
},
"C4_ContainerDb": {
"scope": "plantuml",
"prefix": "Database Container",
"body": [
"ContainerDb(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add Database Container to C4 diagram"
},
"C4_ContainerDb_Descr": {
"scope": "plantuml",
"prefix": "Database Container with Description",
"body": [
"ContainerDb(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add Database Container with Description to C4 diagram"
},
"C4_ContainerDb_Ext": {
"scope": "plantuml",
"prefix": [
"External Database Container",
"Database Container (External)"
],
"body": [
"ContainerDb_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add External Database Container to C4 diagram"
},
"C4_ContainerDb_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Database Container with Description",
"Database Container (External) with Description"
],
"body": [
"ContainerDb_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add External Database Container with Description to C4 diagram"
},
"C4_ContainerQueue": {
"scope": "plantuml",
"prefix": "Queue Container",
"body": [
"ContainerQueue(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add Queue Container to C4 diagram"
},
"C4_ContainerQueue_Descr": {
"scope": "plantuml",
"prefix": "Queue Container with Description",
"body": [
"ContainerQueue(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add Queue Container with Description to C4 diagram"
},
"C4_ContainerQueue_Ext": {
"scope": "plantuml",
"prefix": [
"External Queue Container",
"Queue Container (External)"
],
"body": [
"ContainerQueue_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add External Queue Container to C4 diagram"
},
"C4_ContainerQueue_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Queue Container with Description",
"Queue Container (External) with Description"
],
"body": [
"ContainerQueue_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add ExternalQueue Container with Description to C4 diagram"
},
"C4_Container_Boundary": {
"scope": "plantuml",
"prefix": [
"Container Boundary",
"Boundary for Container"
],
"body": [
"Container_Boundary(${1:alias}, \"${2:label}\"){",
"\t$0",
"}"
],
"description": "Add a Container Boundary to C4 diagram"
},
"C4_Component": {
"scope": "plantuml",
"prefix": "Component",
"body": [
"Component(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add Component to C4 diagram"
},
"C4_Component_Descr": {
"scope": "plantuml",
"prefix": "Component with Description",
"body": [
"Component(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add Component with Description to C4 diagram"
},
"C4_Component_Ext": {
"scope": "plantuml",
"prefix": [
"External Component",
"Component (External)"
],
"body": [
"Component_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add External Component to C4 diagram"
},
"C4_Component_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Component with Description",
"Component (External) with Description"
],
"body": [
"Component_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add External Component with Description to C4 diagram"
},
"C4_ComponentDb": {
"scope": "plantuml",
"prefix": "Database Component",
"body": [
"ComponentDb(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add Database Component to C4 diagram"
},
"C4_ComponentDb_Descr": {
"scope": "plantuml",
"prefix": "Database Component with Description",
"body": [
"ComponentDb(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add Database Component with Description to C4 diagram"
},
"C4_ComponentDb_Ext": {
"scope": "plantuml",
"prefix": [
"External Database Component",
"Database Component (External)"
],
"body": [
"ComponentDb_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add External Database Component to C4 diagram"
},
"C4_ComponentDb_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Database Component with Description",
"Database Component (External) with Description"
],
"body": [
"ComponentDb_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add External Database Component with Description to C4 diagram"
},
"C4_ComponentQueue": {
"scope": "plantuml",
"prefix": "Queue Component",
"body": [
"ComponentQueue(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add Queue Component to C4 diagram"
},
"C4_ComponentQueue_Descr": {
"scope": "plantuml",
"prefix": "Queue Component with Description",
"body": [
"ComponentQueue(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add Queue Component with Description to C4 diagram"
},
"C4_ComponentQueue_Ext": {
"scope": "plantuml",
"prefix": [
"External Queue Component",
"Queue Component (External)"
],
"body": [
"ComponentQueue_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\")"
],
"description": "Add External Queue Component to C4 diagram"
},
"C4_ComponentQueue_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Queue Component with Description",
"Queue Component (External) with Description"
],
"body": [
"ComponentQueue_Ext(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")"
],
"description": "Add External Queue Component with Description to C4 diagram"
},
"C4_System": {
"scope": "plantuml",
"prefix": "System",
"body": [
"System(${1:alias}, \"${2:label}\")"
],
"description": "Add System to C4 diagram"
},
"C4_System_Descr": {
"scope": "plantuml",
"prefix": "System with Description",
"body": [
"System(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add System with Description to C4 diagram"
},
"C4_System_Ext": {
"scope": "plantuml",
"prefix": [
"External System",
"System (External)"
],
"body": [
"System_Ext(${1:alias}, \"${2:label}\")"
],
"description": "Add External System to C4 diagram"
},
"C4_System_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External System with Description",
"System (External) with Description"
],
"body": [
"System_Ext(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add External System with Description to C4 diagram"
},
"C4_SystemDb": {
"scope": "plantuml",
"prefix": "Database System",
"body": [
"SystemDb(${1:alias}, \"${2:label}\")"
],
"description": "Add Database System to C4 diagram"
},
"C4_SystemDb_Descr": {
"scope": "plantuml",
"prefix": "Database System with Description",
"body": [
"SystemDb(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add Database System with Description to C4 diagram"
},
"C4_SystemDb_Ext": {
"scope": "plantuml",
"prefix": [
"External Database System",
"Database System (External)"
],
"body": [
"SystemDb_Ext(${1:alias}, \"${2:label}\")"
],
"description": "Add External Database System to C4 diagram"
},
"C4_SystemDb_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Database System with Description",
"Database System (External) with Description"
],
"body": [
"SystemDb_Ext(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add External Database System with Description to C4 diagram"
},
"C4_SystemQueue": {
"scope": "plantuml",
"prefix": "Queue System",
"body": [
"SystemQueue(${1:alias}, \"${2:label}\")"
],
"description": "Add Queue System to C4 diagram"
},
"C4_SystemQueue_Descr": {
"scope": "plantuml",
"prefix": "Queue System with Description",
"body": [
"SystemQueue(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add Queue System with Description to C4 diagram"
},
"C4_SystemQueue_Ext": {
"scope": "plantuml",
"prefix": [
"External Queue System",
"Queue System (External)"
],
"body": [
"SystemQueue_Ext(${1:alias}, \"${2:label}\")"
],
"description": "Add External Queue System to C4 diagram"
},
"C4_SystemQueue_Ext_Descr": {
"scope": "plantuml",
"prefix": [
"External Queue System with Description",
"Queue System (External) with Description"
],
"body": [
"SystemQueue_Ext(${1:alias}, \"${2:label}\", \"${3:description}\")"
],
"description": "Add External Queue System with Description to C4 diagram"
},
"C4_System_Boundary": {
"scope": "plantuml",
"prefix": [
"System Boundary",
"Boundary for System"
],
"body": [
"System_Boundary(${1:alias}, \"${2:label}\"){",
"\t$0",
"}"
],
"description": "Add a System Boundary to C4 diagram"
},
"C4_Enterprise_Boundary": {
"scope": "plantuml",
"prefix": [
"Enterprise Boundary",
"Boundary for Enterprise"
],
"body": [
"Enterprise_Boundary(${1:alias}, \"${2:label}\"){",
"\t$0",
"}"
],
"description": "Add an Enterprise Boundary to C4 diagram"
},
"C4_Relationship": {
"scope": "plantuml",
"prefix": "Relationship",
"body": [
"Rel(${1:from_alias}, ${2:to_alias}, \"${3:label}\")"
],
"description": "Add unidirectional Relationship to C4 diagram"
},
"C4_Relationship_Techn": {
"scope": "plantuml",
"prefix": "Relationship with Technology",
"body": [
"Rel(${1:from_alias}, ${2:to_alias}, \"${3:label}\", \"${4:technology}\")"
],
"description": "Add unidirectional Relationship with Technology to C4 diagram"
},
"C4_Relationship_Bi": {
"scope": "plantuml",
"prefix": "Bidirectional Relationship",
"body": [
"BiRel(${1:from_alias}, ${2:to_alias}, \"${3:label}\")"
],
"description": "Add bidirectional Relationship to C4 diagram"
},
"C4_Relationship_Bi_Techn": {
"scope": "plantuml",
"prefix": "Bidirectional Relationship with Technology",
"body": [
"BiRel(${1:from_alias}, ${2:to_alias}, \"${3:label}\", \"${4:technology}\")"
],
"description": "Add bidirectional Relationship with Technology to C4 diagram"
},
"C4_Relationship_Index": {
"scope": "plantuml",
"prefix": "Relationship with Index",
"body": [
"RelIndex(${1:index}, ${2:from_alias}, ${3:to_alias}, \"${4:label}\")"
],
"description": "Add unidirectional Relationship to C4 Dynamic Diagram"
},
"C4_Relationship_Index_Techn": {
"scope": "plantuml",
"prefix": "Relationship with Technology and Index",
"body": [
"RelIndex(${1:index}, ${2:from_alias}, ${3:to_alias}, \"${4:label}\", \"${5:technology}\")"
],
"description": "Add unidirectional Relationship with Technology to C4 Dynamic Diagram"
},
"C4_Layout_Right": {
"scope": "plantuml",
"prefix": "Layout to Right side",
"body": [
"Lay_R(${1:from_alias}, ${2:to_alias})"
],
"description": "Add hidden layout line to put {to} to the right of {from}"
},
"C4_Layout_Left": {
"scope": "plantuml",
"prefix": "Layout to Left side",
"body": [
"Lay_L(${1:from_alias}, ${2:to_alias})"
],
"description": "Add hidden layout line to put {to} to the left of {from}"
},
"C4_Boundary": {
"scope": "plantuml",
"prefix": "Boundary",
"body": [
"Boundary(${1:alias}, \"${2:label}\"){",
"\t$0",
"}"
],
"description": "Add a generic boundary to C4 diagram."
},
"C4_Boundary_Type": {
"scope": "plantuml",
"prefix": [
"Boundary with type"
],
"body": [
"Boundary(${1:alias}, \"${2:label}\", \"${3:type}\"){",
"\t$0",
"}"
],
"description": "Add a generic boundary to C4 diagram."
},
"C4_Deployment_Node": {
"scope": "plantuml",
"prefix": "Deployment Node",
"body": [
"Deployment_Node(${1:alias}, \"${2:label}\"){",
"\t$0",
"}"
],
"description": "Add a deployment node to C4 diagram."
},
"C4_Deployment_Node_Type": {
"scope": "plantuml",
"prefix": [
"Deployment Node with type"
],
"body": [
"Deployment_Node(${1:alias}, \"${2:label}\", \"${3:type}\"){",
"\t$0",
"}"
],
"description": "Add a deployment node to C4 diagram."
},
"C4_Dynamic_Increment": {
"scope": "plantuml",
"prefix": [
"Increment index"
],
"body": [
"increment(${1:count})"
],
"description": "Increment index of C4 Dynamic Diagram."
},
"C4_Dynamic_Set_Index": {
"scope": "plantuml",
"prefix": [
"Set index"
],
"body": [
"setIndex(${1:value})"
],
"description": "Set index of C4 Dynamic Diagram"
},
"C4_Hide_Stereotype": {
"scope": "plantuml",
"prefix": [
"Hide stereotype",
"No stereotype"
],
"body": [
"HIDE_STEREOTYPE()"
],
"description": "Hide stereotypes from C4 diagram.."
},
"C4_Layout_With_Legend": {
"scope": "plantuml",
"prefix": [
"Layout with legend",
"Legend layout"
],
"body": [
"LAYOUT_WITH_LEGEND()"
],
"description": "Add legend to C4 diagram."
},
"C4_Layout_Left_Right": {
"scope": "plantuml",
"prefix": [
"Layout left to right",
"Left to right layout"
],
"body": [
"LAYOUT_LEFT_RIGHT()"
],
"description": "Left to right layout for C4 diagram."
},
"C4_Layout_Top_Down": {
"scope": "plantuml",
"prefix": [
"Layout top down",
"Top down layout"
],
"body": [
"LAYOUT_TOP_DOWN()"
],
"description": "Top down layout for C4 diagram."
},
"C4_Layout_As_Sketch": {
"scope": "plantuml",
"prefix": [
"Layout as sketch",
"Sketch layout"
],
"body": [
"LAYOUT_AS_SKETCH()"
],
"description": "Sketch layout for C4 diagram."
}
}
================================================
FILE: .vscode/settings.json
================================================
{
"plantuml.render": "PlantUMLServer",
"plantuml.server": "http://localhost:8080/"
}
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Thang Chung
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# WebAssembly Tour
WebAssembly on Rust is a bright future in making application runs at the Edge or on the Serverless technologies.
We spend a lot of time researching and doing a deep dive into it. We have documented it as the [`mindmap`](https://plantuml.com/mindmap-diagram) diagram so that it might help people like me to save time to search around the internet to find useful documents and tools to get started with WebAssembly on Rust.
## Give a Star! ⭐
If you like or are using this project to learn, please give a star. Thank you very much 👍
## The picture of webassembly serverless

Picture courtesy of [wasmCloud](https://wasmCloud.com) from Kubecon 2021 WasmDay [WebAssembly: The Future of Distributed Computing](https://www.youtube.com/watch?v=6UM64MbsHic) by Liam Randall.
## The full picture of WebAssembly ecosystem

## Export large PNG file with PlantUML
Make sure you install https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml and you have `docker` and `docker-compose` running on your local machine.
```bash
$ docker-compose up
```
Then set settings as following
```
"plantuml.server": "http://192.168.1.100:8080",
"plantuml.render": "PlantUMLServer",
```
Then right-click on the `assets/wasm-tour.puml`, then choose expose this current diagram.
# Diagrams
- https://plantuml.com/mindmap-diagram
- https://github.com/plantuml-stdlib/C4-PlantUML/blob/master/samples/C4CoreDiagrams.md
================================================
FILE: assets/wasm_tour.puml
================================================
@startmindmap wasm-tour
title WebAssembly Tour
caption Copyright by @thangchung \nhttps://github.com/thangchung/webassembly-tour
skinparam shadowing false
'skinparam handwritten true
skinparam BackgroundColor white
+ WASM \n(WebAssembly)
++ WebAssembly: it's neither web, not assembly - Ancient wasm dev proverb
++ Concepts
+++ Basic
++++ callstack is inaccessible
++++ pointers: compiled the offsets into linear memory (checked to ensure stating inbound), virtual address hides from application <>
++++ all control transfers: direct and indirect branches and calls (check to make sure not outbound) <>
++++ all interaction with outside world by imports and exports (no raw access) <>
++++ no undefined behavior
+++ Filesystem access
++++ WASI APIs for file system access
+++++ only access what we allow
+++++ share nothing linking and nano-processes (future)
+++ Terminal output
++++ ANSI-style escape sequences
+++ Spectre
++++ not implement yet, but it is a subject of on-going research
+++ https://docs.wasmtime.dev/security-sandboxing.html
++ ecosystem
+++ Cloudflare - worker (node Isolation)
++++ Build serverless code
+++++ https://github.com/cloudflare/wrangler
++++ https://blog.cloudflare.com/cloud-computing-without-containers
+++ WASI
++++ WebAssembly System Interface (has 2 benefits: portability and security)
++++ Not have a networking layer
++++ current WASM are single-thread and not support concurrency
++++ CGI: attach scripts to website, and provide the dynamic server-side logic. And now WASM + WASI are the same
+++++ https://datatracker.ietf.org/doc/html/rfc3875
++++ wasm32-wasi target
+++++ wasmtime
++++++ https://github.com/bytecodealliance/cargo-wasi
++++ wabt (convert wasm to wat, and vice versa)
+++++ https://github.com/WebAssembly/wabt
++++ https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
+++ wasmCloud
++++ High level concepts
+++++ Middle Level Runtime
++++++ waPC (WebAssembly Procedure Calls)
++++++ wascap (Sign, Embed, Query JWTs in WebAssembly Modules)
+++++ High Level Runtime
++++++ waSCC (WebAssembly Secure Capabilities Connector)
+++++++ services and functions as Actors <>
+++++++ Utilize embedded, signed JWTs (verify provenance, restrict access, integrate with OPA) <>
+++++++ Dynamically bind Actors to Capabilities such as Message Broker, HTTP client and server, Key-value Store, and Custom Capabilities <>
+++++++ Rust Host SDK
+++++++ Rust Actor SDK
++++ wasmcloud shell
+++++ wash CLI
++++++ start wash with `wash up`
++++++ sub-commands
+++++++ claims
++++++++ Generate JWTs for actors, capability providers, accounts and operators. Sign actor modules with claims including capability IDs, expiration, and keys to verify identity <>
++++++++ for examples
+++++++++ call `wash claims inspect wasmcloud.azurecr.io/echo:0.2.1` to inspect the echo actor <>
+++++++++ or sign claims for actor like `claims sign ./table_tennis.wasm --http_server --name "demo" --ver 0.1.0 --rev 0` <>
+++++++ ctl
++++++++ Interact directly with a wasmcloud control-interface, allowing you to imperatively schedule actors, providers and modify configurations of a wasmcloud host <>
++++++++ for examples
+++++++++ `ctl get hosts`
+++++++++ then based on the host id to call `ctl get inventory ` <>
+++++++++ or we can start actor like `ctl start actor table_tennis_s.wasm`(_s mean the wasm file we have already signed it with `claims` sub-command) <>
+++++++++ or we can start the provider too, like `ctl start provider wasmcloud.azurecr.io/httpserver:0.12.1` <>
+++++++++ or we can link actor with provider like `ctl link wasmcloud:httpserver PORT=8080`, then we can `curl localhost:8080 -d "ping"` <>
+++++++ drain
++++++++ Manage contents of the local wasmcloud cache <>
+++++++ keys
++++++++ Generate ed25519 keys for securely signing and identifying wasmcloud entities (actors, providers, hosts) <>
+++++++ par
++++++++ Create, modify and inspect provider archives, a TAR format that contains a signed JWT and OS/Architecture specific binaries for native capability providers <>
+++++++ reg
++++++++ Push and Pull actors and capability providers to/from OCI compliant registries (registry with ORAS standard) <>
++++ Develop app
+++++ manifest.yaml
++++++ declare: name, labels, actors to run, capabilities (image_ref and link_name), links between actor and host also with port (actor, provider_id, contract_id, link_name, values) <>
+++++ More steps to run please see `wasmcloud/ministore/README.md`in this repository <>
+++ WAGI (DeisLabs - Azure)
++++ WebAssembly Gateway Interface<>
++++ Http Server: dynamically load and execute WASM modules using the same CGI technic <>
++++ Headers in env variables, Query params sends in command line options, Incoming HTTP payloads via STDIN, and Response via STDOUT <>
++++ Security in mind: explicit access grants, cannot make outbound network connections, cannot execute others executes on the system, and cannot access arbitrary env variables <>
++++ It works on wasm32-wasi target only. If you want to install it, \nPlease follow command: rustup target add wasm32-wasi <>
++++ There is a version that is written in Rust at the https://github.com/deislabs/wagi <>
++++ DeisLabs is working to bring up .NET Core WAGI at https://github.com/deislabs/wagi-dotnet <>
++++ See more examples at this reposioty in https://github.com/thangchung/webassembly-tour/tree/main/wagi <>
++++ Networking API in WASI is not stable, and WASI socket is still in proposal stage
+++++ wasi-experimental-http is to temporary to solve this problem (will not need when WASI networking API and socket is released and stabled) <>
+++++ The DeisLabs build some of samples using wasi-experimental-http and Azure Rust SDKs (customized to work with WASI) at https://github.com/deislabs/wagi-azure-samples <>
+++ krustlet
++++ [TODO]
++++ https://github.com/deislabs/krustlet
+++ wasmer
++++ WebAssembly Runtime supporting WASI and Emscripten
++++ [TODO]
++++ https://github.com/wasmerio/wasmer
+++ secondstate
++++ [TODO]
++++ https://www.secondstate.io/
+++ suborbital
++++ [TODO]
++++ https://github.com/suborbital/atmo
+++ lucet
++++ Sandboxing WebAssembly Compiler
++++ [TODO]
++++ https://github.com/bytecodealliance/lucet
+++ wapm
++++ [TODO]
+++ wasi-nn
++++ [TODO]
+++ webassembly-dwarf
++++ [TODO]
++++ https://yurydelendik.github.io/webassembly-dwarf/
+++ AssemblyLift
++++ A framework for building serverless applications powered by WebAssembly (AWS) <>
++++ [TODO]
++++ https://github.com/akkoro/assemblylift
+++ WebContainer (StackBlitz)
++++ [TODO]
++++ https://github.com/stackblitz/webcontainer-core
+++ Other tools
++++ https://github.com/engineerd/wasm-to-oci
++++ https://github.com/appcypher/awesome-wasm-runtimes
++++ https://github.com/grain-lang/grain
++ programming languages \n(LLVM family)
+++ Rust
+++ C/C++
+++ AssemblyScript (subset of Typescript)
+++ TinyGo
+++ swiftwasm
+++ pyodide (python)
@endmindmap
================================================
FILE: docker-compose.yml
================================================
version: "3.3"
services:
plantuml-server:
image: "plantuml/plantuml-server:jetty"
container_name: plantuml-server
environment:
PLANTUML_LIMIT_SIZE: 24384
ports:
- 8080:8080
================================================
FILE: krustlet/README.md
================================================
# Step by step to get starting `krustlet` with microk8s
- `cd` into the krustlet folder (the folder contains this README.md file)
```bash
$ vi /var/snap/microk8s/current/args/kube-apiserver
# add --enable-bootstrap-token-auth into this file
$ systemctl restart snap.microk8s.daemon-apiserver
```
- Remove everything if there are existing them
```bash
$ rm -rf ~/.krustlet/
$ rm -rf ${PWD}/krustlet-config # make sure we don't have krustlet-config file in this current folder
$ k delete csr rust-tour-tls # rust-tour is a machine name
$ k delete csr krustlet
```
- Start to run krustlet
```bash
# Download bootstrap.sh from krustlet repo, and change kubectl to microk8s.kubectl in the content of this file
$ sudo chmod +x bootstrap.sh
$ ./bootstrap.sh
$ export KUBECONFIG=${PWD}/krustlet-config
$ KUBECONFIG=${PWD}/krustlet-config krustlet-wasi --node-ip=127.0.0.1 --node-name=krustlet --bootstrap-file=${HOME}/.krustlet/config/bootstrap.conf # make sure don't Ctrl + C in this command
# open another terminal
$ k certificate approve rust-tour-tls # rust-tour is machine name
```
- Run application
```bash
$ k apply --filename=https://raw.githubusercontent.com/deislabs/krustlet/master/demos/wasi/hello-world-rust/k8s.yaml
$ k logs pod/hello-world-wasi-rust
# you shoud see the logs there
```
More information, you could have a reference at https://github.com/deislabs/krustlet/blob/main/docs/howto/krustlet-on-microk8s.md
================================================
FILE: krustlet/bootstrap.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
token_id="$(/dev/null ||
date -v+1H -u "+%Y-%m-%dT%H:%M:%SZ" 2>/dev/null ||
date -u "+%Y-%m-%dT%H:%M:%SZ" -D "%s" -d "$(( `date +%s`+3600 ))")
cat <"${KUBECONFIG_FILE}.full.tmp"
# Switch working context to correct context
microk8s.kubectl --kubeconfig "${KUBECONFIG_FILE}.full.tmp" config use-context "${CONTEXT}"
# Minify
microk8s.kubectl --kubeconfig "${KUBECONFIG_FILE}.full.tmp" \
config view --flatten --minify >"${KUBECONFIG_FILE}.tmp"
# Rename context
microk8s.kubectl config --kubeconfig "${KUBECONFIG_FILE}.tmp" \
rename-context "${CONTEXT}" "${NEW_CONTEXT}"
# Create token user
microk8s.kubectl config --kubeconfig "${KUBECONFIG_FILE}.tmp" \
set-credentials "${TOKEN_USER}" --token "${TOKEN}"
# Set context to use token user
microk8s.kubectl config --kubeconfig "${KUBECONFIG_FILE}.tmp" \
set-context "${NEW_CONTEXT}" --user "${TOKEN_USER}"
# Set context to correct namespace
microk8s.kubectl config --kubeconfig "${KUBECONFIG_FILE}.tmp" \
set-context "${NEW_CONTEXT}" --namespace "${NAMESPACE}"
# Flatten/minify kubeconfig
microk8s.kubectl config --kubeconfig "${KUBECONFIG_FILE}.tmp" \
view --flatten --minify >"${KUBECONFIG_FILE}"
================================================
FILE: krustlet/greet-wasmcloud.yaml
================================================
apiVersion: v1
kind: Pod
metadata:
name: greet
labels:
app: greet
spec:
containers:
- image: ghcr.io/thangchung/ministore:0.1.0
imagePullPolicy: Always
name: greet
ports:
- containerPort: 8080
hostPort: 8080
nodeSelector:
kubernetes.io/arch: wasm32-wasi
tolerations:
- key: "node.kubernetes.io/network-unavailable"
operator: "Exists"
effect: "NoSchedule"
- key: "kubernetes.io/arch"
operator: "Equal"
value: "wasm32-wasi"
effect: "NoExecute"
- key: "kubernetes.io/arch"
operator: "Equal"
value: "wasm32-wasi"
effect: "NoSchedule"
================================================
FILE: restclient.http
================================================
@host = http://localhost:8080
###
@a = 5
@b = 5
GET {{host}}/add?{{a}},{{b}} HTTP/1.1
content-type: application/json
================================================
FILE: wagi/functions/.cargo/config.toml
================================================
[alias]
build-wasm = "build --target wasm32-wasi"
build-native = "build"
================================================
FILE: wagi/functions/Cargo.toml
================================================
[workspace]
members = [
"get-todos"
]
================================================
FILE: wagi/functions/README.md
================================================
# Get starting with wagi
- Build
```bash
$ rustup target add wasm32-wasi
$ cargo build-wasm
```
- Run
```
$ ./wagi --config modules.toml
```
- Test
```
# test it
$ curl -v http://localhost:3000/get-todos
```
Environment:
- Ubuntu 20.04.2 LTS
- rustc 1.52.1 (9bc8c42bb 2021-05-09)
- cargo 1.52.0 (69767412a 2021-04-21)
Happy hacking!
================================================
FILE: wagi/functions/get-todos/Cargo.toml
================================================
[package]
name = "get-todos"
version = "0.1.0"
authors = ["thangchung "]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1.0.126", features = ["derive"] }
serde_json = "1.0.64"
================================================
FILE: wagi/functions/get-todos/src/main.rs
================================================
use serde::Serialize;
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct Todo {
id: i32,
name: String,
is_completed: bool,
}
fn main() {
println!("Content-Type: text/plain\n");
let todos = vec![
Todo {
id: 1,
name: String::from("todo 1"),
is_completed: false,
},
Todo {
id: 2,
name: String::from("todo 2"),
is_completed: true,
},
];
println!("{}", serde_json::to_string_pretty(&todos).unwrap());
}
================================================
FILE: wagi/functions/modules.toml
================================================
default_host = "localhost:3000"
[[module]]
route = "/get-todos"
module = "target/wasm32-wasi/debug/get-todos.wasm"
================================================
FILE: wagi/functions/wagi
================================================
[File too large to display: 24.1 MB]
================================================
FILE: wagi/server/.gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*[.json, .xml, .info]
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# Ionide - VsCode extension for F# Support
.ionide/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
copy_wasm.*
================================================
FILE: wagi/server/.vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/net5.0/server.dll",
"args": [ ],
"cwd": "${workspaceFolder}",
"console": "internalConsole",
"env":{
"WASMTIME_BACKTRACE_DETAILS":"1",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
},
{
"name": ".NET Core Launch (listen)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"env":{
"WASMTIME_BACKTRACE_DETAILS":"1",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"program": "${workspaceFolder}/bin/Debug/net5.0/server.dll",
"args": [],
"cwd": "${workspaceFolder}",
"console": "internalConsole",
"stopAtEntry": false
}
]
}
================================================
FILE: wagi/server/.vscode/tasks.json
================================================
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
================================================
FILE: wagi/server/Program.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace server
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
}
================================================
FILE: wagi/server/Properties/launchSettings.json
================================================
{
"profiles": {
"server": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"WASMTIME_BACKTRACE_DETAILS":1
}
}
}
}
================================================
FILE: wagi/server/Startup.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Deislabs.WAGI.Extensions;
namespace server
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// This adds any wagi endpoints in configuration as RouteEndpoints to the IEndpointRouteBuilder
// by default it looks for its configuration in a section named WASM
endpoints.MapWASMModules();
});
}
}
}
================================================
FILE: wagi/server/appsettings.json
================================================
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Deislabs.WAGI": "Trace"
}
},
"AllowedHosts": "*",
"WASM": {
"ModulePath": "modules",
"Modules": {
"/fibonacci": {
"FileName": "fibonacci.wasm",
"Entrypoint": "_start",
"Environment" :{
},
"Volumes" : {
},
"HttpMethod": "GET"
},
"/todos": {
"FileName": "get-todos.wasm",
"Entrypoint": "_start",
"Environment" :{
},
"Volumes" : {
},
"HttpMethod": "GET"
}
}
}
}
================================================
FILE: wagi/server/server.csproj
================================================
net5.0
PreserveNewest
PreserveNewest
================================================
FILE: wasmcloud/README.md
================================================
# Installation
Install on Windows Sub-system
```bash
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ curl -s https://packagecloud.io/install/repositories/wasmcloud/core/script.deb.sh | sudo bash
$ sudo apt install wasmcloud wash
$ curl https://wasmtime.dev/install.sh -sSf | bash
```
# Build
## Step by step to run mini_store
```bash
$ rustup target add wasm32-unknown-unknown
$ cargo build --target wasm32-unknown-unknown --release
$ wash claims sign target/wasm32-unknown-unknown/release/mini_store.wasm --http_server --name "ministore" --ver 0.1.0 --rev 0
$ wash claims inspect target/wasm32-unknown-unknown/release/mini_store_s.wasm
```
Make sure you run `docker-compose up` to start the `registry`, `redis`, and `nats` before execute the following command
```bash
$ wash reg push localhost:5000/ministore:0.1.0 target/wasm32-unknown-unknown/release/mini_store_s.wasm --insecure
```
Create [`manifest.yaml`](mini-store/manifest.yaml) with content as below
```yaml
labels:
actor: "ministore"
actors:
- "localhost:5000/ministore:0.1.0"
capabilities:
- image_ref: wasmcloud.azurecr.io/httpserver:0.12.1
link_name: default
links:
- actor: ${CLIENT_ACTOR:}
provider_id: "VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4AYJ5RKAX2UNSCAPHA5M"
contract_id: "wasmcloud:httpserver"
link_name: default
values:
PORT: 8080
```
Then
```bash
$ wasmcloud --allowed-insecure localhost:8080 -m manifest.yaml
```
Finally, you can run
```bash
$ curl localhost:8080/add?5,5 --output -
```
> On the Ubuntu VM, you need to forward port of the docker-machine guest machine into the host machine as below
```bash
# pf.sh in the tools folder, and its repo is at https://github.com/johanhaleby/docker-machine-port-forwarder
$ ./pf.sh 5000 && ./pf.sh 6379 && ./pf.sh 4222 & ./pf.sh 6222 &7 ./pf.sh 8222
```
> Push WebAssembly file with signed to Github package
```bash
# before do this, we need to login into Github package so plz follow the link https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-docker-registry
# wasm-to-oci is at https://github.com/engineerd/wasm-to-oci
$ wasm-to-oci push ../mini-store/target/wasm32-unknown-unknown/release/mini_store_s.wasm ghcr.io/thangchung/ministore:0.1.0
```
## Run with wasmtime
> it might not run well
```bash
$ rustup target add wasm32-wasi
$ cargo build --target wasm32-wasi --release
$ wasmtime target/wasm32-wasi/release/mini_store.wasm
```
================================================
FILE: wasmcloud/docker-compose.yml
================================================
version: "3"
services:
registry:
image: registry:2
ports:
- "5000:5000"
nats:
image: nats:2.1.9
ports:
- "6222:6222"
- "4222:4222"
- "8222:8222"
redis:
image: redis:6.0.9
ports:
- "6379:6379"
================================================
FILE: wasmcloud/mini-store/Cargo.toml
================================================
[package]
name = "mini-store"
version = "0.1.0"
authors = ["thangchung@ymail.com"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
wapc-guest = "0.4.0"
wasmcloud-actor-core = { version = "0.2.2", features = ["guest"] }
wasmcloud-actor-http-server = {version = "0.1.0", features = ["guest"]}
[profile.release]
# Optimize for small code size
opt-level = "s"
lto = true
================================================
FILE: wasmcloud/mini-store/justfile
================================================
build:
cargo build
run:
cargo run --bin mini-store
================================================
FILE: wasmcloud/mini-store/manifest.yaml
================================================
labels:
actor: "ministore"
actors:
- "localhost:5000/ministore:0.1.0"
capabilities:
- image_ref: wasmcloud.azurecr.io/httpserver:0.12.1
link_name: default
links:
- actor: ${CLIENT_ACTOR:MDIN3A5WRXNBIKIVMTTRV6CH6I4UQXRW4H6YIINZ4TMYOETYF5TTMJ7Z}
provider_id: "VAG3QITQQ2ODAOWB5TTQSDJ53XK3SHBEIFNK4AYJ5RKAX2UNSCAPHA5M"
contract_id: "wasmcloud:httpserver"
link_name: default
values:
PORT: 8080
================================================
FILE: wasmcloud/mini-store/src/lib.rs
================================================
extern crate wapc_guest as guest;
extern crate wasmcloud_actor_http_server as httpserver;
use guest::prelude::*;
#[wasmcloud_actor_core::init]
fn init() {
httpserver::Handlers::register_handle_request(test_body);
}
fn test_body(msg: httpserver::Request) -> HandlerResult {
let nums: Vec<&str> = msg.query_string.split(",").collect();
let mut ret: String = String::from("Welcome to wasmcloud calculator");
loop {
match msg.path.as_str() {
"/add" => {
let sum = nums[0].parse::().unwrap() + nums[1].parse::().unwrap();
ret = format!("add: {} + {} = {}", nums[0], nums[1], sum);
break;
}
"/sub" => {
let sub = nums[0].parse::().unwrap() - nums[1].parse::().unwrap();
ret = format!("subtract: {} - {} = {}", nums[0], nums[1], sub);
break;
}
// TODO: add multiplication
"/div" => {
if nums[1] == "0" {
ret = String::from("Can not divide by zero!");
break;
}
let div = nums[0].parse::().unwrap() / nums[1].parse::().unwrap();
ret = format!("divide: {} / {} = {}", nums[0], nums[1], div);
break;
}
_ => {
break;
}
}
}
return Ok(httpserver::Response {
status_code: 200,
status: "OK".to_string(),
header: msg.header,
body: ret.as_bytes().to_vec(),
});
}
================================================
FILE: wasmcloud/tools/pf.sh
================================================
#!/bin/bash
readonly PROGNAME=$(basename $0)
port="${1}"
foreground="false"
stop="false"
environment="default"
quiet="false"
hostport="$1"
usage="${PROGNAME} [-h] [-s] [-f] [-e] [-hp] -- Forwards a docker-machine port so that you can access it locally
where:
-h, --help Show this help text
-s, --stop Stop the port forwarding process
-f, --foreground Run the docker-machine ssh client in foreground instead of background
-e, --environment The name of the docker-machine environment (default is default)
-q, --quiet Don't print anything to the console, not even errors
examples:
# Port forward port 8047 in docker-machine environment default
\$ ${PROGNAME} 8047
# Port forward docker port 8047 to host port 8087 in docker-machine environment default
\$ ${PROGNAME} 8087:8047
# Port forward port 8047 in docker-machine dev
\$ ${PROGNAME} 8047 -e dev
# Runs in foreground (port forwarding is automatically stopped when process is terminated)
\$ ${PROGNAME} 8047 -f
# Stop the port forwarding for this port
\$ ${PROGNAME} 8047 -s"
if [ $# -eq 0 ]; then
echo "$usage"
exit 1
fi
if [ -z "$1" ]; then
echo "You need to specify the port to forward" >&2
echo "$usage"
exit 1
fi
if [ "$#" -ne 0 ]; then
while [ "$#" -gt 0 ]
do
case "$1" in
-h|--help)
echo "$usage"
exit 0
;;
-f|--foreground)
foreground="true"
;;
-s|--stop)
stop="true"
;;
-e|--environment)
environment="$2"
;;
-q|--quiet)
quiet="true"
;;
--)
break
;;
-*)
echo "Invalid option '$1'. Use --help to see the valid options" >&2
exit 1
;;
# an option argument, continue
*) ;;
esac
shift
done
fi
pidport() {
lsof -n -i4TCP:$1 | grep --exclude-dir={.bzr,CVS,.git,.hg,.svn} LISTEN
}
# Check if port contains ":", if so we should split
if [[ $port == *":"* ]]; then
# Split by :
ports=(${port//:/ })
if [[ ${#ports[@]} != 2 ]]; then
if [[ $quiet == "false" ]]; then
echo "Port forwarding should be defined as hostport:targetport, for example: 8090:8080"
fi
exit 1
fi
hostport=${ports[0]}
port=${ports[1]}
fi
if [[ ${stop} == "true" ]]; then
result=`pidport $hostport`
if [ -z "${result}" ]; then
if [[ $quiet == "false" ]]; then
echo "Port $hostport is not forwarded, cannot stop"
fi
exit 1
fi
process=`echo "${result}" | awk '{ print $1 }'`
if [[ $process != "ssh" ]]; then
if [[ $quiet == "false" ]]; then
echo "Port $hostport is bound by process ${process} and not by docker-machine, won't stop"
fi
exit 1
fi
pid=`echo "${result}" | awk '{ print $2 }'` &&
kill $pid &&
echo "Stopped port forwarding for $hostport"
else
docker-machine ssh $environment `if [[ ${foreground} == "false" ]]; then echo "-f -N"; fi` -L $hostport:localhost:$port &&
if [[ $quiet == "false" ]] && [[ $foreground == "false" ]]; then
printf "Forwarding port $port"
if [[ $hostport -ne $port ]]; then
printf " to host port $hostport"
fi
echo " in docker-machine environment $environment."
fi
fi
================================================
FILE: wasmcloud/tools/wasm-to-oci
================================================
[File too large to display: 10.6 MB]