Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add windows docker build script #125

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ jobs:
echo "VERSION=${NEXT_VERSION}" >> $GITHUB_ENV
echo "Next version to be published is: ${NEXT_VERSION}"

RUST_TOOLCHAIN=$(./docker.sh print-rust-toolchain)
echo "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" >> $GITHUB_ENV
echo "Rust toolchain used is: ${RUST_TOOLCHAIN}"

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
Expand All @@ -72,6 +76,7 @@ jobs:
# docker container on both x86_64 and arm64.
platforms: linux/amd64,linux/arm64
tags: ${{ env.VERSION }},${{ env.IMAGE_NAME }}:latest
build-args: RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
cache-from: type=gha
cache-to: type=gha,mode=max

Expand Down Expand Up @@ -120,6 +125,10 @@ jobs:
echo "VERSION=${NEXT_VERSION}" >> $GITHUB_ENV
echo "Next version to be published is: ${NEXT_VERSION}"

RUST_TOOLCHAIN=$(./docker.sh print-rust-toolchain)
echo "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" >> $GITHUB_ENV
echo "Rust toolchain used is: ${RUST_TOOLCHAIN}"

- name: Build and push Docker image for RISC-V
id: build-and-push-riscv
uses: docker/build-push-action@v6
Expand All @@ -129,6 +138,7 @@ jobs:
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64
tags: ${{ env.VERSION }}-riscv,${{ env.IMAGE_NAME }}:latest-riscv
build-args: RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
cache-from: type=gha
cache-to: type=gha,mode=max

Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
FROM ubuntu:24.04

ARG RUST_TOOLCHAIN
ENV RUST_TOOLCHAIN=${RUST_TOOLCHAIN}
# Adding rust binaries to PATH.
ENV PATH="$PATH:/root/.cargo/bin"

Expand Down
2 changes: 2 additions & 0 deletions Dockerfile.riscv64
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@

# Build rootfs with sshd and Rust related packages ready
# ---------------------------------------------------------
FROM --platform=linux/riscv64 riscv64/ubuntu:24.04 AS rootfs_builder

Check warning on line 24 in Dockerfile.riscv64

View workflow job for this annotation

GitHub Actions / build-riscv

FROM --platform flag should not use a constant value

FromPlatformFlagConstDisallowed: FROM --platform flag should not use constant value "linux/riscv64" More info: https://docs.docker.com/go/dockerfile/rule/from-platform-flag-const-disallowed/

ARG RUST_TOOLCHAIN
ENV RUST_TOOLCHAIN=${RUST_TOOLCHAIN}
ENV PATH="$PATH:/root/.cargo/bin"
COPY build_container.sh /opt/src/scripts/build.sh
RUN /opt/src/scripts/build.sh
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile.windows.x86_64
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ ARG RUST_TOOLCHAIN
FROM mcr.microsoft.com/windows/servercore:$WIN_VER

ENV chocolateyUseWindowsCompression "true"
ENV RUST_TOOLCHAIN="1.46.0"
# Set Chocolatey version to 1.4.0 to avoid .NET Framework 4.8 dependency
ENV chocolateyVersion="1.4.0"

ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
ADD https://win.rustup.rs/x86_64 C:\TEMP\rustup-init.exe
Expand Down
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ Example of running cargo build on the kvm crate:
Finished `release` profile [optimized] target(s) in 6.34s
```

For Windows users (ensure Docker Desktop is in Linux containers mode):
```powershell
> git clone https://github.com/rust-vmm/kvm.git
> cd kvm
> docker run --volume "${PWD}:/kvm" `
rustvmm/dev:latest `
/bin/bash -c "cd /kvm && cargo build --release"
```
## Testing Changes locally with the Container Image

When we modify the container to install new dependencies, we may need to
Expand Down Expand Up @@ -74,6 +82,28 @@ Since you've mounted the host's current directory ($(pwd)) to `/workdir` in
the container, any files in the current working directory on the host will be
accessible in the `/workdir` directory inside the container.

For Windows (ensure Docker Desktop is in Linux containers mode):
```powershell
> cd rust-vmm-container
> .\docker.ps1 build

# Example output: Build completed for rustvmm/dev:gb607c2b_x86_64

# Test the container using the tag from the build output
> docker run -it --rm `
--volume "${PWD}:/path/to/workdir" `
--workdir /path/to/workdir `
rustvmm/dev:gb607c2b_x86_64
```

Note: Unlike Linux, Windows doesn't have direct access to KVM, so the `--device=/dev/kvm` and `--privileged` flags are not needed.

Note: If you want to build a Windows container instead, you can switch Docker Desktop to "Windows containers" mode and run:
```powershell
> cd rust-vmm-container
> .\docker.ps1 build # This will automatically use Dockerfile.windows.x86_64
```

## Publishing a New Version

A new container version is published for each PR merged to main that adds
Expand Down Expand Up @@ -107,6 +137,18 @@ On an `aarch64` platform:
> ./docker.sh publish
```

On Windows (ensure Docker Desktop is in Linux containers mode):

```powershell
> cd rust-vmm-container
> .\docker.ps1 build
> .\docker.ps1 publish


