Use docker as dev environment

This commit is contained in:
Jianfeng Jiang
2023-07-05 14:08:58 +08:00
committed by Tate, Hongliang Tian
parent bf961756b9
commit 9137ef434f
52 changed files with 202 additions and 207 deletions

14
.gitattributes vendored
View File

@ -1,14 +0,0 @@
regression/apps/hello_world/hello_world filter=lfs diff=lfs merge=lfs -text
regression/apps/fork/fork filter=lfs diff=lfs merge=lfs -text
regression/apps/hello_c/hello filter=lfs diff=lfs merge=lfs -text
regression/apps/execve/execve filter=lfs diff=lfs merge=lfs -text
regression/apps/execve/hello filter=lfs diff=lfs merge=lfs -text
regression/apps/fork_c/fork filter=lfs diff=lfs merge=lfs -text
regression/apps/signal_c/signal_test filter=lfs diff=lfs merge=lfs -text
regression/apps/busybox/busybox filter=lfs diff=lfs merge=lfs -text
regression/apps/pthread/pthread_test filter=lfs diff=lfs merge=lfs -text
regression/apps/hello_pie/hello filter=lfs diff=lfs merge=lfs -text
regression/apps/network/tcp/client filter=lfs diff=lfs merge=lfs -text
regression/apps/network/tcp/server filter=lfs diff=lfs merge=lfs -text
regression/apps/network/udp/client filter=lfs diff=lfs merge=lfs -text
regression/apps/network/udp/server filter=lfs diff=lfs merge=lfs -text

View File

@ -24,38 +24,34 @@ As a zero-cost, least-privilege OS, Jinux provides the best of both worlds: the
## Build and test ## Build and test
While most of the code is written in Rust, the project-scope build process is governed by Makefile. The following commands are intended for use on an Ubuntu server that has installed qemu-system-x86_64. While most of the code is written in Rust, the project-scope build process is governed by Makefile. The development environment is managed with Docker. Please ensure Docker is installed and can be run without sudo privilege.
### Preparation ### Preparation
1. Download the latest source code of jinux.
Before downloading source code, install and init Git LFS since the project manages binaries with Git LFS.
```bash
# 1. install git-lfs
apt install git-lfs
# 2. init git-lfs for current user
git lfs install --skip-repo
```
Then, download source codes as normal.
```bash ```bash
git clone [repository url] git clone [repository url]
``` ```
After downloading the source code, run the following command once to make sure 2. After downloading the source code, run the following command to pull the development image.
all developmennt tools are installed.
```bash ```bash
make setup docker pull jinuxdev/jinux:0.1.0
``` ```
3. Start the development container.
```bash
docker run -it --privileged --network=host --device=/dev/kvm -v `pwd`:/root/jinux jinuxdev/jinux:0.1.0
```
**All build and test commands should be run inside the development container.**
### Build ### Build
Then, we can build the project. 1. Build the project.
```bash ```bash
make build make build
``` ```
If everything goes well, then we can run the OS. 2. If everything goes well, then we can run the OS.
```bash ```bash
make run make run
``` ```
@ -67,11 +63,11 @@ We can run unit tests and integration tests if building succeeds.
make test make test
``` ```
If we want to check access control policy among components, install some standalone tools (e.g., `cargo-component`), and set environmental variables to enable `cargo` find installed tools under the project directory. If we want to check access control policy among components, install some standalone tools (e.g., `cargo-component`).
``` bash ``` bash
make tools make tools
export PATH=`pwd`/target/bin:${PATH}
``` ```
Then we can use the tool to check access control policy. Then we can use the tool to check access control policy.
```bash ```bash
cargo component-check cargo component-check

View File

