Compare commits

..

No commits in common. "master" and "v36" have entirely different histories.
master ... v36

15 changed files with 223 additions and 303 deletions

View File

@ -1,19 +0,0 @@
# yaml-language-server: $schema=https://json.schemastore.org/dependabot-2.0.json
version: 2

updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
groups:
docker-all:
patterns: ["*"]

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
github-actions-all:
patterns: ["*"]

View File

@ -1,134 +0,0 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "Main"

on:
push:
tags: ["*"]
branches: ["*"]
pull_request:
branches: ["*"]
workflow_dispatch:

permissions: {}

jobs:
build-common-stages:
name: "Build common stages"
runs-on: "ubuntu-latest"
permissions:
contents: "read"
strategy:
matrix:
stage: ["build"]
steps:
- name: "Checkout project"
uses: "actions/checkout@v4"
- name: "Build and save image"
run: |
make \
IMAGE_REGISTRY="localhost" IMAGE_NAMESPACE="stage" IMAGE_PROJECT="${{ matrix.stage }}" \
IMAGE_BUILD_OPTS="--pull --target ${{ matrix.stage }} --build-arg BUILDKIT_INLINE_CACHE=1" \
build-native-image save-native-image
- name: "Upload artifacts"
uses: "actions/upload-artifact@v4"
with:
name: "dist-common-stages"
path: "./dist/"
retention-days: 1

build:
name: "Build ${{ matrix.arch }} image"
needs: ["build-common-stages"]
runs-on: "ubuntu-latest"
permissions:
contents: "read"
strategy:
matrix:
arch: ["native", "amd64", "arm64v8"]
steps:
- name: "Checkout project"
uses: "actions/checkout@v4"
- name: "Download artifacts"
uses: "actions/download-artifact@v4"
with:
name: "dist-common-stages"
path: "./dist/"
- name: "Load common stages"
run: |
docker system prune --all --force
make IMAGE_REGISTRY="localhost" IMAGE_NAMESPACE="stage" IMAGE_PROJECT="build" load-native-image clean
- name: "Register binfmt entries"
if: "matrix.arch != 'native'"
run: |
make binfmt-register
- name: "Build and save image"
run: |
make \
IMAGE_BUILD_OPTS="--cache-from localhost/stage/build:latest" \
"build-${{ matrix.arch }}-image" "save-${{ matrix.arch }}-image"
- name: "Upload artifacts"
if: "startsWith(github.ref, 'refs/tags/v') && matrix.arch != 'native'"
uses: "actions/upload-artifact@v4"
with:
name: "dist-${{ matrix.arch }}"
path: "./dist/"
retention-days: 1

push:
name: "Push ${{ matrix.arch }} image"
if: "startsWith(github.ref, 'refs/tags/v')"
needs: ["build"]
runs-on: "ubuntu-latest"
permissions:
contents: "read"
strategy:
matrix:
arch: ["amd64", "arm64v8"]
steps:
- name: "Checkout project"
uses: "actions/checkout@v4"
- name: "Download artifacts"
uses: "actions/download-artifact@v4"
with:
name: "dist-${{ matrix.arch }}"
path: "./dist/"
- name: "Login to Docker Hub"
uses: "docker/login-action@v3"
with:
registry: "docker.io"
username: "${{ secrets.DOCKERHUB_USERNAME }}"
password: "${{ secrets.DOCKERHUB_TOKEN }}"
- name: "Load and push image"
run: |
make "load-${{ matrix.arch }}-image" "push-${{ matrix.arch }}-image"

push-manifest:
name: "Push manifest"
if: "startsWith(github.ref, 'refs/tags/v')"
needs: ["push"]
runs-on: "ubuntu-latest"
permissions:
contents: "read"
steps:
- name: "Checkout project"
uses: "actions/checkout@v4"
- name: "Login to Docker Hub"
uses: "docker/login-action@v3"
with:
registry: "docker.io"
username: "${{ secrets.DOCKERHUB_USERNAME }}"
password: "${{ secrets.DOCKERHUB_TOKEN }}"
- name: "Push manifest"
run: |
make push-cross-manifest

publish-github-release:
name: "Publish GitHub release"
if: "startsWith(github.ref, 'refs/tags/v')"
needs: ["push-manifest"]
runs-on: "ubuntu-latest"
permissions:
contents: "write"
steps:
- name: "Publish"
uses: "hectorm/ghaction-release@066200d04c3549852afa243d631ea3dc93390f68"

View File

@ -1,22 +0,0 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "Rebuild latest release"

on:
schedule:
- cron: "20 04 * * 1"
workflow_dispatch:

permissions: {}

jobs:
trigger-rebuild:
name: "Trigger rebuild"
runs-on: "ubuntu-latest"
permissions:
actions: "write"
contents: "read"
steps:
- name: "Trigger rebuild"
uses: "hectorm/ghaction-trigger-workflow@04c79e7a4e0c0b94bbcff3829f38359e34f1ea9e"
with:
workflow-id: "main.yml"

97
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,97 @@
stages:
- 'build:images'
- 'push:images'
- 'push:manifests'

variables:
DOCKER_HOST: 'tcp://dockerd:2376'
DOCKER_TLS_SAN: 'DNS:dockerd'
DOCKER_TLS_CERTDIR: '/certs'
DOCKER_DRIVER: 'overlay2'

