Skip to content
This repository was archived by the owner on Aug 27, 2024. It is now read-only.

feat(latest-rust-std): add example #53

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
- fibonacci-rust
- fibonacci-zig
- http-rust-tokio
- latest-rust-std

runs-on: ubuntu-20.04
steps:
Expand Down
5 changes: 5 additions & 0 deletions Rust/std-latest/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
target = "wasm32-wasi"

[target.wasm32-wasi]
runner = ["enarx", "run", "--wasmcfgfile", "Enarx.toml"]
53 changes: 53 additions & 0 deletions Rust/std-latest/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Rust/std-latest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
15 changes: 15 additions & 0 deletions Rust/std-latest/Enarx.toml
Original file line number Diff line number Diff line change
@@ -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"
84 changes: 84 additions & 0 deletions Rust/std-latest/src/main.rs
Original file line number Diff line number Diff line change
@@ -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"),
}
}
57 changes: 32 additions & 25 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
];

Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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;
Expand All @@ -310,47 +325,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 {
Expand Down