@ -38,9 +38,11 @@ fn read_ramdisk_content() -> &'static [u8] {
#[cfg(not(test))] #[cfg(not(test))]
#[panic_handler] #[panic_handler]
fn panic(info: &PanicInfo) -> ! { fn panic(info: &PanicInfo) -> ! {
use jinux_frame::{exit_qemu, QemuExitCode};
println!("[panic]:{:?}", info); println!("[panic]:{:?}", info);
jinux_frame::panic_handler(); jinux_frame::panic_handler();
loop {} exit_qemu(QemuExitCode::Failed);
} }
#[cfg(test)] #[cfg(test)]

View File

@ -17,10 +17,10 @@ all: build
$(INITRAMFS): $(INITRAMFS):
@rm -rf $@ && mkdir -p $@ @rm -rf $@ && mkdir -p $@
@# Mkdir necessary folders @# Mkdir necessary folders
@mkdir -p $@/tmp @mkdir -p $@/bin $@/etc $@/sbin $@/usr/bin $@/root $@/tmp $@/opt $@/lib64 $@/lib/x86_64-linux-gnu
@mkdir -p $@/opt @# Install busybox
@mkdir -p $@/lib64 @/bin/busybox --install -s $@/bin
@mkdir -p $@/lib/x86_64-linux-gnu @cp /usr/bin/busybox $@/usr/bin
@# Copy necessary libs @# Copy necessary libs
@cp -L /lib64/ld-linux-x86-64.so.2 $@/lib64 @cp -L /lib64/ld-linux-x86-64.so.2 $@/lib64
@cp -L /lib/x86_64-linux-gnu/libc.so.6 $@/lib/x86_64-linux-gnu @cp -L /lib/x86_64-linux-gnu/libc.so.6 $@/lib/x86_64-linux-gnu

View File

