Skip to content

Commit

Permalink
start on gh controllers; fixes #55
Browse files Browse the repository at this point in the history
  • Loading branch information
mmoskal committed Feb 10, 2024
1 parent 7a056e3 commit c8f214c
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 28 deletions.
89 changes: 62 additions & 27 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions aicirt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ cap = "0.1.2"
fxhash = "0.2.1"
bincode = "1.3.3"
uuid = "1.6.1"
regex = "1.10.3"
ureq = "2.9.5"

[target.'cfg(target_os = "linux")'.dependencies]
linux-futex = "0.2.0"
Expand Down
95 changes: 94 additions & 1 deletion aicirt/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ use base64::{self, Engine as _};
use clap::Parser;
use hex;
use hostimpl::GlobalInfo;
use regex::Regex;
use serde_json::{json, Value};
use sha2::{Digest, Sha256};
use std::{
fs,
ops::Sub,
path::PathBuf,
sync::{Arc, Mutex},
time::{Duration, Instant},
time::{Duration, Instant, SystemTime},
};
use worker::{RtPostPreProcessArg, SeqWorkerHandle};

Expand Down Expand Up @@ -154,6 +156,12 @@ struct Stepper {
pre_recv_timer: TimerRef,
}

fn hex_hash_string(s: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(s);
hex::encode(hasher.finalize())
}

impl ModuleRegistry {
pub fn new(wasm_ctx: WasmContext, shm: Shm) -> Result<Self> {
let forker = WorkerForker::new(wasm_ctx.clone(), shm);
Expand Down Expand Up @@ -193,6 +201,11 @@ impl ModuleRegistry {
self.cache_path.join(format!("{}.wasm", module_id))
}

fn url_path(&self, url: &str) -> PathBuf {
let hex = hex_hash_string(url);
self.cache_path.join(format!("url-{}.json", hex))
}

fn elf_path(&self, module_id: &str) -> PathBuf {
self.cache_path.join(format!("{}.elf", module_id))
}
Expand Down Expand Up @@ -384,6 +397,86 @@ impl ModuleRegistry {
Ok(json!(resp))
}

fn resolve_gh_module(&self, module_id: &str) -> Result<String> {
if !module_id.starts_with("gh:") {
return Ok(module_id.to_string());
}
ensure!(
Regex::new(r"^gh:[\./a-zA-Z0-9_-]+$")
.unwrap()
.is_match(module_id),
"invalid gh: module_id"
);
let mut parts = module_id[3..]
.split('/')
.map(|s| s.to_string())
.collect::<Vec<_>>();
ensure!(
2 <= parts.len() && parts.len() <= 4,
"invalid gh: module_id"
);
let mut ver = "latest".to_string();
let last_part = parts.last().unwrap();
let mut selector = "".to_string();
if parts.len() > 2
&& (last_part == "latest"
|| regex::Regex::new(r"^v\d+\.\d+")
.unwrap()
.is_match(last_part))
{
ver = format!("tags/{}", parts.pop().unwrap());
}
if parts.len() > 2 {
selector = parts.pop().unwrap();
}
ensure!(parts.len() == 2, "invalid gh: module_id");

let url = format!(
"https://api.github.com/repos/{}/{}/releases/{}",
parts[0], parts[1], ver
);
let cache_path = self.url_path(&url);
let meta = cache_path.metadata();
if !(meta.is_ok()
&& meta.unwrap().modified()? > SystemTime::now().sub(Duration::from_secs(120)))
{
log::info!("fetching {}", url);
let resp = ureq::get(&url)
.set("User-Agent", "AICI")
.set("Accept", "application/vnd.github+json")
.set("X-GitHub-Api-Version", "2022-11-28")
.call()
.map_err(|e| anyhow!("gh: fetch failed: {}", e))?;
std::fs::write(cache_path.clone(), resp.into_string()?)?;
}
let json: serde_json::Value = serde_json::from_slice(&std::fs::read(cache_path)?)?;

let wasm_files = json["assets"]
.as_array()
.ok_or_else(|| anyhow!("no assets"))?
.iter()
.filter(|a| {
a["name"]
.as_str()
.map(|s| s.ends_with(".wasm") && s.contains(&selector))
.unwrap_or(false)
})
.collect::<Vec<_>>();

ensure!(wasm_files.len() > 0, "no wasm files found");
ensure!(wasm_files.len() == 1, "too many wasm files found");

let wasm_file = wasm_files[0];
let _upd = wasm_file["updated_at"]
.as_str()
.ok_or_else(|| anyhow!("no updated_at"))?;
let _wasm_url = wasm_file["browser_download_url"]
.as_str()
.ok_or_else(|| anyhow!("no browser_download_url"))?;

todo!()
}

fn instantiate(&mut self, mut req: InstantiateReq) -> Result<Value> {
if valid_tagname(&req.module_id) {
let taginfo = self.read_tag(&req.module_id)?;
Expand Down

0 comments on commit c8f214c

Please sign in to comment.