Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+220
View File
@@ -0,0 +1,220 @@
//! 只在测试自己的目录中,用 dev Pod 已安装的绝对路径 Go 工具制作签名 fixture。
use super::*;
use ring::signature::{Ed25519KeyPair, KeyPair};
use std::{
fs,
os::unix::fs::{DirBuilderExt, PermissionsExt},
path::{Path, PathBuf},
process::Command,
};
pub struct Fixture {
pub root: PathBuf,
pub signed: SignedResources,
pub files: BTreeMap<String, Vec<u8>>,
pub descriptor: serde_json::Value,
}
pub fn write(root: &Path, path: &str, bytes: impl AsRef<[u8]>) {
let path = root.join(path);
fs::create_dir_all(path.parent().unwrap()).unwrap();
for directory in path
.parent()
.unwrap()
.ancestors()
.take_while(|path| path.starts_with(root))
{
fs::set_permissions(directory, fs::Permissions::from_mode(0o700)).unwrap();
}
fs::write(&path, bytes).unwrap();
fs::set_permissions(path, fs::Permissions::from_mode(0o600)).unwrap();
}
fn go(root: &Path, arguments: &[&str]) -> String {
let result = Command::new("/usr/local/go/bin/go")
.args(arguments)
.current_dir(root)
.env_clear()
.env("GOTOOLCHAIN", "local")
.env("GOPROXY", "off")
.env("GOSUMDB", "off")
.env("CGO_ENABLED", "0")
.env("GO111MODULE", "off")
.env("GOCACHE", root.join("go-cache"))
.output()
.unwrap();
assert!(
result.status.success(),
"{}",
String::from_utf8_lossy(&result.stderr)
);
String::from_utf8(result.stdout).unwrap()
}
impl Fixture {
pub fn new() -> Self {
let root = std::env::temp_dir().join(format!(
"dever-go-acceptance-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
fs::DirBuilder::new().mode(0o700).create(&root).unwrap();
let version = go(&root, &["version"]);
let target = BuildTarget::host().unwrap();
let arch = if target == BuildTarget::LinuxX86_64 {
"amd64"
} else {
"arm64"
};
let version_number = version
.split_whitespace()
.nth(2)
.unwrap()
.strip_prefix("go")
.unwrap();
write(&root, "selector.go", include_bytes!("selector.go"));
go(
&root,
&["build", "-trimpath", "-o", "selector", "selector.go"],
);
let mut files = BTreeMap::new();
files.insert(
"bin/analyze".into(),
fs::read(root.join("selector")).unwrap(),
);
for tool in ["compile", "link"] {
files.insert(
format!("bin/{tool}"),
fs::read(format!("/usr/local/go/pkg/tool/linux_{arch}/{tool}")).unwrap(),
);
}
let exports = go(
&root,
&[
"list",
"-deps",
"-export",
"-f",
"{{if .Export}}{{.ImportPath}}={{.Export}}{{end}}",
"bytes",
"context",
"encoding/binary",
"encoding/json",
"errors",
"fmt",
"io",
"math",
"os",
"regexp",
"sort",
"strconv",
"strings",
"time",
"unicode/utf8",
"embed",
],
);
let mut cfg = String::new();
for line in exports.lines().filter(|line| !line.is_empty()) {
let (name, source) = line.split_once('=').unwrap();
let path = format!("stdlib/{name}.a");
cfg.push_str(&format!("packagefile {name}={path}\n"));
files.insert(path, fs::read(source).unwrap());
}
files.insert("stdlib/importcfg".into(), cfg.into_bytes());
let descriptor = serde_json::json!({"host":target.name(), "compiler":"bin/compile", "linker":"bin/link", "analyzer":"bin/analyze",
"stdlib_importcfg":"stdlib/importcfg", "goos":"linux", "goarch":arch, "go_version":version.trim()});
files.insert("dever-runtime.json".into(), serde_json::to_vec(&serde_json::json!({"format":"dever-worker-runtime-v1", "ecosystem":"go", "target":target.name(),
"executable":null, "arguments":[], "build":descriptor, "python_markers":null, "python_wheel_tags":[]})).unwrap());
let archive = archive(&files);
let metadata = serde_json::to_vec(&serde_json::json!({"format":"dever-registry-runtime-v1", "runtime":{"pack":{"name":"go", "version":version_number,
"sha256":crate::compiler::project::dependency::digest(&archive)}, "target":target.name(), "python_markers":null, "python_wheel_tags":[]}})).unwrap();
let loader = if arch == "amd64" {
"ld-linux-x86-64.so.2"
} else {
"ld-linux-aarch64.so.1"
};
let loader_source = if arch == "amd64" {
"/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2"
} else {
"/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1"
};
let artifacts = BTreeMap::from([
(
format!("runtime/go/{}/runtime.pack", target.name()),
archive,
),
(
format!("runtime/go/{}/manifest.json", target.name()),
metadata,
),
(
format!("process-runtime/{}/lib/{loader}", target.name()),
fs::read(loader_source).unwrap(),
),
(
"sdk/go/component.go".into(),
fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("../sdk/go/component.go"))
.unwrap(),
),
]);
let signed = sign(&root.join("installation"), &artifacts);
Self {
root,
signed,
files,
descriptor,
}
}
}
pub fn archive(files: &BTreeMap<String, Vec<u8>>) -> Vec<u8> {
let gzip = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::fast());
let mut tar = tar::Builder::new(gzip);
for (name, bytes) in files {
let mut header = tar::Header::new_gnu();
header.set_size(bytes.len() as u64);
header.set_mode(0o644);
header.set_cksum();
tar.append_data(&mut header, name, bytes.as_slice())
.unwrap();
}
tar.into_inner().unwrap().finish().unwrap()
}
pub fn sign(root: &Path, artifacts: &BTreeMap<String, Vec<u8>>) -> SignedResources {
let key = Ed25519KeyPair::from_seed_unchecked(&[93; 32]).unwrap();
let hex = |bytes: &[u8]| {
bytes
.iter()
.map(|byte| format!("{byte:02x}"))
.collect::<String>()
};
write(
root,
"state/trusted-release-key",
hex(key.public_key().as_ref()),
);
let entries = artifacts.iter().map(|(path, bytes)| {
write(root, &format!("versions/0.0.1/{path}"), bytes);
serde_json::json!({"path":path, "bytes":bytes.len(), "sha256":crate::compiler::project::dependency::digest(bytes)})
}).collect::<Vec<_>>();
let manifest = serde_json::to_vec(&serde_json::json!({"format":"dever-release-v2", "version":"0.0.1", "platform":BuildTarget::host().unwrap().name(), "artifacts":entries, "extensions":[]})).unwrap();
write(root, "versions/0.0.1/manifest.json", &manifest);
write(
root,
"versions/0.0.1/manifest.sig",
hex(key.sign(&manifest).as_ref()),
);
SignedResources::load(root, "0.0.1").unwrap()
}
impl Drop for Fixture {
fn drop(&mut self) {
fs::remove_dir_all(&self.root).unwrap();
}
}