@ -2,11 +2,14 @@ MAKEFLAGS += --no-builtin-rules # Prevent the implicit rules from compiling ".c"
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH))) CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
INITRAMFS ?= $(CUR_DIR)/../build/initramfs INITRAMFS ?= $(CUR_DIR)/../build/initramfs
REGRESSION_BUILD_DIR ?= $(INITRAMFS)/regression
TEST_APPS := signal_c pthread network hello_world hello_pie hello_c fork_c fork execve
.PHONY: all .PHONY: all
all: build all:
@mkdir -p $(REGRESSION_BUILD_DIR)
build: @for test_app in $(TEST_APPS); \
@cp -a $(CUR_DIR)/* $(INITRAMFS) do make --no-print-directory -C $${test_app}; \
@cd $(INITRAMFS) && find . \( -name "*.s" -o -name "*.c" -o -name "Makefile" -o -name "README.md" \) -delete done
@make --no-print-directory BUILD_DIR=$(REGRESSION_BUILD_DIR) -C scripts

View File

@ -1,4 +0,0 @@
.PHONY: all
all:
ln -sf /busybox/busybox sh

View File

@ -1 +0,0 @@
/busybox/busybox

View File

@ -1,7 +0,0 @@
### How to compile this busybox
We don't include the source code of busybox here since the source code is really large. The busybox can be compiled with following commands.
After download the source code of busybox 1.35.0 and unzip, then cd to the directory of busybox
1. `make defconfig`. We set all config as default.
2. Set static link option in .config: `CONFIG_STATIC=y`. We need a static-linked busybox binary since we does not support dynamic linking now.
3. Set standalone shell option in .config: `CONFIG_FEATURE_SH_STANDALONE=y`. The standalone ash will try to call busybox applets instead of search binaries in host system. e.g., when running ls, standalone ash will invoke `busybox ls`.

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6db28e1ed8bdac06ac595b2126cefc10ecf16156bf4c1005950f561aedc0531a
size 2701792

View File

@ -1,12 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: hello.c execve.c EXTRA_C_FLAGS :=-static
@gcc -static hello.c -o hello
@gcc -static execve.c -o execve
clean:
@rm hello
@rm execve
run: build
@./execve

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c7cc90df87ade7ff2cb494e13678aceaf93542883558fda947bd2fc01e2d73a6
size 871952

View File

@ -8,7 +8,7 @@ int main() {
printf("Execve a new file /execve/hello:\n"); printf("Execve a new file /execve/hello:\n");
// flush the stdout content to ensure the content print to console // flush the stdout content to ensure the content print to console
fflush(stdout); fflush(stdout);
execve("/execve/hello", argv, envp); execve("/regression/execve/hello", argv, envp);
printf("Should not print\n"); printf("Should not print\n");
fflush(stdout); fflush(stdout);
return 0; return 0;

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d0152798ba393fb04603ead02083e74de560d9cf51584f5cdca762d0706ebd2d
size 871960

View File

@ -1,10 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: fork.s EXTRA_C_FLAGS :=-static -nostdlib
@gcc -static -nostdlib fork.s -o fork
clean:
@rm fork
run: build
@./fork

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9bc1642390b9dc38ecc058240e529401c38aa8bb9a86bad3615e4bdad505fa8c
size 9592

View File

@ -1,10 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: fork.c EXTRA_C_FLAGS :=-static
@gcc -static fork.c -o fork
clean:
@rm fork
run: build
@./fork

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ca7a77a72da160f11670a04a16b623944295b9059399da45f57668f121b00d11
size 877152

View File

@ -1,10 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: hello.c EXTRA_C_FLAGS :=-static -mno-sse
@gcc -static -mno-sse hello.c -o hello
clean:
@rm hello
run: build
@./hello

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dda5a7d6081cc2252056375d0550731ef2fd24789aa5f17da189a36bf78c588d
size 871896

View File

@ -1,10 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: hello.c EXTRA_C_FLAGS :=
@gcc hello.c -o hello
clean:
@rm hello
run: build
@./hello

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:64b67cf4ad247d668833888447ec7f12d37f5f816abd549d5c2c08fecfa4dd09
size 16696

View File

@ -1,10 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: hello_world.s EXTRA_C_FLAGS :=-static -nostdlib
@gcc -static -nostdlib hello_world.s -o hello_world
clean:
@rm hello_world
run: build
@./hello_world

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f56fb5cf05f234578b13c8d73f2d29568f6f513602f1ea0b71a0dbf0cf8f60f8
size 9104

View File

@ -1,13 +1,3 @@
.PHONY: build clean include ../test_common.mk
build: tcp/client.c tcp/server.c udp/client.c udp/server.c EXTRA_C_FLAGS :=
@gcc tcp/client.c -o tcp/client
@gcc tcp/server.c -o tcp/server
@gcc udp/server.c -o udp/server
@gcc udp/client.c -o udp/client
clean:
@rm tcp/client
@rm tcp/server
@rm udp/client
@rm udp/server

View File

@ -1,11 +0,0 @@
#!/bin/sh
NETTEST_DIR=/network
cd ${NETTEST_DIR}
echo "Start net test......"
./tcp/server &
./tcp/client
./udp/server &
./udp/client
echo "All net test passed"

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6ba2aa2da39e5e6d7be121f13e9321a43a4a47b03f50d3d8303d3d51753e2f5c
size 17096

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:209ffb16164cc1e4f7dc978ce3d660e5c9bee5cd4f70e20088d59c8ff64b8d7d
size 17368

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2701b848bdcbde4c1a2af2923f6c57d261befd7b20180fe0c10ac820f7082303
size 17280

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8e890e0782c4320369841b50abfb56f0059b02881ea5b3384224ae65ce9c1d65
size 17328

View File

@ -1,10 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: pthread_test.c EXTRA_C_FLAGS :=-static -lpthread
@gcc -static pthread_test.c -lpthread -o pthread_test
clean:
@rm pthread_test
run: build
@./pthread_test

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d40bfc16dbf95aba3afa1934fa4efc0147f0a0a12533362a8d95e105d4d2af21
size 1693840

View File

@ -0,0 +1,4 @@
.PHONY: all
all: ./*.sh
@cp ./*.sh $(BUILD_DIR)

View File

@ -0,0 +1,11 @@
#!/bin/sh
NETTEST_DIR=/regression/network
cd ${NETTEST_DIR}
echo "Start net test......"
./tcp_server &
./tcp_client
./udp_server &
./udp_client
echo "All net test passed"

View File

@ -2,15 +2,14 @@
set -e set -e
SCRIPT_DIR=/scripts SCRIPT_DIR=/regression
cd ${SCRIPT_DIR}/.. cd ${SCRIPT_DIR}/..
echo "Running tests......" echo "Running tests......"
tests="hello_world/hello_world fork/fork execve/execve fork_c/fork signal_c/signal_test pthread/pthread_test hello_pie/hello" tests="hello_world/hello_world fork/fork execve/execve fork_c/fork signal_c/signal_test pthread/pthread_test hello_pie/hello"
for testcase in ${tests} for testcase in ${tests}
do do
echo "Running test ${testcase}......" echo "Running test ${testcase}......"
${testcase} ${SCRIPT_DIR}/${testcase}
done done
echo "All tests passed" echo "All tests passed"

View File

@ -3,7 +3,7 @@
set -e set -e
set -x set -x
SCRIPT_DIR=/scripts SCRIPT_DIR=/regression
cd ${SCRIPT_DIR} cd ${SCRIPT_DIR}
touch hello.txt touch hello.txt

View File

@ -1,7 +1,3 @@
.PHONY: build clean run include ../test_common.mk
build: signal_test.c
@gcc -static signal_test.c -o signal_test EXTRA_C_FLAGS :=-static
clean:
@rm signal_test
run: build
@./signal_test

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:25894b343f222eea5074a83e16a7140868a992a66e7bc8e363fabf2c23e19451
size 882520

View File

@ -0,0 +1,27 @@
MAIN_MAKEFILE := $(firstword $(MAKEFILE_LIST))
INCLUDE_MAKEFILE := $(lastword $(MAKEFILE_LIST))
CUR_DIR := $(shell dirname $(realpath $(MAIN_MAKEFILE)))
CUR_DIR_NAME := $(shell basename $(realpath $(CUR_DIR)))
REGRESSION_BUILD_DIR := $(CUR_DIR)/../../build/initramfs/regression
OBJ_OUTPUT_DIR := $(REGRESSION_BUILD_DIR)/$(CUR_DIR_NAME)
C_SRCS := $(wildcard *.c)
C_OBJS := $(addprefix $(OBJ_OUTPUT_DIR)/,$(C_SRCS:%.c=%))
ASM_SRCS := $(wildcard *.s)
ASM_OBJS := $(addprefix $(OBJ_OUTPUT_DIR)/,$(ASM_SRCS:%.s=%))
CC := gcc
C_FLAGS :=
.PHONY: all
all: $(OBJ_OUTPUT_DIR) $(C_OBJS) $(ASM_OBJS)
$(OBJ_OUTPUT_DIR):
@mkdir -p $(OBJ_OUTPUT_DIR)
$(CUR_DIR)/../../build/initramfs/regression/$(CUR_DIR_NAME)/%: %.c
@$(CC) $(C_FLAGS) $(EXTRA_C_FLAGS) $< -o $@
@echo "CC <= $@"
$(CUR_DIR)/../../build/initramfs/regression/$(CUR_DIR_NAME)/%: %.s
@$(CC) $(C_FLAGS) $(EXTRA_C_FLAGS) $< -o $@
@echo "CC <= $@"

View File

@ -1,2 +1,3 @@
[toolchain] [toolchain]
channel = "nightly-2023-02-05" channel = "nightly-2023-02-05"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View File

@ -98,7 +98,7 @@ pub fn run_first_process() -> ! {
} }
fn run_busybox() -> Result<Arc<Process>> { fn run_busybox() -> Result<Arc<Process>> {
let executable_path = "/busybox/busybox"; let executable_path = "/usr/bin/busybox";
let argv = ["sh", "-l"]; let argv = ["sh", "-l"];
let envp = [ let envp = [
"SHELL=/bin/sh", "SHELL=/bin/sh",

View File

@ -53,14 +53,12 @@ pub fn spawn_background_poll_thread(iface: Arc<dyn Iface>) {
debug!("spawn background poll thread"); debug!("spawn background poll thread");
loop { loop {
let next_poll_time = if let Some(next_poll_time) = iface.next_poll_at_ms() { let next_poll_time = if let Some(next_poll_time) = iface.next_poll_at_ms() {
trace!("next poll time = {:?}", next_poll_time);
next_poll_time next_poll_time
} else { } else {
Thread::yield_now(); Thread::yield_now();
continue; continue;
}; };
let now = read_monotonic_milli_seconds(); let now = read_monotonic_milli_seconds();
trace!("now = {:?}", now);
if now > next_poll_time { if now > next_poll_time {
// FIXME: now is later than next poll time. This may cause problem. // FIXME: now is later than next poll time. This may cause problem.
iface.poll(); iface.poll();

View File

@ -4,24 +4,24 @@ use jinux_frame::task::{set_scheduler, Scheduler, Task, TaskAdapter};
use intrusive_collections::LinkedList; use intrusive_collections::LinkedList;
pub struct FifoScheduler { pub struct FifoScheduler {
tasks: Mutex<LinkedList<TaskAdapter>>, tasks: SpinLock<LinkedList<TaskAdapter>>,
} }
impl FifoScheduler { impl FifoScheduler {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tasks: Mutex::new(LinkedList::new(TaskAdapter::new())), tasks: SpinLock::new(LinkedList::new(TaskAdapter::new())),
} }
} }
} }
impl Scheduler for FifoScheduler { impl Scheduler for FifoScheduler {
fn enqueue(&self, task: Arc<Task>) { fn enqueue(&self, task: Arc<Task>) {
self.tasks.lock().push_back(task.clone()); self.tasks.lock_irq_disabled().push_back(task.clone());
} }
fn dequeue(&self) -> Option<Arc<Task>> { fn dequeue(&self) -> Option<Arc<Task>> {
self.tasks.lock().pop_front() self.tasks.lock_irq_disabled().pop_front()
} }
} }

View File

@ -102,7 +102,9 @@ impl<'a> Iterator for FutexIter<'a> {
} else { } else {
None None
}; };
let robust_list = read_val_from_user::<RobustList>(self.entry_ptr).unwrap(); let Ok(robust_list) = read_val_from_user::<RobustList>(self.entry_ptr) else {
return None;
};
self.entry_ptr = robust_list.next; self.entry_ptr = robust_list.next;
self.count += 1; self.count += 1;
if futex_addr.is_some() { if futex_addr.is_some() {

View File

@ -465,7 +465,7 @@ pub fn syscall_dispatch(
SYS_GETRANDOM => syscall_handler!(3, sys_getrandom, args), SYS_GETRANDOM => syscall_handler!(3, sys_getrandom, args),
SYS_EXECVEAT => syscall_handler!(5, sys_execveat, args, context), SYS_EXECVEAT => syscall_handler!(5, sys_execveat, args, context),
_ => { _ => {
error!("Unimplemented syscall number: {}", syscall_number); warn!("Unimplemented syscall number: {}", syscall_number);
return_errno_with_message!(Errno::ENOSYS, "Syscall was unimplemented"); return_errno_with_message!(Errno::ENOSYS, "Syscall was unimplemented");
} }
} }

View File

@ -254,7 +254,6 @@ impl Vmo_ {
pub fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> Result<()> { pub fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
let read_len = buf.len(); let read_len = buf.len();
debug_assert!(offset + read_len <= self.size());
if offset + read_len > self.size() { if offset + read_len > self.size() {
return_errno_with_message!(Errno::EINVAL, "read range exceeds vmo size"); return_errno_with_message!(Errno::EINVAL, "read range exceeds vmo size");
} }

View File

@ -0,0 +1,72 @@
FROM ubuntu:22.04
SHELL ["/bin/bash", "-c"]
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update && apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
cpio \
cpuid \
curl \
file \
g++ \
gdb \
git-core \
gnupg \
grub-common \
libssl-dev \
net-tools \
openssh-server \
pkg-config \
python-is-python3 \
python3-pip \
qemu-system-x86 \
strace \
sudo \
unzip \
vim \
wget \
xorriso \
zip
# Install bazel, , which is required by the system call test suite from Gvisor project
RUN curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg \
&& mv bazel.gpg /etc/apt/trusted.gpg.d/ \
&& echo 'deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8' | tee /etc/apt/sources.list.d/bazel.list \
&& apt update \
&& apt install bazel=5.4.0 -y
# Clean apt cache
RUN apt clean \
&& rm -rf /var/lib/apt/lists/*
# Install Rust
ENV PATH="/root/.cargo/bin:${PATH}"
ENV JINUX_RUST_VERSION="nightly-2023-02-05"
RUN curl https://sh.rustup.rs -sSf | \
sh -s -- --default-toolchain ${JINUX_RUST_VERSION} -y \
&& rm -rf /root/.cargo/registry && rm -rf /root/.cargo/git \
&& cargo -V \
&& rustup component add rust-src rustc-dev llvm-tools-preview
# Install mdbook
RUN cargo install mdbook
# Add the path of jinux tools
ENV PATH="/root/jinux/target/bin:${PATH}"
# Build busybox
RUN curl --output busybox.tar.bz2 https://busybox.net/downloads/busybox-1.35.0.tar.bz2 \
&& mkdir /root/busybox \
&& tar xf busybox.tar.bz2 --strip-components=1 -C /root/busybox
WORKDIR /root/busybox
RUN make defconfig \
&& sed -i "s/# CONFIG_STATIC is not set/CONFIG_STATIC=y/g" .config \
&& sed -i "s/# CONFIG_FEATURE_SH_STANDALONE is not set/CONFIG_FEATURE_SH_STANDALONE=y/g" .config \
&& make -j \
&& cp /root/busybox/busybox /bin/busybox
VOLUME [ "/root/jinux" ]
WORKDIR /root/jinux

14
tools/docker/build_image.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -e
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
CARGO_TOML_PATH=${SCRIPT_DIR}/../../Cargo.toml
VERSION=$( grep -m1 -o '[0-9]\+\.[0-9]\+\.[0-9]\+' ${CARGO_TOML_PATH} | sed 's/[^0-9\.]//g' )
IMAGE_NAME=jinuxdev/jinux:${VERSION}
DOCKER_FILE=${SCRIPT_DIR}/Dockerfile.ubuntu22.04
ARCH=linux/amd64
# Build docker
cd ${SCRIPT_DIR}
docker buildx build -f ${DOCKER_FILE} --platform ${ARCH} -t ${IMAGE_NAME} .

View File

@ -0,0 +1,11 @@
#!/bin/bash
set -e
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
JINUX_SRC_DIR=${SCRIPT_DIR}/../..
CARGO_TOML_PATH=${SCRIPT_DIR}/../../Cargo.toml
VERSION=$( grep -m1 -o '[0-9]\+\.[0-9]\+\.[0-9]\+' ${CARGO_TOML_PATH} | sed 's/[^0-9\.]//g' )
IMAGE_NAME=jinuxdev/jinux:${VERSION}
docker run -it --privileged --network=host --device=/dev/kvm -v ${JINUX_SRC_DIR}:/root/jinux ${IMAGE_NAME}