Skip to content

Commit

Permalink
feat: create the RuntimeMetadata and Repository structs. Refactor Run…
Browse files Browse the repository at this point in the history
…times (#72)

* feat: create the RuntimeMetadata and Repository structs. Refactor Runtimes

* feat: merge metadata files into RemoteFile. Add tests
  • Loading branch information
Angelmmiguel authored Jan 24, 2023
1 parent 67ac7f0 commit d59d0f9
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 9 deletions.
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"))
}
}

#[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" } }

0 comments on commit d59d0f9

Please sign in to comment.