Add tdx guide for osdk

This commit is contained in:
Hsy-Intel 2024-05-15 22:57:04 +08:00 committed by Tate, Hongliang Tian
parent 69f0954271
commit 6014ecfc0f
9 changed files with 234 additions and 55 deletions

View File

@ -40,13 +40,32 @@ jobs:
build-args: |
"ASTER_RUST_VERSION=${{ steps.fetch-versions.outputs.rust_version }}"
- name: Generate OSDK Dockerfile
run: |
python3 ./osdk/tools/docker/gen_dockerfile.py
- name: Build and push OSDK test image
uses: docker/build-push-action@v4
with:
context: .
file: ./osdk/tools/Dockerfile.ubuntu22.04
file: ./osdk/tools/docker/Dockerfile
platforms: linux/amd64
push: true
tags: asterinas/osdk:${{ steps.fetch-versions.outputs.aster_version }}
build-args: |
"ASTER_RUST_VERSION=${{ steps.fetch-versions.outputs.rust_version }}"
- name: Generate OSDK Dockerfile for Intel TDX
run: |
python3 ./osdk/tools/docker/gen_dockerfile.py --intel-tdx
- name: Build and push OSDK test image for Intel TDX
uses: docker/build-push-action@v4
with:
context: .
file: ./osdk/tools/docker/Dockerfile
platforms: linux/amd64
push: true
tags: asterinas/osdk:${{ steps.fetch-versions.outputs.aster_version }}-tdx
build-args: |
"ASTER_RUST_VERSION=${{ steps.fetch-versions.outputs.rust_version }}"

View File

@ -24,6 +24,8 @@
* [Creating an OS Project](osdk/guide/create-project.md)
* [Testing or Running an OS Project](osdk/guide/run-project.md)
* [Working in a Workspace](osdk/guide/work-in-workspace.md)
* Advanced Topics
* [Intel TDX](osdk/guide/intel-tdx.md)
* [OSDK User Reference](osdk/reference/README.md)
* [Commands](osdk/reference/commands/README.md)
* [cargo osdk new](osdk/reference/commands/new.md)

View File

