Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create the RuntimeMetadata and Repository structs. Refactor Runtimes #72

Merged
merged 4 commits into from
Jan 24, 2023
Merged
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 src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern crate lazy_static;
mod config;
mod data;
mod router;
mod runtimes;
mod workers;

use actix_files::{Files, NamedFile};
Expand Down
85 changes: 85 additions & 0 deletions src/runtimes/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

use super::{remote_file::RemoteFile, runtime::RuntimeStatus};
use anyhow::{anyhow, Result};
use serde::Deserialize;
use std::collections::HashMap;

// TODO: Remove it when implementing the manager
#[allow(dead_code)]
/// Metadata associated to a Runtime. It contains information
/// about a certain runtime like name, version and all the
/// details to run workers with it.
///
/// A runtime is a Wasm binary + configuration that can run
/// a source code as a worker. The configuration includes
/// different pieces like polyfills files, templates,
/// arguments, etc.
#[derive(Deserialize)]
pub struct RuntimeMetadata<'a> {
/// Name of the runtime (like ruby, python, etc)
name: &'a str,
/// Specific version of the runtime
version: &'a str,
/// Current status in the repository
status: RuntimeStatus,
/// Associated extensions
extensions: Vec<&'a str>,
/// Arguments to pass to the Wasm module via WASI
args: Vec<&'a str>,
/// A list of environment variables that must be configured
/// for the runtime to work.
envs: Option<HashMap<&'a str, &'a str>>,
/// The reference to a remote binary (url + checksum)
binary: RemoteFile<'a>,
/// The reference to a remote polyfill file (url + checksum)
polyfill: Option<RemoteFile<'a>>,
/// The refernmece to a template file for the worker. It will wrap the
/// source code into a template that can include imports,
/// function calls, etc.
template: Option<RemoteFile<'a>>,
}

// TODO: Remove it when implementing the manager
#[allow(dead_code)]
impl<'a> RuntimeMetadata<'a> {
/// Reads and parses the metadata from a slice of bytes. It will return
/// a result as the deserialization may fail.
pub fn from_slice(data: &'a [u8]) -> Result<Self> {
toml::from_slice::<RuntimeMetadata>(data)
.map_err(|_| anyhow!("wws could not deserialize the runtime metadata"))
}
Angelmmiguel marked this conversation as resolved.
Show resolved Hide resolved
}

#[cfg(test)]
mod tests {
use crate::runtimes::remote_file::Checksum;

use super::*;
use std::{any::Any, fs};

#[test]
fn parse_runtime_toml() {
let contents = fs::read("tests/data/metadata/runtime.toml").unwrap();
let metadata = RuntimeMetadata::from_slice(&contents).unwrap();

assert_eq!(metadata.name, "ruby");
assert_eq!(metadata.version, "3.2.0+20230118-8aec06d");
assert_eq!(metadata.status.type_id(), RuntimeStatus::Active.type_id());
assert_eq!(metadata.binary.url, "https://github.com/vmware-labs/webassembly-language-runtimes/releases/download/ruby%2F3.2.0%2B20230118-8aec06d/ruby-3.2.0.wasm");

let Checksum::Sha256 { value } = metadata.binary.checksum;
assert_eq!(
value,
"e2d91cff05ec59ed9c88aadbd3b477842092054bf24c5d944d5ad6dbafdd3b32"
);

// Optionals
let polyfill = metadata.polyfill.unwrap();
assert_eq!(
polyfill.url,
"https://raw.githubusercontent.com/Angelmmiguel/wws-index-test/main/ruby/poly.rb"
);
}
}
8 changes: 8 additions & 0 deletions src/runtimes/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

mod metadata;
mod modules;
mod remote_file;
mod repository;
pub mod runtime;
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use super::data::Data;
use crate::workers::runtime::Runtime;
use crate::runtimes::runtime::Runtime;
use anyhow::Result;
use std::{fs, path::PathBuf};
use wasmtime_wasi::Dir;
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::workers::runtime::Runtime;
use crate::runtimes::runtime::Runtime;
use anyhow::Result;
use std::{fs, path::PathBuf};

Expand Down
24 changes: 24 additions & 0 deletions src/runtimes/remote_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use serde::Deserialize;

/// A file represents a combination of both a remote URL and
/// a checksum. It will provide utils to download and validate
/// the file.
///
/// If the checksum is not present, the validation will return
/// always an Ok result.
///
#[derive(Deserialize)]
pub struct RemoteFile<'a> {
/// URL pointing to the file
pub url: &'a str,
/// Checksum to validate the given file
pub checksum: Checksum<'a>,
}

/// A list of available checksums. For now,
/// we will support only sha256
#[derive(Deserialize)]
#[serde(rename_all = "lowercase", tag = "type")]
pub enum Checksum<'a> {
Sha256 { value: &'a str },
}
49 changes: 49 additions & 0 deletions src/runtimes/repository.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

use super::metadata::RuntimeMetadata;
use anyhow::{anyhow, Result};
use serde::Deserialize;