default:
image: 'docker.io/docker:latest'
services:
- name: 'docker.io/docker:dind'
alias: 'dockerd'

.cmds:
- &cmd_install_build_packages 'apk add --no-cache coreutils git m4 make zstd'
- &cmd_install_push_packages 'apk add --no-cache coreutils git make zstd'
- &cmd_docker_login_registry 'docker login -u "${CI_REGISTRY_USER:?}" -p "${CI_REGISTRY_PASSWORD:?}" "${CI_REGISTRY:?}"'

.regexes:
- &regex_version '/^v[0-9]+$/'

build:images:native:
stage: 'build:images'
except: [*regex_version]
before_script:
- *cmd_install_build_packages
script:
- 'make IMAGE_BUILD_OPTS="--pull" build-native-image save-native-image'
artifacts:
expire_in: '1 day'
paths:
- './dist/'

.build:images:cross:
stage: 'build:images'
only: [*regex_version]
before_script:
- *cmd_install_build_packages
script:
- 'make binfmt-register'
- 'make IMAGE_BUILD_OPTS="--pull" "build-${ARCH:?}-image" "save-${ARCH:?}-image"'
artifacts:
expire_in: '1 week'
paths:
- './dist/'

build:images:amd64:
extends: '.build:images:cross'
variables: {ARCH: 'amd64'}

build:images:arm64v8:
extends: '.build:images:cross'
variables: {ARCH: 'arm64v8'}

build:images:arm32v7:
extends: '.build:images:cross'
variables: {ARCH: 'arm32v7'}

.push:images:cross:
stage: 'push:images'
only: [*regex_version]
before_script:
- *cmd_install_push_packages
- *cmd_docker_login_registry
script:
- 'make "load-${ARCH:?}-image" "push-${ARCH:?}-image"'

push:images:amd64:
extends: '.push:images:cross'
dependencies: ['build:images:amd64']
variables: {ARCH: 'amd64'}

push:images:arm64v8:
extends: '.push:images:cross'
dependencies: ['build:images:arm64v8']
variables: {ARCH: 'arm64v8'}

push:images:arm32v7:
extends: '.push:images:cross'
dependencies: ['build:images:arm32v7']
variables: {ARCH: 'arm32v7'}

push:manifests:cross:
stage: 'push:manifests'
dependencies: ['push:images:amd64', 'push:images:arm64v8', 'push:images:arm32v7']
only: [*regex_version]
variables:
DOCKER_CLI_EXPERIMENTAL: 'enabled'
before_script:
- *cmd_install_push_packages
- *cmd_docker_login_registry
script:
- 'make push-cross-manifest'

View File

@ -4,116 +4,106 @@ m4_changequote([[, ]])
## "build" stage
##################################################

FROM --platform=${BUILDPLATFORM} docker.io/ubuntu:24.04 AS build
FROM docker.io/ubuntu:20.04 AS build

# Install system packages
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
binutils-mingw-w64-i686 \
ca-certificates \
curl \
gcc-mingw-w64-i686 \
genisoimage \
make \
p7zip-full \
qemu-system-x86 \
qemu-utils \
&& rm -rf /var/lib/apt/lists/*

# Download noVNC
ARG NOVNC_VERSION=v1.5.0
ARG NOVNC_VERSION=v1.3.0
ARG NOVNC_TARBALL_URL=https://github.com/novnc/noVNC/archive/${NOVNC_VERSION}.tar.gz
ARG NOVNC_TARBALL_CHECKSUM=6a73e41f98388a5348b7902f54b02d177cb73b7e5eb0a7a0dcf688cc2c79b42a
ARG NOVNC_TARBALL_CHECKSUM=ee8f91514c9ce9f4054d132f5f97167ee87d9faa6630379267e569d789290336
RUN curl -Lo /tmp/novnc.tgz "${NOVNC_TARBALL_URL:?}"
RUN printf '%s' "${NOVNC_TARBALL_CHECKSUM:?} /tmp/novnc.tgz" | sha256sum -c
RUN mkdir /tmp/novnc/ && tar -xzf /tmp/novnc.tgz --strip-components=1 -C /tmp/novnc/

# Download Websockify
ARG WEBSOCKIFY_VERSION=v0.12.0
ARG WEBSOCKIFY_VERSION=v0.10.0
ARG WEBSOCKIFY_TARBALL_URL=https://github.com/novnc/websockify/archive/${WEBSOCKIFY_VERSION}.tar.gz
ARG WEBSOCKIFY_TARBALL_CHECKSUM=37448ec992ef626f29558404cf6535592d02894ec1d5f0990a8c62621b39a967
ARG WEBSOCKIFY_TARBALL_CHECKSUM=7bd99b727e0be230f6f47f65fbe4bd2ae8b2aa3568350148bdf5cf440c4c6b4a
RUN curl -Lo /tmp/websockify.tgz "${WEBSOCKIFY_TARBALL_URL:?}"
RUN printf '%s' "${WEBSOCKIFY_TARBALL_CHECKSUM:?} /tmp/websockify.tgz" | sha256sum -c
RUN mkdir /tmp/websockify/ && tar -xzf /tmp/websockify.tgz --strip-components=1 -C /tmp/websockify/

# Download and build srvany-ng
ARG SRVANY_NG_TARBALL_URL=https://github.com/hectorm/srvany-ng/archive/refs/tags/v1.0.tar.gz
ARG SRVANY_NG_TARBALL_CHECKSUM=62d4c85d5dbef86d57bf5d21ff913bce81b821735df293968e1706f85096c8b0
RUN curl -Lo /tmp/srvany-ng.tgz "${SRVANY_NG_TARBALL_URL:?}"
RUN printf '%s' "${SRVANY_NG_TARBALL_CHECKSUM:?} /tmp/srvany-ng.tgz" | sha256sum -c
RUN mkdir /tmp/srvany-ng/ && tar -xzf /tmp/srvany-ng.tgz --strip-components=1 -C /tmp/srvany-ng/
RUN make -C /tmp/srvany-ng/ build

# Download ncat
ARG NCAT_ZIP_URL=https://nmap.org/dist/ncat-portable-5.59BETA1.zip
ARG NCAT_ZIP_CHECKSUM=9cdc2e688410f4563af7002d8dfa3f8a5710f15f6d409be2cab4e87890c91d1c
RUN curl -Lo /tmp/ncat.zip "${NCAT_ZIP_URL:?}"
RUN printf '%s' "${NCAT_ZIP_CHECKSUM:?} /tmp/ncat.zip" | sha256sum -c
RUN 7z e /tmp/ncat.zip -so '**/*.exe' > /tmp/ncat.exe

