Giter Site home page Giter Site logo

fredldotme / container2wasm Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ktock/container2wasm

0.0 0.0 0.0 6.96 MB

Container to WASM converter

Home Page: https://ktock.github.io/container2wasm-demo/

License: Apache License 2.0

Shell 3.14% JavaScript 0.08% C++ 68.71% Perl 0.09% C 21.81% Go 0.37% Assembly 0.07% Rebol 1.96% AppleScript 0.02% Makefile 1.98% HTML 0.10% Yacc 0.28% Lex 0.10% M4 0.61% Dockerfile 0.15% Roff 0.38% ASL 0.15%

container2wasm's Introduction

[:arrow_down: Download] [:book: Command reference] [:books: Additional Documents] [:arrow_forward: Demo]

container2wasm: Container to WASM converter

container2wasm is a container-to-wasm image converter that enables to run the container on WASM.

  • Converts a container to WASM with emulation by Bochs (for x86_64 containers) and TinyEMU (for riscv64 containers).
  • Runs on WASI runtimes (e.g. wasmtime, wamr, wasmer, wasmedge, wazero)
  • Runs on browser
  • x86_64 or riscv64 containers are recommended. Other platforms (e.g. arm64) also work (but slow).

This is an experimental software.

Demo page of containers on browser (debian,python,node,vim): https://ktock.github.io/container2wasm-demo/

Examples

Container Image to WASM (WASI)

$ c2w ubuntu:22.04 out.wasm

The above command converts ubuntu:22.04 container image to WASI image (out.wasm).

NOTE1: For selecting the container image's architecture other than amd64, use --target-arch flag of c2w (e.g. c2w --target-arch=riscv64 riscv64/ubuntu:22.04 out.wasm).

NOTE2: x86_64 or riscv64 container is recommended. Other platform's containers should work but slow because of additional emulation.

The generated image runs on WASI runtimes:

$ wasmtime out.wasm uname -a
Linux localhost 6.1.0 #1 PREEMPT_DYNAMIC Mon Jun  5 11:57:09 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
$ wasmtime out.wasm ls /
bin   dev  home  lib32	libx32	mnt  proc  run	 srv  tmp  var
boot  etc  lib	 lib64	media	opt  root  sbin  sys  usr

NOTE: Directory mapping is available on non-x86_64 containers (TinyEMU-emulated ones) as of now. Other WASI features untested. Future version will support more WASI features.

Container on Browser

Container on browser

You can run the container on browser as well. There are two methods for running the container on browser.

NOTE: Please also refer to ./examples/wasi-browser (WASI-on-browser example) and ./examples/emscripten (emscripten example).

WASI on browser

This example converts the container to WASI and runs it on browser.

The following command generates a WASI image.

$ c2w ubuntu:22.04 /tmp/out-js2/htdocs/out.wasm

The following is an example of running the image on browser relying on xterm-pty and browser_wasi_shim. This example serves the image on localhost:8080 using apache http server.

