Skip to content

Commit

Permalink
Add dev container configuration
Browse files Browse the repository at this point in the history
The following dev container configuration can be found in the .devcontainer directory.
It contains:
- devcontainer.json a configuration file for the Dev container that puts everything toghether
- create_env.sh script that is run on the host machine and creates a .devcontainer/.env file that contains the necessary group info for the container image build phase
- Dockerfile.base config for a base container image that is pre-built by using the .github/workflows/CreateDevcontainerImage.yml action that is automatically triggered when a change is detected for Dockerfile.base or the workflow configuration.
- Dockerfile config that uses the pre-build image as a base image, creates a group with the same GID of the device being passed to the docker container and adds the user to that group

Note: The reason why the environment file generation is needed is because in order to access the device (/dev/kvm) inside the container, the user needs to belong to the correct group, so the group is created at image build time.

Signed-off-by: Doru Blanzeanu <[email protected]>
  • Loading branch information
dblnz authored Nov 12, 2024
1 parent 5de971c commit c34cfd1
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM ghcr.io/dblnz/hyperlight-devcontainer:latest

COPY .env /tmp/.env

RUN . /tmp/.env && \
sudo groupadd -r -g ${DEVICE_GID} -U ${USER} ${DEVICE_GROUP}

59 changes: 59 additions & 0 deletions .devcontainer/Dockerfile.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## Dockerfile for devcontainer

FROM mcr.microsoft.com/devcontainers/base:debian AS base

ARG USER
ARG GROUP
ARG RUST_TOOLCHAIN

ENV HOME="/home/${USER}"
ENV PATH="$HOME/.cargo/bin:$PATH"

# Install dependencies
RUN apt-get update \
&& apt-get -y install \
build-essential \
cmake \
curl \
git \
gnupg \
lsb-release \
make \
software-properties-common \
sudo \
wget

# Install llvm
RUN wget https://apt.llvm.org/llvm.sh \
&& chmod +x ./llvm.sh \
&& sudo ./llvm.sh 17 all \
&& sudo ln -s /usr/lib/llvm-17/bin/clang-cl /usr/bin/clang-cl \
&& sudo ln -s /usr/lib/llvm-17/bin/llvm-lib /usr/bin/llvm-lib \
&& sudo ln -s /usr/lib/llvm-17/bin/lld-link /usr/bin/lld-link \
&& sudo ln -s /usr/lib/llvm-17/bin/llvm-ml /usr/bin/llvm-ml \
&& sudo ln -s /usr/lib/llvm-17/bin/ld.lld /usr/bin/ld.lld \
&& sudo ln -s /usr/lib/llvm-17/bin/clang /usr/bin/clang

FROM base AS dev

# Make sure the devcontainer user has sudo access
RUN chown -R "${USER}:$GROUP" /home/${USER} \
&& echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# Persist bash hystory
RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
&& mkdir /commandhistory \
&& touch /commandhistory/.bash_history \
&& chown -R $USER /commandhistory \
&& echo "$SNIPPET" >> "/home/$USER/.bashrc"

USER $USER

# Install rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
&& rustup default $RUST_TOOLCHAIN \
&& rustup target add x86_64-unknown-linux-gnu \
&& rustup target add x86_64-unknown-none \
&& rustup target add x86_64-pc-windows-msvc \
&& cargo install just

12 changes: 12 additions & 0 deletions .devcontainer/create_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

ENV_FILE=.devcontainer/.env

DEVICE="/dev/kvm"
DEVICE_GROUP=$(ls -l $DEVICE | awk '{print $4}')
DEVICE_GID=$(getent group $DEVICE_GROUP | cut -d: -f3)

echo "USER=vscode" > $ENV_FILE
echo "GROUP=vscode" >> $ENV_FILE
echo "DEVICE_GID=$DEVICE_GID" >> $ENV_FILE
echo "DEVICE_GROUP=$DEVICE_GROUP" >> $ENV_FILE
28 changes: 28 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// For more info on the configuration below, check out the link:
// https://code.visualstudio.com/docs/devcontainers/create-dev-container
{
"name": "Hyperlight",

"build": {
"dockerfile": "Dockerfile"
},

"remoteUser": "vscode",

"runArgs": [
"--env-file", ".devcontainer/.env",
"--device=/dev/kvm"
],

// Use 'initializeCommand' to run commands before container image build
"initializeCommand": "bash .devcontainer/create_env.sh",

"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cmake-tools",
"rust-lang.rust-analyzer"
]
}
}
}
59 changes: 59 additions & 0 deletions .github/workflows/CreateDevcontainerImage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Create and publish devcontainer Docker image

on:
push:
paths:
- ".devcontainer/Dockerfile.base"
- ".github/workflows/CreateDevcontainerImage.yml"

# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}-devcontainer
USER: vscode
GROUP: vscode
RUST_TOOLCHAIN: 1.81.0

# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v3
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
with:
context: ./.devcontainer
file: ./.devcontainer/Dockerfile.base
push: true
tags: |
${{ steps.meta.outputs.tags }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
labels: ${{ steps.meta.outputs.labels }}
build-args: |
USER=${{ env.USER }}
GROUP=${{ env.GROUP }}
RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
# Mono auto generated files
mono_crash.*

# Devcontainer generated files
.devcontainer/.env

# Build results
**/[Dd]ebug/*
/[Dd]ebugPublic/
Expand Down Expand Up @@ -474,4 +477,4 @@ hyperlight_guest.h
# created by vs code c# extension
.mono

!.gitkeep
!.gitkeep

0 comments on commit c34cfd1

Please sign in to comment.