# Download Samba
# Download Samba for ReactOS
ARG SAMBA_EXE_URL=https://svn.reactos.org/packages/samba-for-ReactOSv1.3.exe
ARG SAMBA_EXE_CHECKSUM=c3f55cd7a4069cd682cbdca3954c425f6657e3a1aba786e3d1559448e9f849a3
RUN curl -Lo /tmp/samba.exe "${SAMBA_EXE_URL:?}"
RUN printf '%s' "${SAMBA_EXE_CHECKSUM:?} /tmp/samba.exe" | sha256sum -c

# Download BusyBox
ARG BUSYBOX_EXE_URL=https://frippery.org/files/busybox/busybox-w32-FRP-5398-g89ae34445.exe
ARG BUSYBOX_EXE_CHECKSUM=e311f576b6222a6a30fc892c4be13bd42387bcca65563e7ffff7004b9460b86c
# Download BusyBox for Windows
ARG BUSYBOX_EXE_URL=https://frippery.org/files/busybox/busybox-w32-FRP-4487-gd239d2d52.exe
ARG BUSYBOX_EXE_CHECKSUM=35e2b0db6d57a045188b9afc617aae52a6c8e2aa0205256c049f3537a48f879b
RUN curl -Lo /tmp/busybox.exe "${BUSYBOX_EXE_URL:?}"
RUN printf '%s' "${BUSYBOX_EXE_CHECKSUM:?} /tmp/busybox.exe" | sha256sum -c

# Download ncat for Windows
ARG NCAT_ZIP_URL=https://nmap.org/dist/ncat-portable-5.59BETA1.zip
ARG NCAT_ZIP_CHECKSUM=9cdc2e688410f4563af7002d8dfa3f8a5710f15f6d409be2cab4e87890c91d1c
RUN curl -Lo /tmp/ncat.zip "${NCAT_ZIP_URL:?}"
RUN printf '%s' "${NCAT_ZIP_CHECKSUM:?} /tmp/ncat.zip" | sha256sum -c

# Download and install ReactOS
ARG REACTOS_ISO_URL=https://downloads.sourceforge.net/reactos/ReactOS-0.4.14-release-119-gce0b4ff-iso.zip
ARG REACTOS_ISO_CHECKSUM=2937a619c9988d9c697930160e378d21048069c74e224b5c5ff6be470784b7d8
ARG REACTOS_ISO_URL=https://altushost-swe.dl.sourceforge.net/project/reactos/ReactOS/0.4.14/ReactOS-0.4.14-RC-120-g1c6eb6d-iso.zip
ARG REACTOS_ISO_CHECKSUM=ae46c71fd389f6d4e752ef82aa048fd46a757285f8e7ededf51ee679b5511f31
RUN curl -Lo /tmp/reactos.zip "${REACTOS_ISO_URL:?}"
RUN printf '%s' "${REACTOS_ISO_CHECKSUM:?} /tmp/reactos.zip" | sha256sum -c
RUN 7z e /tmp/reactos.zip -so '*.iso' > /tmp/reactos.iso \
&& 7z x /tmp/reactos.iso -o/tmp/reactos/ \
&& rm -f /tmp/reactos.iso
COPY --chown=root:root ./data/iso/ /tmp/reactos/
RUN install -D /tmp/srvany-ng/srvany-ng.exe /tmp/reactos/reactos/3rdParty/srvany-ng.exe
RUN install -D /tmp/ncat.exe /tmp/reactos/reactos/3rdParty/ncat.exe
RUN install -D /tmp/samba.exe /tmp/reactos/reactos/3rdParty/samba.exe
RUN install -D /tmp/busybox.exe /tmp/reactos/reactos/3rdParty/busybox.exe
RUN cp /tmp/samba.exe /tmp/reactos/reactos/3rdParty/samba.exe
RUN cp /tmp/busybox.exe /tmp/reactos/reactos/3rdParty/busybox.exe
RUN 7z e /tmp/ncat.zip -so '**/*.exe' > /tmp/reactos/reactos/3rdParty/ncat.exe
RUN mkisofs -no-emul-boot -iso-level 4 -eltorito-boot loader/isoboot.bin -o /tmp/reactos.iso /tmp/reactos/ \
&& qemu-img create -f qcow2 /tmp/reactos.qcow2 128G \
&& timeout 900 qemu-system-x86_64 \
-machine pc -smp 2 -m 512M -accel tcg \
-device VGA -display none -serial stdio \
-device e1000,netdev=n0 -netdev user,id=n0,ipv4=on,ipv6=off,net=10.0.2.0/24,host=10.0.2.2,dns=10.0.2.3,dhcpstart=10.0.2.15,restrict=on \
-device ide-hd,id=disk0,bus=ide.0,drive=disk0 -blockdev driver=qcow2,node-name=disk0,file.driver=file,file.filename=/tmp/reactos.qcow2 \
-device ide-cd,id=cd0,bus=ide.1,drive=cd0 -blockdev driver=raw,node-name=cd0,file.driver=file,file.filename=/tmp/reactos.iso,read-only=on \
-boot order=cd,menu=off \
-usb -device usb-tablet
-serial stdio -device VGA -display none \
-device e1000,netdev=n0 -netdev user,id=n0,restrict=on \
-drive file=/tmp/reactos.qcow2,index=0,media=disk,format=qcow2 \
-drive file=/tmp/reactos.iso,index=2,media=cdrom,format=raw \
-boot order=cd,menu=off -usb -device usb-tablet