@ -0,0 +1,81 @@
# Running an OS in Intel TDX env
OSDK supports running your OS in an [Intel TDX](https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html) environment conveniently.
Intel TDX can provide a more secure environment for your OS.
## Prepare the Intel TDX Environment
Please make sure your server supports Intel TDX.
See [this guide](https://github.com/canonical/tdx/tree/noble-24.04?tab=readme-ov-file#4-setup-host-os)
or other materials to enable Intel TDX in host OS.
To verify the TDX host status, you can type:
```bash
dmesg | grep "TDX module initialized"
```
The following result is an example:
```bash
[ 20.507296] tdx: TDX module initialized.
```
If you see the message "TDX module initialized",
it means the TDX module has loaded successfully.
The Intel TDX environment requires TDX-enhanced versions of QEMU, KVM, GRUB,
and other essential software for running an OS.
Therefore, it is recommended to use a Docker image to deploy the environment.
Run a TDX Docker container:
```bash
docker run -it --privileged --network=host --device=/dev/kvm asterinas/osdk-tdx:0.4.2
```
## Edit `OSDK.toml` for Intel TDX support
As Intel TDX has extra requirements or restrictions for VMs,
it demands adjusting the OSDK configurations accordingly.
This can be easily achieved with the `scheme` feature of OSDK,
which provides a convenient way to override the default OSDK configurations
for a specific environment.
For example, you can append the following TDX-specific scheme to your `OSDK.toml` file.
```toml
[scheme."tdx"]
supported_archs = ["x86_64"]
boot.method = "grub-qcow2"
grub.mkrescue_path = "~/tdx-tools/grub"
grub.protocol = "linux"
qemu.args = """\
-accel kvm \
-name process=tdxvm,debug-threads=on \
-m 6G \
-vga none \
-monitor pty \
-no-hpet \
-nodefaults \
-drive file=target/osdk/asterinas/asterinas.qcow2,if=virtio,format=qcow2 \
-monitor telnet:127.0.0.1:9001,server,nowait \
-bios /usr/share/qemu/OVMF.fd \
-object tdx-guest,sept-ve-disable=on,id=tdx,quote-generation-service=vsock:2:4050 \
-object memory-backend-memfd-private,id=ram1,size=2G \
-cpu host,-kvm-steal-time,pmu=off,tsc-freq=1000000000 \
-machine q35,kernel_irqchip=split,confidential-guest-support=tdx,memory-backend=ram1 \
-smp 1 \
-nographic \
"""
```
To choose the configurations specified by the TDX scheme over the default ones,
add the `--scheme` argument to the build, run, or test command.
```bash
cargo osdk build --scheme tdx
cargo osdk run --scheme tdx
cargo osdk test --scheme tdx
```

View File

@ -1,50 +0,0 @@
# SPDX-License-Identifier: MPL-2.0
# This image is for the OSDK GitHub CI.
# The environment is consistent with the one
# described in the OSDK User Guide section of the Asterinas Book.
#
# TODO: We should build the Asterinas image based on the OSDK image
# since Asterinas is managed by OSDK itself.
# However, currently, these two images have different contents.
# The main distinction is that
# QEMU, grub, and OVMF in the OSDK image are installed via apt,
# while these tools in the Asterinas image are built from source.
# Some boot methods in Asterinas only function properly
# when using the tools that are built from source.
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update \
&& apt install -y \
build-essential \
curl \
gdb \
grub-efi-amd64 \
grub2-common \
libpixman-1-dev `# running dependency for QEMU` \
mtools `# used by grub-mkrescue` \
ovmf \
qemu-system-x86 \
xorriso \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*
# Install Rust of both nightly and stable channel
ENV PATH="/root/.cargo/bin:${PATH}"
ARG ASTER_RUST_VERSION
RUN curl https://sh.rustup.rs -sSf | \
sh -s -- --default-toolchain ${ASTER_RUST_VERSION} -y \
&& rustup toolchain install stable \
&& rm -rf /root/.cargo/registry && rm -rf /root/.cargo/git \
&& cargo -V \
&& rustup component add rust-src rustc-dev llvm-tools-preview
# Install cargo-binutils
RUN cargo install cargo-binutils
VOLUME [ "/root/asterinas" ]
WORKDIR /root/asterinas

1
osdk/tools/docker/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
**/Dockerfile

View File

@ -0,0 +1,36 @@
# SPDX-License-Identifier: MPL-2.0
FROM {% base_image %}
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update \
&& apt install -y \
build-essential \
curl \
gdb \
grub-efi-amd64 \
grub2-common \
libpixman-1-dev `# running dependency for QEMU` \
mtools `# used by grub-mkrescue` \
xorriso \
{% qemu_ovmf_installation %} \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*
# Install Rust of both nightly and stable channel
ENV PATH="/root/.cargo/bin:${PATH}"
ARG ASTER_RUST_VERSION
RUN curl https://sh.rustup.rs -sSf | \
sh -s -- --default-toolchain ${ASTER_RUST_VERSION} -y \
&& rustup toolchain install stable \
&& rm -rf /root/.cargo/registry && rm -rf /root/.cargo/git \
&& cargo -V \
&& rustup component add rust-src rustc-dev llvm-tools-preview
# Install cargo-binutils
RUN cargo install cargo-binutils
VOLUME [ "/root/asterinas" ]
WORKDIR /root/asterinas

View File

@ -5,11 +5,18 @@
set -e
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
ASTER_ROOT_DIR=${SCRIPT_DIR}/../..
ASTER_ROOT_DIR=${SCRIPT_DIR}/../../..
ASTER_RUST_VERSION=$( grep -m1 -o 'nightly-[0-9]\+-[0-9]\+-[0-9]\+' ${ASTER_ROOT_DIR}/rust-toolchain.toml )
VERSION=$( cat ${ASTER_ROOT_DIR}/VERSION )
IMAGE_NAME=asterinas/osdk:${VERSION}
DOCKERFILE=${SCRIPT_DIR}/Dockerfile.ubuntu22.04
DOCKERFILE=${SCRIPT_DIR}/Dockerfile
if [ "$1" = "intel-tdx" ]; then
IMAGE_NAME="asterinas/osdk:${VERSION}-tdx"
python3 gen_dockerfile.py --intel-tdx
else
IMAGE_NAME="asterinas/osdk:${VERSION}"
python3 gen_dockerfile.py
fi
docker build \
-t ${IMAGE_NAME} \

View File

@ -0,0 +1,78 @@
# SPDX-License-Identifier: MPL-2.0
import re
import argparse
import os
import sys
import logging
# Setup logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
def parse_arguments():
parser = argparse.ArgumentParser(description='The Dockerfile generator for OSDK.')
parser.add_argument('--intel-tdx', action='store_true', help='Include Intel TDX support')
parser.add_argument(
'--out-dir',
type=str,
default='.',
help='Output the Dockerfile under this directory. \
By default, the output directory is the current working directory.'
)
return parser.parse_args()
def validate_out_dir(out_dir):
if os.path.isabs(out_dir):
print("Error: The --out-dir argument must be a relative path.")
sys.exit(1)
def setup_output_directory(out_dir):
template_dir = os.path.dirname(os.path.abspath(__file__))
if out_dir == '.':
return template_dir
output_directory_path = os.path.join(template_dir, out_dir)
if not os.path.exists(output_directory_path):
os.makedirs(output_directory_path)
return output_directory_path
def load_template(template_dir):
template_file = os.path.join(template_dir, 'Dockerfile.template')
if not os.path.isfile(template_file):
logging.error(f"Template file {template_file} does not exist.")
sys.exit(1)
with open(template_file, 'r') as file:
return file.read()
def generate_dockerfile_content(variables, template_content):
for var_name, var_value in variables.items():
template_content = re.sub(r'{%\s*' + var_name + r'\s*%}', var_value, template_content)
return template_content
def write_dockerfile(output_directory, content):
output_path = os.path.join(output_directory, 'Dockerfile')
with open(output_path, 'w') as file:
file.write(content)
logging.info(f'Dockerfile has been generated at {output_path}.')
def main():
args = parse_arguments()
validate_out_dir(args.out_dir)
variables = {
'base_image': r'ubuntu:22.04',
'qemu_ovmf_installation': r"""ovmf \
qemu-system-x86""",
}
if args.intel_tdx:
variables['base_image'] = r'intelcczoo/tdvm:ubuntu22.04-mvp_2023ww15'
variables['qemu_ovmf_installation'] = r''
template_dir = os.path.dirname(os.path.abspath(__file__))
output_directory = setup_output_directory(args.out_dir)
template_content = load_template(template_dir)
dockerfile_content = generate_dockerfile_content(variables, template_content)
write_dockerfile(output_directory, dockerfile_content)
if __name__ == '__main__':
main()

View File

@ -7,6 +7,11 @@ set -e
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
ASTER_ROOT_DIR=${SCRIPT_DIR}/../..
VERSION=$( cat ${ASTER_ROOT_DIR}/VERSION )
IMAGE_NAME=asterinas/osdk:${VERSION}
if [ "$1" = "intel-tdx" ]; then
IMAGE_NAME="asterinas/osdk:${VERSION}-tdx"
else
IMAGE_NAME="asterinas/osdk:${VERSION}"
fi
docker run -it -v ${ASTER_ROOT_DIR}:/root/asterinas ${IMAGE_NAME}