// TODO: Remove it when implementing the manager
#[allow(dead_code)]
/// A Repository contains the list of runtimes available on it.
/// This file is used by wws to properly show the list of available
/// repos and install them.
///
/// By default, this repository class rely on the [WebAssembly Language Runtimes](https://github.com/vmware-labs/webassembly-language-runtimes)
/// repository. It looks for a repository.toml file in the Git repo.
#[derive(Deserialize)]
pub struct Repository<'a> {
/// Version of the repository file
pub version: u32,
/// The list of runtimes available in the repository
#[serde(borrow)]
pub runtimes: Vec<RuntimeMetadata<'a>>,
}

// TODO: Remove it when implementing the manager
#[allow(dead_code)]
impl<'a> Repository<'a> {
/// Reads and parses the metadata from a slice of bytes. It will return
/// a result as the deserialization may fail.
pub fn from_slice(data: &'a [u8]) -> Result<Self> {
toml::from_slice::<Repository>(data)
.map_err(|_| anyhow!("wws could not deserialize the repository metadata"))
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::fs;

#[test]
fn parse_index_toml() {
let contents = fs::read("tests/data/metadata/repository.toml").unwrap();
let repo = Repository::from_slice(&contents).unwrap();

assert_eq!(repo.version, 1);
assert_eq!(repo.runtimes.len(), 1);
}
}
26 changes: 25 additions & 1 deletion src/workers/runtime.rs → src/runtimes/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

use super::runtimes::{javascript::JavaScriptRuntime, native::NativeRuntime};
use super::modules::{javascript::JavaScriptRuntime, native::NativeRuntime};
use anyhow::{anyhow, Result};
use serde::Deserialize;
use std::path::Path;
use wasmtime_wasi::WasiCtxBuilder;

/// Define the status of a runtime in a target repository
#[derive(Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RuntimeStatus {
Active,
Yanked,
Deprecated,
Unknown,
}

impl From<&str> for RuntimeStatus {
/// Create a RuntimeStatus variant from a &str. It uses predefined
/// values
fn from(value: &str) -> Self {
match value {
"active" => RuntimeStatus::Active,
"yanked" => RuntimeStatus::Yanked,
"deprecated" => RuntimeStatus::Deprecated,
_ => RuntimeStatus::Unknown,
}
}
}

/// Define the behavior a Runtime must have. This includes methods
/// to initialize the environment for the given runtime as well as
/// the Wasi Context to process the request.
Expand Down
2 changes: 0 additions & 2 deletions src/workers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

mod runtime;
mod runtimes;
pub mod wasm_io;
mod worker;

Expand Down
6 changes: 2 additions & 4 deletions src/workers/worker.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// Copyright 2022 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

use super::{
runtime::{init_runtime, Runtime},
wasm_io::{WasmInput, WasmOutput},
};
use super::wasm_io::{WasmInput, WasmOutput};
use crate::runtimes::runtime::{init_runtime, Runtime};
use actix_web::HttpRequest;
use anyhow::Result;
use std::{collections::HashMap, path::Path};
Expand Down
11 changes: 11 additions & 0 deletions tests/data/metadata/repository.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version = 1

[[runtimes]]
name = "ruby"
version = "3.2.0+20230118-8aec06d"
status = "active"
args = [ "--", "/src/index.rb" ]
binary = { url = "https://github.com/vmware-labs/webassembly-language-runtimes/releases/download/ruby%2F3.2.0%2B20230118-8aec06d/ruby-3.2.0.wasm", checksum = { type = "sha256", value = "e2d91cff05ec59ed9c88aadbd3b477842092054bf24c5d944d5ad6dbafdd3b32" } }
extensions = [ "rb" ]
polyfill = { url = "https://raw.githubusercontent.com/Angelmmiguel/wws-index-test/main/ruby/poly.rb", checksum = { type = "sha256", value = "2ba09117ed20a05480615b2aaaf6c7cd7f61fa06f4919777d773df2fcbc736cf" } }
template = { url = "https://raw.githubusercontent.com/Angelmmiguel/wws-index-test/main/ruby/template.txt", checksum = { type = "sha256", value = "6d808b4747cf30f82665a38a47e1176513bbdd6ad558c09db03d719e33ad2da0" } }
8 changes: 8 additions & 0 deletions tests/data/metadata/runtime.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name = "ruby"
version = "3.2.0+20230118-8aec06d"
status = "active"
args = [ "--", "/src/index.rb" ]
binary = { url = "https://github.com/vmware-labs/webassembly-language-runtimes/releases/download/ruby%2F3.2.0%2B20230118-8aec06d/ruby-3.2.0.wasm", checksum = { type = "sha256", value = "e2d91cff05ec59ed9c88aadbd3b477842092054bf24c5d944d5ad6dbafdd3b32" } }
extensions = [ "rb" ]
polyfill = { url = "https://raw.githubusercontent.com/Angelmmiguel/wws-index-test/main/ruby/poly.rb", checksum = { type = "sha256", value = "2ba09117ed20a05480615b2aaaf6c7cd7f61fa06f4919777d773df2fcbc736cf" } }
template = { url = "https://raw.githubusercontent.com/Angelmmiguel/wws-index-test/main/ruby/template.txt", checksum = { type = "sha256", value = "6d808b4747cf30f82665a38a47e1176513bbdd6ad558c09db03d719e33ad2da0" } }