
vpod v0.8.1
अविश्वसनीय प्रक्रियाओं के लिए हल्के, सुरक्षित Linux सैंडबॉक्स। ब्राउज़र और सर्वर पर चलता है।
Vpod
vpod क्या है?
vpod एक हल्का, पोर्टेबल सैंडबॉक्स है जो एक अविश्वसनीय प्रक्रिया को तुरंत Linux वातावरण प्रदान करता है। यह RISC‑V आर्किटेक्चर का उपयोग करता है और पूरी तरह से WebAssembly के अंदर चलता है।
- तेज़ स्टार्टअप: एक सेकंड से भी कम समय में बूट होता है।
- पोर्टेबल: बिना किसी सेटअप के कहीं भी चलता है।
- पृथक: सभी निष्पादन स्थिति WASM सैंडबॉक्स के अंदर रहती है।
यह कैसे काम करता है
एक vpod WebAssembly में संकलित एक पूर्ण RISC‑V सिस्टम (RV64GC, सिंगल vCPU) चलाता है। इसके अंदर एक वास्तविक Linux कर्नेल वास्तविक यूज़रस्पेस के साथ बूट होता है, इसलिए शेल, टूल्स और डेमॉन सभी वास्तविक हार्डवेयर की तरह व्यवहार करते हैं।
स्नैपशॉट। शुरू से Linux बूट करने के बजाय, एक vpod स्नैपशॉट को पुनर्स्थापित करता है: एक सहेजी गई मशीन स्थिति (CPU रजिस्टर, RAM, फ़ाइल सिस्टम) जो बूट के तुरंत बाद कैप्चर की गई होती है। इसे पुनर्स्थापित करने में एक सेकंड से भी कम समय लगता है। सस्पेंड उल्टे क्रम में उसी तरह काम करता है, केवल गंदे मेमोरी पेज डिस्क पर वापस लिखे जाते हैं, इसलिए आप एक सैंडबॉक्स को रोक सकते हैं और बाद में उसे फिर से शुरू कर सकते हैं, यहाँ तक कि किसी अन्य प्रक्रिया से भी।
अग्रिम-समय अनुवाद। शुद्ध निर्देश-दर-निर्देश एमुलेशन धीमा है, और WebAssembly रनटाइम JIT को असंभव बना देता है। इसलिए स्नैपशॉट निर्माण समय पर, सबसे अधिक उपयोग होने वाले गेस्ट कोड पथ RISC‑V से नेटिव कोड में अनुवादित किए जाते हैं जो स्वयं WASM मॉड्यूल में संकलित होते हैं। रनटाइम पर एमुलेटर इन अनुवादित ब्लॉकों में डिस्पैच करता है जब गेस्ट कोड मेल खाता है, और जब नहीं मेल खाता तो इंटरप्रेटर पर वापस आ जाता है। यह CPU-बाउंड कार्यों पर लगभग 5x का लाभ देता है, पृथक्करण पर शून्य प्रभाव के साथ: अनुवादित कोड उसी MMU और मेमोरी जाँच से गुजरता है जैसे इंटरप्रेटेड कोड।
WASI सीमा। WASM घटक होस्ट से केवल WASI 0.2 के माध्यम से संवाद करता है। गेस्ट कभी भी होस्ट फ़ाइल डिस्क्रिप्टर, सॉकेट या मेमोरी नहीं देखता है: फ़ाइल सिस्टम एक्सेस स्पष्ट रूप से माउंट किए गए निर्देशिकाओं के माध्यम से होता है, और नेटवर्किंग घटक के अंदर एक यूज़र-मोड नेटवर्क स्टैक के माध्यम से होती है जो होस्ट से केवल साधारण आउटबाउंड सॉकेट माँगता है। बाकी सब कुछ (गेस्ट कर्नेल, प्रक्रियाएँ, मेमोरी) WASM लीनियर मेमोरी के अंदर रहता है और उसके साथ समाप्त हो जाता है।
RV64GC विनिर्देश
G (सामान्य-उद्देश्य एक्सटेंशन)
- I: आधार 64-बिट पूर्णांक निर्देश सेट।
- M: हार्डवेयर गुणा और भाग, हैशिंग और क्रिप्टोग्राफी के लिए उपयोगी।
- A: थ्रेड-सुरक्षित प्रोग्रामों के लिए परमाणु संचालन।
- F/D: सिंगल और डबल-परिशुद्धता फ्लोटिंग-पॉइंट, वैज्ञानिक कंप्यूटिंग और ML इन्फ़रेंस के लिए उपयुक्त।
C (संपीड़ित निर्देश) कोड आकार को 30% तक कम करता है, निर्देश प्राप्ति गति और मेमोरी दक्षता में सुधार करता है। यह हमारे मेमोरी-सीमित WASM वातावरण में पूर्ण Linux यूज़रस्पेस चलाते समय महत्वपूर्ण है।
[!NOTE] V (वेक्टर) एक्सटेंशन लागू नहीं किया गया है। RVV निर्देश एमुलेटेड RISC-V के रूप में निष्पादित होंगे; होस्ट CPU के लिए कोई SIMD पासथ्रू नहीं है। V जोड़ने से वेक्टराइज़्ड वर्कलोड के लिए किसी भी प्रदर्शन लाभ के बिना एमुलेशन ओवरहेड बढ़ जाएगा।
आरंभ करें
TypeScript SDK
npm install @capsule-run/vpod
import { Sandbox } from "@capsule-run/vpod";
const sandbox = await Sandbox.create();
// कॉल के बीच स्थिति संरक्षित रहती है
await sandbox.commands.run("export API_KEY=secret");
const key = await sandbox.commands.run("echo $API_KEY");
console.log(key.stdout); // secret
// Python REPL — वेरिएबल बने रहते हैं
await sandbox.code.run("data = [1, 2, 3]");
const total = await sandbox.code.run("print(sum(data))");
console.log(total.text); // 6
await sandbox.close();
वही पैकेज ब्राउज़र टैब में चलता है, जहाँ स्नैपशॉट डिस्क के बजाय ऑरिजिन-प्राइवेट स्टोरेज में कैश किया जाता है।
[!IMPORTANT]
Sandbox.create()का पहला कॉल डिफ़ॉल्ट स्नैपशॉट (alpine) डाउनलोड करता है और यदि पहले से मौजूद नहीं है तो उसे स्थानीय रूप से कैश करता है।
Python SDK
pip install vpod
from vpod import Sandbox
# एक कमांड चलाएँ
sandbox = Sandbox.create()
result = sandbox.commands.run("whoami")
print(result.stdout) # root
sandbox.close()
# स्थायी सत्र — कॉल के बीच स्थिति संरक्षित
with Sandbox.create() as sandbox:
sandbox.commands.run("export API_KEY=secret")
result = sandbox.commands.run("echo $API_KEY")
print(result.stdout) # secret
# Python REPL — वेरिएबल बने रहते हैं
with Sandbox.create() as sandbox:
sandbox.code.run("import requests")
sandbox.code.run("data = [1, 2, 3]")
result = sandbox.code.run("print(sum(data))")
print(result.text) # 6
CLI
curl -fsSL https://install.vpod.sh | sh
या PowerShell के माध्यम से इंस्टॉल करें (windows)
irm https://install.vpod.sh | iex
# एक स्नैपशॉट खींचें
vpod pull alpine:latest
# एक इंटरैक्टिव शेल शुरू करें
vpod
दस्तावेज़ीकरण
Vpod दस्तावेज़ीकरण पर जाएँ।
सीमाएँ
- एमुलेशन ओवरहेड: WebAssembly के अंदर कोई हार्डवेयर वर्चुअलाइज़ेशन नहीं है, इसलिए सभी गेस्ट कोड एमुलेटेड होते हैं। ओवरहेड पूरी तरह से वर्कलोड पर निर्भर करता है: I/O-बाउंड और नेटवर्क-बाउंड कार्य नेटिव गति के करीब चलते हैं, जबकि भारी CPU-बाउंड कार्य AOT अनुवाद के साथ भी काफी धीमे चलते हैं। यदि आपका वर्कलोड अधिकतर "एक टूल चलाएँ, एक फ़ाइल पढ़ें, एक API कॉल करें" है, तो आपको अंतर महसूस नहीं होगा।
- कोई GPU एक्सेस नहीं: CUDA, Metal और हार्डवेयर ML एक्सेलेरेटर उपलब्ध नहीं हैं। भविष्य में wasi-nn के साथ समर्थन जोड़ा जा सकता है।
योगदान
बग रिपोर्ट से लेकर नए डिवाइस समर्थन तक, योगदान का स्वागत है। कुछ भी महत्वपूर्ण बनाने से पहले चर्चा करने के लिए एक issue खोलें।
पूर्वापेक्षाएँ
- Rust (नवीनतम स्थिर)
wasm32-wasip2टारगेट के साथ:rustup target add wasm32-wasip2 - Python 3.10+ Python SDK के लिए
- Node 20+ TypeScript SDK के लिए
- Zig (0.16) और bsdtar, केवल तभी आवश्यक हैं जब आप स्वयं स्नैपशॉट बनाते हैं
विकास सेटअप
# एक बार: AOT स्टब उत्पन्न करें (एक नए क्लोन में कोई अनुवादित ब्लॉक नहीं होते)
./scripts/aot-stub.sh
# WASM घटक बनाएँ (लाइब्रेरी + CLI)। दोनों टियर को sdks/python/vpod/ में कॉपी करता है
./scripts/build-wasm.sh
# होस्ट CLI इंस्टॉल करें
cargo install --path crates/vpod
# Python SDK को डेव मोड में इंस्टॉल करें
pip install -e "sdks/python[dev]"
# TypeScript SDK बनाएँ। घटक को Python SDK निर्देशिका से उठाता है
cd sdks/typescript && npm install && npm run build
npm run build डिफ़ॉल्ट रूप से --tier aot का उपयोग करता है; CI --tier base पिन करता है। बिल्ड crates/ के अंतर्गत नवीनतम फ़ाइल से पुराने घटक को अस्वीकार कर देता है, इसलिए एमुलेटर को छूने के बाद ./scripts/build-wasm.sh को फिर से चलाएँ। एमुलेटर परिवर्तन केवल गेस्ट के माध्यम से सतह पर आता है, इसलिए एक पुराना घटक संकलित होता है और लगभग सब कुछ पास करता है।
परीक्षण चलाना
CI हर PR पर इन्हें चलाता है, इसलिए पुश करने से पहले इन्हें चलाएँ:
cargo fmt --all -- --check # फ़ॉर्मेटिंग
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all # Rust परीक्षण
# Python SDK एकीकरण परीक्षण (WASM लाइब्रेरी की आवश्यकता है)
cp target/wasm32-wasip2/release/vpod_wasi_lib.wasm sdks/python/vpod/
pytest sdks/python/tests/ -v -m integration
# TypeScript SDK (sdks/typescript से)
npm run typecheck
npm test # यूनिट
npm run test:all # यूनिट + एकीकरण, स्थानीय स्नैपशॉट की आवश्यकता है
npm run test:perf # गेस्ट-टाइम रिग्रेशन, सटीक स्थिरांक
TypeScript परीक्षण निर्मित dist/ को आयात करते हैं, src/ को नहीं, इसलिए चलाने से पहले बिल्ड करें। वे साझा कैश निर्देशिका में एक स्नैपशॉट खोजते हैं; VPOD_TEST_SNAPSHOT=/path/to/x.snap उन्हें कहीं और इंगित करता है।
ब्राउज़र को एंड-टू-एंड परीक्षण करने के लिए, npm run dev COOP/COEP चालू के साथ पेज परोसता है और node dev/run-network.mjs --browser chrome इसे हेडलेस चलाता है।
स्थानीय रूप से निर्मित स्नैपशॉट का उपयोग करना
SDK डिफ़ॉल्ट रूप से registry.vpod.sh से खींचते हैं। स्वयं निर्मित स्नैपशॉट चलाने के लिए, रजिस्ट्री नाम के बजाय सीधे उसे सौंपें:
// TypeScript: डिस्क पर एक फ़ाइल (Node), या बाइट्स (कहीं भी)
await Sandbox.create({ snapshot: { path: "./dist/alpine-3.23.0-256mb.snap" } });
await Sandbox.create({ snapshot: { bytes, name: "alpine-3.23.0-256mb.snap" } });
# Python: VPOD_SNAPSHOT=/path/to/x.snap
किसी भी तरह से फ़ाइल नाम में RAM आकार रखें, क्योंकि एमुलेटर इसे वहाँ से पढ़ता है।
स्नैपशॉट बनाना
प्रोजेक्ट registry.vpod.sh से पूर्व-निर्मित Alpine स्नैपशॉट का उपयोग करता है, इसलिए आपको सामान्यतः इसकी आवश्यकता नहीं होती। स्थानीय रूप से एक बनाने के लिए:
./scripts/build-default-snapshot.sh # dist/alpine-3.23.0-256mb.snap
./scripts/build-data-snapshot.sh # numpy/pandas/scipy के साथ 512 MB वैरिएंट
[!TIP] CLI में स्थानीय रूप से निर्मित स्नैपशॉट का उपयोग करने के लिए,
crates/vpod/src/main.rsमेंresolve_snapshot()में पंक्तियों को अनकमेंट करें।
स्नैपशॉट बिल्ड AOT पास (scripts/aot-snapshot.sh <snapshot>) भी चला सकते हैं, जो एक प्रतिनिधि वर्कलोड को ट्रेस करता है, हॉट ब्लॉक का अनुवाद करता है, और उनके साथ एमुलेटर को फिर से बनाता है। इसमें समय लगता है; aot-stub.sh से स्टब रोज़मर्रा के विकास के लिए पर्याप्त है, सब कुछ समान काम करता है, बस धीमा।
Dockerfile से (macOS और Linux)
कस्टम स्नैपशॉट Dockerfile से भी बनाए जा सकते हैं। बिल्डर macOS पर Apple के container CLI और Linux पर Docker Buildx का उपयोग करता है। एक नए macOS इंस्टॉल को एक बार अपना रनटाइम कॉन्फ़िगर करने की आवश्यकता होती है, अन्यथा बिल्ड एक बिल्डर की प्रतीक्षा करता है जो कभी शुरू नहीं होता:
container system kernel set --recommended
container builder start
Linux पर, Buildx प्लगइन के साथ Docker इंस्टॉल करें और riscv64 एमुलेशन एक बार पंजीकृत करें यदि होस्ट क्रॉस-प्लेटफ़ॉर्म बिल्ड के लिए पहले से कॉन्फ़िगर नहीं है:
docker run --privileged --rm tonistiigi/binfmt --install riscv64
./scripts/build-custom-snapshot.sh -f Dockerfile -n my-image # dist/my-image-256mb.snap
# वैकल्पिक रूप से: --aot --trace-cmd '<छवि का हॉट कमांड>' AOT ब्लॉक बेक करने के लिए
Dockerfile linux/riscv64 के लिए बनाया गया है (BuildKit RUN चरणों को एमुलेशन के तहत निष्पादित करता है), इसकी फ्लैट की गई rootfs Alpine minirootfs को प्रतिस्थापित करती है, और बाकी पाइपलाइन समान है: vpod ओवरले, बूट, --snapshot-save।
निर्यात से केवल फ़ाइल सिस्टम बचता है। छवि कॉन्फ़िगरेशन से ENV, CMD और ENTRYPOINT हटा दिए जाते हैं, इसलिए पर्यावरण को RUN चरण में /etc/profile.d/ के माध्यम से बनाए रखें। Python वार्म-स्टार्ट स्वचालित रूप से musl-आधारित छवियों के लिए लागू होता है जो /usr/bin या /bin में python3 भेजती हैं।
पुल रिक्वेस्ट
- PR को केंद्रित रखें: प्रति PR एक परिवर्तन।
fmt,clippyऔर परीक्षण सूट पास होने चाहिए (CI तीनों को लागू करता है)।- यदि आप एमुलेटर के निष्पादन या मेमोरी पथ को छूते हैं, तो बताएँ कि आपने शुद्धता को कैसे मान्य किया (कम से कम परीक्षण सूट; सूक्ष्म परिवर्तनों के लिए गेस्ट में एक बूट और एक वास्तविक वर्कलोड एक अच्छी सैनिटी जाँच है)।
लाइसेंस
यह प्रोजेक्ट Apache License 2.0 के तहत लाइसेंस प्राप्त है। विवरण के लिए LICENSE फ़ाइल देखें।