$ cp -R ./examples/wasi-browser/* /tmp/out-js2/ && chmod 755 /tmp/out-js2/htdocs
$ docker run --rm -p 8080:80 \
         -v "/tmp/out-js2/htdocs:/usr/local/apache2/htdocs/:ro" \
         -v "/tmp/out-js2/xterm-pty.conf:/usr/local/apache2/conf/extra/xterm-pty.conf:ro" \
         --entrypoint=/bin/sh httpd -c 'echo "Include conf/extra/xterm-pty.conf" >> /usr/local/apache2/conf/httpd.conf && httpd-foreground'

You can run the container on browser via localhost:8080.

emscripten on browser

This example uses emscripten for converting the container to WASM.

  • pros: WASM image size can be smaller than WASI.
  • cons: WASI-specific optimization like Wizer pre-initialization isn't available for this mode. So the startup of the container can be slow (For x86_64 containers it might take >= 30s. For riscv64 containers it might take >= 10s).

The following command generates a WASM image and a JS file runnable on browser.

$ c2w --to-js ubuntu:22.04 /tmp/out-js/htdocs/

The following is an example of running the image on browser relying on xterm-pty. This example serves the image on localhost:8080 using apache http server.

$ cp -R ./examples/emscripten/* /tmp/out-js/ && chmod 755 /tmp/out-js/htdocs
$ docker run --rm -p 8080:80 \
         -v "/tmp/out-js/htdocs:/usr/local/apache2/htdocs/:ro" \
         -v "/tmp/out-js/xterm-pty.conf:/usr/local/apache2/conf/extra/xterm-pty.conf:ro" \
         --entrypoint=/bin/sh httpd -c 'echo "Include conf/extra/xterm-pty.conf" >> /usr/local/apache2/conf/httpd.conf && httpd-foreground'

You can run the container on browser via localhost:8080.

NOTE: It can take some time to load and start the container.

Getting Started

  • requirements
    • Docker 18.09+ (w/ DOCKER_BUILDKIT=1)
    • Docker Buildx v0.8+ (recommended) or docker build (w/ DOCKER_BUILDKIT=1)

You can install the converter command c2w using one of the following methods:

Release binary

Binaries are available from https://github.com/ktock/container2wasm/releases Extract the tarball and put the binary somewhere under $PATH.

Building binary using make

Go 1.19+ is needed.

make
sudo make install

Command reference

c2w

Converts a container image into a WASM image and writes it to the specified path (default: out.wasm at the current directory).

Usage: c2w [options] image-name [output file]

  • image-name: container image name (will be pulled from the registry if it doesn't exist in Docker)
  • [output file]: path to the result WASM file.

Sub commands

  • help, h: Shows a list of commands or help for one command

Options

  • --assets value: Custom location of build assets.
  • --dockerfile value: Custom location of Dockerfile (default: embedded to this command)
  • --builder value: Bulider command to use (default: "docker")
  • --target-arch value: target architecture of the source image to use (default: "amd64")
  • --build-arg value: Additional build arguments (please see Dockerfile for available build args)
  • --to-js: convert the container to WASM using emscripten
  • --debug-image: Enable debug print in the output image
  • --show-dockerfile: Show default Dockerfile
  • --legacy: Use "docker build" instead of buildx (no support for assets flag) (default:false)
  • --help, -h: show help
  • --version, -v: print the version

Run-time flags for WASM image

You can specify run-time flags to the generated wasm image for configuring the execution (e.g. for changing command to run in the container).

Usage: out.wasm [options] [COMMAND] [ARG...]

  • [COMMAND] [ARG...]: command to run in the container. (default: commands specified in the image config)

Options

  • -entrypoint <command> : entrypoint command. (default: entrypoint specified in the image config)
  • -no-stdin : disable stdin. (default: false)

Example:

The following changes the container's entrypoint to echo and pass hello to the arguments.

wasmtime -- /app/out.wasm --entrypoint=echo hello

Directory mapping

Directories mapped to the WASM program is accessible on the container as well.

$ mkdir -p /tmp/share/ && echo hi > /tmp/share/hi
$ wasmtime --mapdir /test/dir/share::/tmp/share /app/out.wasm ls /test/dir/share/
hi

NOTE: Directory mapping is available on non-x86_64 containers (TinyEMU-emulated) as of now. This should be available on all containers in the future.

Motivation

Though more and more programming languages start to support WASM, it's not easy to run the existing programs on WASM. This sometimes requires re-implementing and re-compiling them and costs extra time for development. This is a PoC converter tries to solve it by enabling running unmodified containers on WASM.

How does it work

contaienr2wasm creates a WASM image that runs the container and the Linux kernel on the emulated CPU.

The following shows the techniqual details:

  • Builder: BuildKit runs the conversion steps written in Dockerfile.
  • Emulator: Bochs emulates x86_64 CPU on WASM. TinyEMU emulates RISC-V CPU on WASM. They're compiled to WASM using wasi-sdk (for WASI and on-browser) and emscripten (for on-browser).
  • Guest OS: Linux runs on the emulated CPU. runc starts the container. Non-x86 and non-RISC-V containers runs with additional emulation by QEMU installed via tonistiigi/binfmt.
  • Directory Mapping: WASI filesystem API makes host directories visible to the emulator. TinyEMU mounts them to the guest linux via virtio-9p. Unsupported on Bochs (for x86_64 emulation) as of now.
  • Packaging: wasi-vfs (for WASI and on-browser) and emscripten (for on-browser) are used for packaging the dependencies. The kernel is pre-booted during the build using wizer to minimize the startup latency (for WASI only as of now).
  • Security: The converted container runs in the sandboxed WASM (WASI) VM with the limited access to the host system.

WASI Runtimes Integration Status

  • โœ”๏ธ : supported

  • ๐Ÿšง : WIP

  • NOTE: WASI features not listed here are untested (future version will support more features)

x86_64 containers

runtime stdio mapdir note
wasmtime โœ”๏ธ ๐Ÿšง
wamr(wasm-micro-runtime) โœ”๏ธ ๐Ÿšง
wazero โœ”๏ธ ๐Ÿšง
wasmer ๐Ÿšง (stdin unsupported) ๐Ÿšง non-blocking stdin doesn't seem to work
wasmedge ๐Ÿšง (stdin unsupported) ๐Ÿšง non-blocking stdin doesn't seem to work

risc-v and other architecutre's containers

runtime stdio mapdir note
wasmtime โœ”๏ธ โœ”๏ธ
wamr(wasm-micro-runtime) โœ”๏ธ โœ”๏ธ
wazero โœ”๏ธ โœ”๏ธ
wasmer ๐Ÿšง (stdin unsupported) โœ”๏ธ non-blocking stdin doesn't seem to work
wasmedge ๐Ÿšง (stdin unsupported) โœ”๏ธ non-blocking stdin doesn't seem to work

Example of mapdir with wasmtime:

$ mkdir -p /tmp/share/ && echo hi > /tmp/share/hi
$ wasmtime --mapdir /test/dir/share::/tmp/share -- out.wasm --entrypoint=cat -- /test/dir/share/hi
hi

Similar projects

There are several container runtimes support running WASM applications, but they don't run containers on WASM.

There are emulators that support running linux on WASM, but they don't support WASI.

Some WASM API specs provides applications access to the host system. Re-compilation (and possibe re-implementation) of the application is needed.

Additional Documents

  • ./examples/: Examples (python, php, on-browser, etc.)

Acknowledgement

container2wasm's People

Contributors

ktock avatar dependabot[bot] avatar kateinoigakukun avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.