##################################################
## "base" stage
##################################################

m4_ifdef([[CROSS_ARCH]], [[FROM docker.io/CROSS_ARCH/ubuntu:24.04]], [[FROM docker.io/ubuntu:24.04]]) AS base
m4_ifdef([[CROSS_ARCH]], [[FROM docker.io/CROSS_ARCH/ubuntu:20.04]], [[FROM docker.io/ubuntu:20.04]]) AS base
m4_ifdef([[CROSS_QEMU]], [[COPY --from=docker.io/hectormolinero/qemu-user-static:latest CROSS_QEMU CROSS_QEMU]])

# Install system packages
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
catatonit \
net-tools \
netcat-openbsd \
procps \
python3 \
qemu-kvm \
qemu-system-x86 \
qemu-utils \
rlwrap \
runit \
samba \
tini \
&& rm -rf /var/lib/apt/lists/*

# Environment
ENV VM_CPU=2
ENV VM_RAM=1024M
ENV VM_KEYBOARD=en-us
ENV VM_NET_GUESTFWD_OPTIONS=guestfwd=tcp:10.0.2.254:445-cmd:"nc 127.0.0.1 445"
ENV VM_NET_HOSTFWD_OPTIONS=hostfwd=tcp::2323-:23,hostfwd=tcp::5151-:51,hostfwd=tcp::3389-:3389
ENV VM_NET_EXTRA_OPTIONS=
ENV VM_KVM=true
ENV SVDIR=/etc/service/
@ -125,7 +115,7 @@ COPY --from=build --chown=root:root /tmp/novnc/ /opt/novnc/
COPY --from=build --chown=root:root /tmp/websockify/ /opt/novnc/utils/websockify/

# Copy ReactOS disk
COPY --from=build --chown=root:root /tmp/reactos.qcow2 /var/lib/qemu/disk/reactos.qcow2
COPY --from=build --chown=root:root /tmp/reactos.qcow2 /var/lib/qemu/image/reactos.qcow2

# Copy Samba config
COPY --chown=root:root ./config/samba/ /etc/samba/
@ -142,7 +132,7 @@ COPY --chown=root:root ./scripts/bin/ /usr/local/bin/
RUN find /usr/local/bin/ -type d -not -perm 0755 -exec chmod 0755 '{}' ';'
RUN find /usr/local/bin/ -type f -not -perm 0755 -exec chmod 0755 '{}' ';'

ENTRYPOINT ["/usr/bin/catatonit", "--", "/usr/local/bin/container-init"]
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/container-init"]

##################################################
## "test" stage
@ -153,8 +143,8 @@ FROM base AS test
RUN if [ "$(uname -m)" = 'x86_64' ]; then \
container-init & \
printf '%s\n' 'The quick brown fox jumps over the lazy dog' > /mnt/in || exit 1; \
printf '%s\n' '@echo off & smbclient -c "get /in C:/local; quit" //10.0.2.2/share noop & exit' | timeout 900 vmshell || exit 1; \
printf '%s\n' '@echo off & smbclient -c "put C:/local /out; quit" //10.0.2.2/share noop & exit' | timeout 120 vmshell || exit 1; \
printf '%s\n' '@echo off & smbclient -c "get /in C:/local; quit" //10.0.2.254/share noop & exit' | timeout 900 vmshell || exit 1; \
printf '%s\n' '@echo off & smbclient -c "put C:/local /out; quit" //10.0.2.254/share noop & exit' | timeout 120 vmshell || exit 1; \
cmp -s /mnt/in /mnt/out || exit 1; \
fi


View File

@ -1,7 +1,7 @@
The MIT License (MIT)
=====================

Copyright © Héctor Molinero Fernández
Copyright © 2021 Héctor Molinero Fernández

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,37 +1,40 @@
#!/usr/bin/make -f

SHELL := /bin/sh
.SHELLFLAGS := -euc
.SHELLFLAGS := -eu -c

DOCKER := $(shell command -v docker 2>/dev/null)
GIT := $(shell command -v git 2>/dev/null)
M4 := $(shell command -v m4 2>/dev/null)

DISTDIR := ./dist
VERSION_FILE = ./VERSION
DOCKERFILE_TEMPLATE := ./Dockerfile.m4

IMAGE_REGISTRY := docker.io
IMAGE_NAMESPACE := hectorm
IMAGE_NAMESPACE := hectormolinero
IMAGE_PROJECT := qemu-reactos
IMAGE_NAME := $(IMAGE_REGISTRY)/$(IMAGE_NAMESPACE)/$(IMAGE_PROJECT)
ifeq ($(shell '$(GIT)' status --porcelain 2>/dev/null),)
IMAGE_GIT_TAG := $(shell '$(GIT)' tag --list --contains HEAD 2>/dev/null)
IMAGE_GIT_SHA := $(shell '$(GIT)' rev-parse --verify --short HEAD 2>/dev/null)
IMAGE_VERSION := $(if $(IMAGE_GIT_TAG),$(IMAGE_GIT_TAG),$(if $(IMAGE_GIT_SHA),$(IMAGE_GIT_SHA),nil))
else
IMAGE_GIT_BRANCH := $(shell '$(GIT)' symbolic-ref --short HEAD 2>/dev/null)
IMAGE_VERSION := $(if $(IMAGE_GIT_BRANCH),$(IMAGE_GIT_BRANCH)-dirty,nil)

IMAGE_VERSION := v0
ifneq ($(wildcard $(VERSION_FILE)),)
IMAGE_VERSION := $(shell cat '$(VERSION_FILE)')
endif

IMAGE_BUILD_OPTS :=

IMAGE_NATIVE_DOCKERFILE := $(DISTDIR)/Dockerfile
IMAGE_NATIVE_TARBALL := $(DISTDIR)/$(IMAGE_PROJECT).tzst

IMAGE_AMD64_DOCKERFILE := $(DISTDIR)/Dockerfile.amd64
IMAGE_AMD64_TARBALL := $(DISTDIR)/$(IMAGE_PROJECT).amd64.tzst

IMAGE_ARM64V8_DOCKERFILE := $(DISTDIR)/Dockerfile.arm64v8
IMAGE_ARM64V8_TARBALL := $(DISTDIR)/$(IMAGE_PROJECT).arm64v8.tzst

IMAGE_ARM32V7_DOCKERFILE := $(DISTDIR)/Dockerfile.arm32v7
IMAGE_ARM32V7_TARBALL := $(DISTDIR)/$(IMAGE_PROJECT).arm32v7.tzst

export DOCKER_BUILDKIT := 1
export BUILDKIT_PROGRESS := plain

@ -53,14 +56,14 @@ $(IMAGE_NATIVE_DOCKERFILE): $(DOCKERFILE_TEMPLATE)
mkdir -p '$(DISTDIR)'
'$(M4)' \
--prefix-builtins \
'$(DOCKERFILE_TEMPLATE)' > '$@'
'$(DOCKERFILE_TEMPLATE)' | cat --squeeze-blank > '$@'
'$(DOCKER)' build $(IMAGE_BUILD_OPTS) \
--tag '$(IMAGE_NAME):$(IMAGE_VERSION)' \
--tag '$(IMAGE_NAME):latest' \
--file '$@' ./

.PHONY: build-cross-images
build-cross-images: build-amd64-image build-arm64v8-image
build-cross-images: build-amd64-image build-arm64v8-image build-arm32v7-image

.PHONY: build-amd64-image
build-amd64-image: $(IMAGE_AMD64_DOCKERFILE)
@ -69,12 +72,12 @@ $(IMAGE_AMD64_DOCKERFILE): $(DOCKERFILE_TEMPLATE)
mkdir -p '$(DISTDIR)'
'$(M4)' \
--prefix-builtins \
--define=CROSS_ARCH=amd64 \
'$(DOCKERFILE_TEMPLATE)' > '$@'
-D CROSS_ARCH=amd64 \
-D CROSS_QEMU=/usr/bin/qemu-x86_64-static \
'$(DOCKERFILE_TEMPLATE)' | cat --squeeze-blank > '$@'
'$(DOCKER)' build $(IMAGE_BUILD_OPTS) \
--tag '$(IMAGE_NAME):$(IMAGE_VERSION)-amd64' \
--tag '$(IMAGE_NAME):latest-amd64' \
--platform linux/amd64 \
--file '$@' ./

.PHONY: build-arm64v8-image
@ -84,12 +87,27 @@ $(IMAGE_ARM64V8_DOCKERFILE): $(DOCKERFILE_TEMPLATE)
mkdir -p '$(DISTDIR)'
'$(M4)' \
--prefix-builtins \
--define=CROSS_ARCH=arm64v8 \
'$(DOCKERFILE_TEMPLATE)' > '$@'
-D CROSS_ARCH=arm64v8 \
-D CROSS_QEMU=/usr/bin/qemu-aarch64-static \
'$(DOCKERFILE_TEMPLATE)' | cat --squeeze-blank > '$@'
'$(DOCKER)' build $(IMAGE_BUILD_OPTS) \
--tag '$(IMAGE_NAME):$(IMAGE_VERSION)-arm64v8' \
--tag '$(IMAGE_NAME):latest-arm64v8' \
--platform linux/arm64/v8 \
--file '$@' ./

.PHONY: build-arm32v7-image
build-arm32v7-image: $(IMAGE_ARM32V7_DOCKERFILE)

$(IMAGE_ARM32V7_DOCKERFILE): $(DOCKERFILE_TEMPLATE)
mkdir -p '$(DISTDIR)'
'$(M4)' \
--prefix-builtins \
-D CROSS_ARCH=arm32v7 \
-D CROSS_QEMU=/usr/bin/qemu-arm-static \
'$(DOCKERFILE_TEMPLATE)' | cat --squeeze-blank > '$@'
'$(DOCKER)' build $(IMAGE_BUILD_OPTS) \
--tag '$(IMAGE_NAME):$(IMAGE_VERSION)-arm32v7' \
--tag '$(IMAGE_NAME):latest-arm32v7' \
--file '$@' ./

##################################################
@ -97,7 +115,7 @@ $(IMAGE_ARM64V8_DOCKERFILE): $(DOCKERFILE_TEMPLATE)
##################################################

define save_image
'$(DOCKER)' save '$(1)' | zstd -T0 > '$(2)'
'$(DOCKER)' save '$(1)' | zstd -T0 -19 > '$(2)'
endef

.PHONY: save-native-image
@ -107,7 +125,7 @@ $(IMAGE_NATIVE_TARBALL): $(IMAGE_NATIVE_DOCKERFILE)
$(call save_image,$(IMAGE_NAME):$(IMAGE_VERSION),$@)

.PHONY: save-cross-images
save-cross-images: save-amd64-image save-arm64v8-image
save-cross-images: save-amd64-image save-arm64v8-image save-arm32v7-image

.PHONY: save-amd64-image
save-amd64-image: $(IMAGE_AMD64_TARBALL)
@ -121,6 +139,12 @@ save-arm64v8-image: $(IMAGE_ARM64V8_TARBALL)
$(IMAGE_ARM64V8_TARBALL): $(IMAGE_ARM64V8_DOCKERFILE)
$(call save_image,$(IMAGE_NAME):$(IMAGE_VERSION)-arm64v8,$@)

.PHONY: save-arm32v7-image
save-arm32v7-image: $(IMAGE_ARM32V7_TARBALL)

$(IMAGE_ARM32V7_TARBALL): $(IMAGE_ARM32V7_DOCKERFILE)
$(call save_image,$(IMAGE_NAME):$(IMAGE_VERSION)-arm32v7,$@)

##################################################
## "load-*" targets
##################################################
@ -139,7 +163,7 @@ load-native-image:
$(call tag_image,$(IMAGE_NAME):$(IMAGE_VERSION),$(IMAGE_NAME):latest)

.PHONY: load-cross-images
load-cross-images: load-amd64-image load-arm64v8-image
load-cross-images: load-amd64-image load-arm64v8-image load-arm32v7-image

.PHONY: load-amd64-image
load-amd64-image:
@ -151,6 +175,11 @@ load-arm64v8-image:
$(call load_image,$(IMAGE_ARM64V8_TARBALL))
$(call tag_image,$(IMAGE_NAME):$(IMAGE_VERSION)-arm64v8,$(IMAGE_NAME):latest-arm64v8)

.PHONY: load-arm32v7-image
load-arm32v7-image:
$(call load_image,$(IMAGE_ARM32V7_TARBALL))
$(call tag_image,$(IMAGE_NAME):$(IMAGE_VERSION)-arm32v7,$(IMAGE_NAME):latest-arm32v7)

##################################################
## "push-*" targets
##################################################
@ -160,9 +189,10 @@ define push_image
endef

define push_cross_manifest
'$(DOCKER)' manifest create --amend '$(1)' '$(2)-amd64' '$(2)-arm64v8'
'$(DOCKER)' manifest create --amend '$(1)' '$(2)-amd64' '$(2)-arm64v8' '$(2)-arm32v7'
'$(DOCKER)' manifest annotate '$(1)' '$(2)-amd64' --os linux --arch amd64
'$(DOCKER)' manifest annotate '$(1)' '$(2)-arm64v8' --os linux --arch arm64 --variant v8
'$(DOCKER)' manifest annotate '$(1)' '$(2)-arm32v7' --os linux --arch arm --variant v7
'$(DOCKER)' manifest push --purge '$(1)'
endef

@ -171,7 +201,7 @@ push-native-image:
@printf '%s\n' 'Unimplemented'

.PHONY: push-cross-images
push-cross-images: push-amd64-image push-arm64v8-image
push-cross-images: push-amd64-image push-arm64v8-image push-arm32v7-image

.PHONY: push-amd64-image
push-amd64-image:
@ -183,6 +213,11 @@ push-arm64v8-image:
$(call push_image,$(IMAGE_NAME):$(IMAGE_VERSION)-arm64v8)
$(call push_image,$(IMAGE_NAME):latest-arm64v8)

.PHONY: push-arm32v7-image
push-arm32v7-image:
$(call push_image,$(IMAGE_NAME):$(IMAGE_VERSION)-arm32v7)
$(call push_image,$(IMAGE_NAME):latest-arm32v7)

push-cross-manifest:
$(call push_cross_manifest,$(IMAGE_NAME):$(IMAGE_VERSION),$(IMAGE_NAME):$(IMAGE_VERSION))
$(call push_cross_manifest,$(IMAGE_NAME):latest,$(IMAGE_NAME):latest)
@ -193,7 +228,7 @@ push-cross-manifest:

.PHONY: binfmt-register
binfmt-register:
'$(DOCKER)' run --rm --privileged docker.io/hectorm/qemu-user-static:latest --reset --persistent yes --credential yes
'$(DOCKER)' run --rm --privileged docker.io/hectormolinero/qemu-user-static:latest --reset

##################################################
## "version" target
@ -201,13 +236,13 @@ binfmt-register:

.PHONY: version
version:
@LATEST_IMAGE_VERSION=$$('$(GIT)' describe --abbrev=0 2>/dev/null || printf 'v0'); \
if printf '%s' "$${LATEST_IMAGE_VERSION:?}" | grep -q '^v[0-9]\{1,\}$$'; then \
NEW_IMAGE_VERSION=$$(awk -v v="$${LATEST_IMAGE_VERSION:?}" 'BEGIN {printf("v%.0f", substr(v,2)+1)}'); \
'$(GIT)' commit --allow-empty -m "$${NEW_IMAGE_VERSION:?}"; \
@if printf '%s' '$(IMAGE_VERSION)' | grep -q '^v[0-9]\{1,\}$$'; then \
NEW_IMAGE_VERSION=$$(awk -v 'v=$(IMAGE_VERSION)' 'BEGIN {printf "v%.0f", substr(v,2)+1}'); \
printf '%s\n' "$${NEW_IMAGE_VERSION:?}" > '$(VERSION_FILE)'; \
'$(GIT)' add '$(VERSION_FILE)'; '$(GIT)' commit -m "$${NEW_IMAGE_VERSION:?}"; \
'$(GIT)' tag -a "$${NEW_IMAGE_VERSION:?}" -m "$${NEW_IMAGE_VERSION:?}"; \
else \
>&2 printf 'Malformed version string: %s\n' "$${LATEST_IMAGE_VERSION:?}"; \
>&2 printf 'Malformed version string: %s\n' '$(IMAGE_VERSION)'; \
exit 1; \
fi

@ -217,6 +252,6 @@ version:

.PHONY: clean
clean:
rm -f '$(IMAGE_NATIVE_DOCKERFILE)' '$(IMAGE_AMD64_DOCKERFILE)' '$(IMAGE_ARM64V8_DOCKERFILE)'
rm -f '$(IMAGE_NATIVE_TARBALL)' '$(IMAGE_AMD64_TARBALL)' '$(IMAGE_ARM64V8_TARBALL)'
rm -f '$(IMAGE_NATIVE_DOCKERFILE)' '$(IMAGE_AMD64_DOCKERFILE)' '$(IMAGE_ARM64V8_DOCKERFILE)' '$(IMAGE_ARM32V7_DOCKERFILE)'
rm -f '$(IMAGE_NATIVE_TARBALL)' '$(IMAGE_AMD64_TARBALL)' '$(IMAGE_ARM64V8_TARBALL)' '$(IMAGE_ARM32V7_TARBALL)'
if [ -d '$(DISTDIR)' ] && [ -z "$$(ls -A '$(DISTDIR)')" ]; then rmdir '$(DISTDIR)'; fi

View File

@ -9,17 +9,13 @@ docker run --detach \
--device /dev/kvm \
--publish 127.0.0.1:5900:5900/tcp \
--publish 127.0.0.1:6080:6080/tcp \
--mount type=volume,src=qemu-reactos-disk,dst=/var/lib/qemu/disk/ \
docker.io/hectorm/qemu-reactos:latest
docker.io/hectormolinero/qemu-reactos:latest
```

> [!NOTE]
> The `--device /dev/kvm` option can only be used on Linux hosts, it can be removed on Windows and macOS hosts at a significant performance penalty.

The instance can be accessed from:
* **VNC** (`5900/TCP`), without password.
* **noVNC** (`6080/TCP`), http://127.0.0.1:6080/vnc.html
* `docker exec -it qemu-reactos vmshell`
* **VNC (5900/TCP):** any VNC client, without credentials.
* **noVNC (6080/TCP):** http://127.0.0.1:6080/vnc.html
* **Shell:** `docker exec -it qemu-reactos vmshell`

## Environment variables
#### `VM_CPU`

1
VERSION Normal file
View File

@ -0,0 +1 @@
v36

0
data/iso/reactos/3rdParty/.gitkeep vendored Normal file
View File

View File

@ -1,11 +1,5 @@
@echo off

:: Install srvany-ng
copy "D:\reactos\3rdParty\srvany-ng.exe" "%SystemRoot%\bin\srvany-ng.exe"

:: Install ncat
copy "D:\reactos\3rdParty\ncat.exe" "%SystemRoot%\bin\ncat.exe"

:: Install Samba
copy "D:\reactos\3rdParty\samba.exe" "%SystemRoot%\bin\samba.exe"
"%SystemRoot%\bin\samba.exe" -s
@ -13,19 +7,13 @@ copy "D:\reactos\3rdParty\samba.exe" "%SystemRoot%\bin\samba.exe"
:: Install BusyBox
copy "D:\reactos\3rdParty\busybox.exe" "%SystemRoot%\bin\busybox.exe"

:: Enable BindShell
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell"
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v DisplayName /t REG_SZ /d "BindShell" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v Description /t REG_SZ /d "Allows remote access" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v ErrorControl /t REG_DWORD /d 1 /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v ImagePath /t REG_EXPAND_SZ /d "srvany-ng.exe" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v ObjectName /t REG_SZ /d "LocalSystem" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v Start /t REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell" /v Type /t REG_DWORD /d 16 /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell\Parameters"
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell\Parameters" /v Application /t REG_SZ /d "%SystemRoot%\bin\ncat.exe" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell\Parameters" /v AppParameters /t REG_SZ /d "-l -k -n -e \"cmd.exe /c (cmd.exe 2^>^&1)\" 51" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BindShell\Parameters" /v AppDirectory /t REG_SZ /d "%SystemDrive%\\" /f
:: Install bind shell service
copy "D:\reactos\3rdParty\ncat.exe" "%SystemRoot%\bin\ncat.exe"
sc create "BindShell" ^
DisplayName= "Bind shell" ^
BinPath= "ncat.exe -l -k -n -e \"cmd.exe /c (cmd.exe 2^>^&1)\" 51" ^
Error= "ignore" ^
Start= "auto"

:: Set UTF-8 encoding in CMD
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor" /v AutoRun /t REG_EXPAND_SZ /d "CHCP 65001" /f

2
run.sh
View File

@ -6,7 +6,7 @@ export LC_ALL=C
DOCKER=$(command -v docker 2>/dev/null)

IMAGE_REGISTRY=docker.io
IMAGE_NAMESPACE=hectorm
IMAGE_NAMESPACE=hectormolinero
IMAGE_PROJECT=qemu-reactos
IMAGE_TAG=latest
IMAGE_NAME=${IMAGE_REGISTRY:?}/${IMAGE_NAMESPACE:?}/${IMAGE_PROJECT:?}:${IMAGE_TAG:?}

View File

@ -2,4 +2,4 @@

set -eu

printf '%s\n' 'system_powerdown' | nc -w 1 -U /run/qemu-monitor
printf '%s\n' 'system_powerdown' | nc -U /run/qemu-monitor

View File

@ -4,11 +4,10 @@ set -eu

set --
set -- "$@" -machine pc -smp "${VM_CPU:?}" -m "${VM_RAM:?}"
set -- "$@" -device VGA -display vnc=:0 -serial stdio -monitor unix:/run/qemu-monitor,server,nowait
set -- "$@" -device e1000,netdev=n0 -netdev user,id=n0,ipv4=on,ipv6=off,net=10.0.2.0/24,host=10.0.2.2,dns=10.0.2.3,dhcpstart=10.0.2.15,hostfwd=tcp::2323-:23,hostfwd=tcp::5151-:51,hostfwd=tcp::3389-:3389,"${VM_NET_EXTRA_OPTIONS?}"
set -- "$@" -device ide-hd,id=disk0,bus=ide.0,drive=disk0 -blockdev driver=qcow2,node-name=disk0,file.driver=file,file.filename=/var/lib/qemu/disk/reactos.qcow2
set -- "$@" -usb -device usb-tablet
set -- "$@" -k "${VM_KEYBOARD:?}"
set -- "$@" -serial stdio -monitor unix:/run/qemu-monitor,server,nowait -device VGA -display vnc=:0
set -- "$@" -device e1000,netdev=n0 -netdev user,id=n0,"${VM_NET_GUESTFWD_OPTIONS?}","${VM_NET_HOSTFWD_OPTIONS?}","${VM_NET_EXTRA_OPTIONS?}"
set -- "$@" -drive file=/var/lib/qemu/image/reactos.qcow2,index=0,media=disk,format=qcow2
set -- "$@" -usb -device usb-tablet -k "${VM_KEYBOARD:?}"

if [ "${VM_KVM:?}" = true ] && [ -c /dev/kvm ]; then
set -- "$@" -accel kvm -cpu host
@ -16,21 +15,14 @@ else
set -- "$@" -accel tcg
fi

cd_i=0
for cd in /var/lib/qemu/cd/*; do
[ -f "${cd:?}" ] || continue
set -- "$@" -device ide-cd,id=cd"${cd_i:?}",bus=ide.1,drive=cd"${cd_i:?}" -blockdev driver=raw,node-name=cd"${cd_i:?}",file.driver=file,file.filename="${cd:?}",read-only=on
cd_i="$((cd_i + 1))"
iso_i=2
for iso in /var/lib/qemu/iso/*; do
[ -f "${iso:?}" ] || continue
set -- "$@" -drive file="${iso:?}",index="${iso_i:?}",media=cdrom,format=raw
iso_i="$((iso_i + 1))"
done

floppy_i=0
for floppy in /var/lib/qemu/floppy/*; do
[ -f "${floppy:?}" ] || continue
set -- "$@" -device floppy,id=floppy"${floppy_i:?}",bus=floppy-bus.0,drive=floppy"${floppy_i:?}" -blockdev driver=raw,node-name=floppy"${floppy_i:?}",file.driver=file,file.filename="${floppy:?}",read-only=on
floppy_i="$((floppy_i + 1))"
done

if [ "${cd_i:?}" -gt 0 ]; then
if [ "${iso_i:?}" -gt 2 ]; then
set -- "$@" -boot order=dc,menu=on,splash-time=5000
fi


View File

@ -2,10 +2,6 @@

set -eu

if [ ! -d /run/samba/ ]; then
install -m 755 -o root -g root -d /run/samba/
fi

cd /run/samba/
exec 2>&1
exec /usr/sbin/smbd --foreground --debug-stdout --debuglevel=3
exec /usr/sbin/smbd --foreground --log-stdout --debuglevel=3