From 2b7a23780d8a6d3fe5eaa2b649e518c377beafeb Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 2 Sep 2022 09:47:42 +0200 Subject: [PATCH 1/2] build(nix): add Rust to default shell Signed-off-by: Roman Volosatovs --- flake.nix | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/flake.nix b/flake.nix index 048a4dc..2cf5e04 100644 --- a/flake.nix +++ b/flake.nix @@ -62,8 +62,8 @@ codex = final: prev: let rust = with fenix.packages.${final.system}; combine [ - stable.rustc stable.cargo + stable.rustc targets.wasm32-wasi.stable.rust-std ]; @@ -310,47 +310,39 @@ ; }; - devShells = + devShells = let + rust = with pkgs.fenix; + combine [ + stable.cargo + stable.clippy + stable.rustc + stable.rustfmt + targets.wasm32-wasi.stable.rust-std + ]; + in { default = pkgs.mkShell { buildInputs = [ enarx.packages.${system}.enarx-static + + rust ]; }; - rust = devShells.default.overrideAttrs (attrs: let - rust = with pkgs.fenix; - combine [ - stable.rustc - stable.cargo - targets.wasm32-wasi.stable.rust-std - ]; - in { - buildInputs = - attrs.buildInputs - ++ [ - rust - ]; + rust = devShells.default.overrideAttrs (attrs: { + buildInputs = attrs.buildInputs ++ [rust]; }); } // pkgs.lib.optionalAttrs (!pkgs.tinygo.meta.broken) { # NOTE: TinyGo is broken on some platforms, only add Go shell on platforms where it works go = devShells.default.overrideAttrs (attrs: { - buildInputs = - attrs.buildInputs - ++ [ - pkgs.tinygo - ]; + buildInputs = attrs.buildInputs ++ [pkgs.tinygo]; }); } // pkgs.lib.optionalAttrs (!pkgs.zig.meta.broken) { # NOTE: Zig is broken on some platforms, only add Zig shell on platforms where it works zig = devShells.default.overrideAttrs (attrs: { - buildInputs = - attrs.buildInputs - ++ [ - pkgs.zig - ]; + buildInputs = attrs.buildInputs ++ [pkgs.zig]; }); }; in { From 15e9dcc9aa1406bcbc56aa97639d54b21d80f30c Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 23 Aug 2022 14:12:05 +0200 Subject: [PATCH 2/2] feat(latest-rust-std): add example Signed-off-by: Roman Volosatovs --- .github/workflows/build.yml | 1 + Rust/std-latest/.cargo/config | 5 +++ Rust/std-latest/Cargo.lock | 53 ++++++++++++++++++++++ Rust/std-latest/Cargo.toml | 9 ++++ Rust/std-latest/Enarx.toml | 15 +++++++ Rust/std-latest/src/main.rs | 84 +++++++++++++++++++++++++++++++++++ flake.nix | 15 +++++++ 7 files changed, 182 insertions(+) create mode 100644 Rust/std-latest/.cargo/config create mode 100644 Rust/std-latest/Cargo.lock create mode 100644 Rust/std-latest/Cargo.toml create mode 100644 Rust/std-latest/Enarx.toml create mode 100644 Rust/std-latest/src/main.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c3fdf2..99c6695 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ jobs: - fibonacci-rust - fibonacci-zig - http-rust-tokio + - latest-rust-std runs-on: ubuntu-20.04 steps: diff --git a/Rust/std-latest/.cargo/config b/Rust/std-latest/.cargo/config new file mode 100644 index 0000000..b367d7a --- /dev/null +++ b/Rust/std-latest/.cargo/config @@ -0,0 +1,5 @@ +[build] +target = "wasm32-wasi" + +[target.wasm32-wasi] +runner = ["enarx", "run", "--wasmcfgfile", "Enarx.toml"] diff --git a/Rust/std-latest/Cargo.lock b/Rust/std-latest/Cargo.lock new file mode 100644 index 0000000..cde5d99 --- /dev/null +++ b/Rust/std-latest/Cargo.lock @@ -0,0 +1,53 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9a8f622bcf6ff3df478e9deba3e03e4e04b300f8e6a139e192c05fa3490afc7" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "itoa" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "serde" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" + +[[package]] +name = "serde_json" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "std-latest" +version = "0.1.0" +dependencies = [ + "anyhow", + "httparse", + "serde_json", +] diff --git a/Rust/std-latest/Cargo.toml b/Rust/std-latest/Cargo.toml new file mode 100644 index 0000000..2c148bb --- /dev/null +++ b/Rust/std-latest/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "std-latest" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.57" +httparse = "1.8.0" +serde_json = "1.0.85" diff --git a/Rust/std-latest/Enarx.toml b/Rust/std-latest/Enarx.toml new file mode 100644 index 0000000..422f1e6 --- /dev/null +++ b/Rust/std-latest/Enarx.toml @@ -0,0 +1,15 @@ +[[files]] +kind = "stdin" + +[[files]] +kind = "stdout" + +[[files]] +kind = "stderr" + +[[files]] +name = "api.github.com" +kind = "connect" +prot = "tls" +port = 443 +host = "api.github.com" diff --git a/Rust/std-latest/src/main.rs b/Rust/std-latest/src/main.rs new file mode 100644 index 0000000..a42b0e8 --- /dev/null +++ b/Rust/std-latest/src/main.rs @@ -0,0 +1,84 @@ +use std::io::{Read, Write}; +use std::net::TcpStream; +#[cfg(unix)] +use std::os::unix::io::{FromRawFd, RawFd}; +#[cfg(target_os = "wasi")] +use std::os::wasi::io::{FromRawFd, RawFd}; +use std::str::FromStr; +use std::{env, io}; + +use anyhow::{bail, Context}; +use httparse::Status; + +fn main() -> anyhow::Result<()> { + let fd_count = env::var("FD_COUNT").context("failed to lookup `FD_COUNT`")?; + let fd_count = usize::from_str(&fd_count).context("failed to parse `FD_COUNT`")?; + assert_eq!( + fd_count, + 4, // STDIN, STDOUT, STDERR and the socket connected to the endpoint + "unexpected amount of file descriptors received" + ); + + let stream_fd: RawFd = env::var("FD_NAMES") + .context("failed to lookup `FD_NAMES`")? + .splitn(fd_count, ':') + .position(|name| name == "api.github.com") + .context("`api.github.com` socket not found")? + .try_into() + .unwrap(); // the value is at most 3 and therefore always fits into RawFd + let mut stream = unsafe { TcpStream::from_raw_fd(stream_fd) }; + + let req = vec![ + "GET /repos/enarx/enarx/releases?per_page=1 HTTP/1.0", + "Host: api.github.com", + "Accept: */*", + &format!( + "User-Agent: {}:{}", + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION") + ), + "\r\n", + ] + .join("\r\n"); + assert_eq!( + io::copy(&mut req.as_bytes(), &mut stream).context("failed to send request")?, + req.len() as u64 + ); + stream.flush().context("failed to flush stream")?; + + let mut buf = Vec::new(); + stream + .read_to_end(&mut buf) + .context("failed to read response")?; + + let mut headers = [httparse::EMPTY_HEADER; 64]; + let mut res = httparse::Response::new(&mut headers); + let n = match res.parse(&buf).context("failed to parse HTTP response")? { + Status::Complete(n) => n, + Status::Partial => bail!("partial response"), + }; + match res.code { + Some(200) => {} + Some(c) => bail!("unexpected response code {c}"), + None => bail!("unknown response code"), + } + + match serde_json::from_slice(&buf[n..]).context("failed to decode JSON")? { + serde_json::Value::Array(releases) => { + match releases.first().context("no releases available")? { + serde_json::Value::Object(release) => { + let name = release + .get("name") + .context("release name missing")? + .as_str() + .context("release name is not a string")?; + eprintln!("Latest https://github.com/enarx/enarx release is:"); + println!("{name}"); + Ok(()) + } + _ => bail!("release is not a JSON object"), + } + } + _ => bail!("response is not a JSON array"), + } +} diff --git a/flake.nix b/flake.nix index 2cf5e04..8fff884 100644 --- a/flake.nix +++ b/flake.nix @@ -221,6 +221,19 @@ wasm = "${final.http-rust-tokio-wasm}/bin/tokio-http.wasm"; conf = "${self}/Rust/tokio-http/Enarx.toml"; }; + + latest-rust-std-wasm = naersk-lib.buildPackage { + src = "${self}/Rust/std-latest"; + CARGO_BUILD_TARGET = "wasm32-wasi"; + }; + + latest-rust-std = buildEnarxPackage { + inherit (final) pkgs; + inherit (cargoPackage "${self}/Rust/std-latest/Cargo.toml") name version; + + wasm = "${final.latest-rust-std-wasm}/bin/std-latest.wasm"; + conf = "${self}/Rust/std-latest/Enarx.toml"; + }; }; credentialHelpers = final: prev: { @@ -290,6 +303,8 @@ fibonacci-rust-wasm http-rust-tokio http-rust-tokio-wasm + latest-rust-std + latest-rust-std-wasm ; cryptle-rust = cryptle-enarx;