# To check if Docker is in Linux containers mode:
> docker version --format '{{.Server.Os}}' # Should output 'linux'
```

You will need to redo all steps on an `x86_64` platform so the containers are
kept in sync (same package versions on both `x86_64` and `aarch64`).

Expand Down
1 change: 0 additions & 1 deletion build_container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
set -ex

ARCH=$(uname -m)
RUST_TOOLCHAIN="1.85.0"

apt-get update

Expand Down
5 changes: 5 additions & 0 deletions docker.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
IMAGE_NAME=rustvmm/dev
REGISTRY=index.docker.io
GIT_COMMIT=$(git rev-parse HEAD)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
RUST_TOOLCHAIN="1.85.0"
100 changes: 100 additions & 0 deletions docker.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
param(
[Parameter(Mandatory=$false)]
[string]$Command
)
$ErrorActionPreference = "Stop"
Get-Content docker.env | Where-Object { $_ -match '^([^#][^=]+)=(.+)$' } | ForEach-Object {
if ($matches[2] -match '\$\((.*)\)') {
$cmdOutput = Invoke-Expression $matches[1]
Set-Variable -Name $matches[1].Trim() -Value $cmdOutput -Scope Script
} else {
Set-Variable -Name $matches[1].Trim() -Value $matches[2].Trim() -Scope Script
}
}
$ARCH = "x86_64" # Explicitly set the architecture

function Next-Version {
return (git show -s --format=%h)
}

function Get-FullVersion {
$version = Next-Version
return "${IMAGE_NAME}:g${version}"
}

function Print-NextVersion {
Write-Output (Get-FullVersion)
}

function Print-Registry {
Write-Output $REGISTRY
}

function Print-ImageName {
Write-Output $IMAGE_NAME
}

function Build-Tag {
return "$(Get-FullVersion)_$ARCH"
}

function Check-ExitCode {
param (
[int]$ExitCode,
[string]$Message
)

if ($ExitCode -ne 0) {
Write-Error $Message
exit $ExitCode
}
}

function Build-Container {
# Check if running in Linux or Windows container mode
$containerInfo = docker version --format '{{.Server.Os}}'
$dockerfile = if ($containerInfo -eq "linux") {
"Dockerfile"
} else {
"Dockerfile.windows.x86_64"
}

# Build the container and check for failures
$tag = Build-Tag
Write-Host "Building using $dockerfile in $containerInfo container mode..."

docker build -t $tag `
--build-arg GIT_BRANCH=$GIT_BRANCH `
--build-arg GIT_COMMIT=$GIT_COMMIT `
--build-arg RUST_TOOLCHAIN=$RUST_TOOLCHAIN `
-f $dockerfile .
Check-ExitCode $LASTEXITCODE "Build failed with exit code $LASTEXITCODE"
Write-Host "Build completed for $tag"
}

function Publish-Container {
$tag = Build-Tag
Write-Host "Publishing $tag to dockerhub"

# Check if image exists locally
$imageExists = docker image inspect $tag 2>$null
Check-ExitCode $LASTEXITCODE "Image $tag not found locally. Please run 'build' first."

# Attempt to push
docker push $tag
Check-ExitCode $LASTEXITCODE "Failed to publish $tag"
Write-Host "Successfully published $tag"
}

# Handle commands
switch ($Command) {
"build" { Build-Container }
"publish" { Publish-Container }
"print-registry" { Print-Registry }
"print-image-name" { Print-ImageName }
"print-next-version" { Print-NextVersion }
default {
Write-Host "Command $Command not supported. Try with 'publish', 'build', or 'print-next-version'."
exit 1
}
}
13 changes: 9 additions & 4 deletions docker.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#!/usr/bin/env bash
set -e
source "$(dirname "$0")/docker.env"
ARCH=$(uname -m)
GIT_COMMIT=$(git rev-parse HEAD)
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
IMAGE_NAME=rustvmm/dev
REGISTRY=index.docker.io

next_version() {
echo "$(git show -s --format=%h)"
Expand All @@ -22,6 +19,10 @@ print_image_name() {
echo ${IMAGE_NAME}
}

print_rust_toolchain() {
echo ${RUST_TOOLCHAIN}
}

# Builds the tag for the newest versions. It needs the last published version number.
# Returns a valid docker tag.
build_tag(){
Expand All @@ -40,6 +41,7 @@ build(){
--load \
--build-arg GIT_BRANCH="${GIT_BRANCH}" \
--build-arg GIT_COMMIT="${GIT_COMMIT}" \
--build-arg RUST_TOOLCHAIN="${RUST_TOOLCHAIN}" \
-f Dockerfile .
echo "Build completed for $new_tag"
}
Expand Down Expand Up @@ -82,6 +84,9 @@ case $1 in
"print-next-version")
print_next_version;
;;
"print-rust-toolchain")
print_rust_toolchain;
;;
*)
echo "Command $1 not supported. Try with 'publish', 'build', 'manifest' or 'print-next-version'. ";
;;
Expand Down