Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
85 changes: 85 additions & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Docker Integration Tests

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

jobs:
docker-integration:
name: Docker Integration Tests
runs-on: ubuntu-latest
strategy:
matrix:
arch: [amd64] # arm64 works but is very slow
fail-fast: false

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
install: true

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64

- name: Create libvirt directories
run: |
sudo mkdir -p /var/run/libvirt
sudo mkdir -p /var/lib/libvirt
sudo chmod -R 777 /var/run/libvirt
sudo chmod -R 777 /var/lib/libvirt

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static

- name: Build and run tests
run: |
# Create test artifacts directory
mkdir -p test-artifacts

# Build the Docker image with GitHub Actions cache
docker buildx build \
--platform linux/${{ matrix.arch }} \
--build-arg BASE_IMAGE=node:20-slim \
-t libvirt-test-${{ matrix.arch }} \
--cache-from type=gha \
--cache-to type=gha,mode=max \
--load \
.

# Run the container with necessary privileges
docker run \
--platform linux/${{ matrix.arch }} \
--privileged \
-v /var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock \
-v /var/lib/libvirt:/var/lib/libvirt \
-v $(pwd)/test-artifacts:/app/test-artifacts \
--name test-container \
libvirt-test-${{ matrix.arch }}

# Copy coverage data from the container
docker cp test-container:/app/coverage ./coverage
docker rm test-container

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-report-${{ matrix.arch }}
path: coverage/
retention-days: 14
9 changes: 6 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Cache APT Packages
uses: awalsh128/cache-apt-pkgs-action@v1.4.3
with:
packages: libvirt-dev
packages: libvirt-dev qemu-system qemu-user-static
version: 1.0

- name: Set Node.js
Expand Down Expand Up @@ -72,8 +72,11 @@ jobs:
- name: Build
run: pnpm run build

- name: test
run: pnpm run test
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
install: true


- name: Setup NPM Authentication
if: ${{ needs.release-please.outputs.release_created }}
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@
*.tgz

# tsbuildinfo
tsconfig.tsbuildinfo
tsconfig.tsbuildinfo

# coverage
coverage

test-artifacts/
91 changes: 85 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,90 @@
FROM node:22-bookworm-slim AS development
# Install build tools
RUN apt-get update -y && apt-get install -y \
# Build stage
FROM node:20-slim AS builder

# Prevent interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive

# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
python3 \
libvirt-dev \
jq
&& rm -rf /var/lib/apt/lists/*

# Set up the build environment
WORKDIR /app

# Copy package files first to leverage caching
COPY package*.json ./
COPY pnpm-lock.yaml ./

# Install pnpm globally using npm
RUN npm install -g pnpm@latest
# Install pnpm and dependencies
RUN npm install -g pnpm && \
pnpm install --frozen-lockfile

# Copy source files
COPY . .

# Build the project
RUN pnpm run build

# Test stage
FROM node:20-slim AS test

# Prevent interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive

# Install test dependencies
RUN apt-get update && apt-get install -y \
build-essential \
python3 \
qemu-system-x86 \
qemu-system-arm \
qemu-efi \
qemu-efi-aarch64 \
qemu-utils \
ovmf \
libvirt-daemon-system \
libvirt-dev \
&& rm -rf /var/lib/apt/lists/*

# Create a non-root user for libvirt and set up permissions
RUN useradd -m -s /bin/bash -g libvirt libvirt && \
usermod -aG kvm libvirt && \
mkdir -p /var/run/libvirt && \
chown root:libvirt /var/run/libvirt && \
chmod g+w /var/run/libvirt

# Set up the test environment
WORKDIR /app

# Copy package files and install all dependencies (including dev)
COPY package*.json ./
COPY pnpm-lock.yaml ./
RUN npm install -g pnpm && \
pnpm install --frozen-lockfile

# Copy built files and test files from builder stage
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/lib ./lib
COPY --from=builder /app/__tests__ ./__tests__
COPY --from=builder /app/vitest.config.ts ./vitest.config.ts
COPY --from=builder /app/build ./build

# Set up libvirt configuration
RUN mkdir -p /etc/libvirt && \
echo 'unix_sock_group = "libvirt"' >> /etc/libvirt/libvirtd.conf && \
echo 'unix_sock_rw_perms = "0770"' >> /etc/libvirt/libvirtd.conf && \
echo 'auth_unix_rw = "none"' >> /etc/libvirt/libvirtd.conf

# Create necessary directories with correct permissions
RUN mkdir -p /home/libvirt/.config/libvirt && \
echo 'uri_default = "qemu:///session"' > /home/libvirt/.config/libvirt/libvirt.conf && \
chown -R libvirt:libvirt /home/libvirt/.config && \
chown -R libvirt:libvirt /app

# Switch to non-root user
USER libvirt

# Start libvirtd and run tests
CMD ["/bin/sh", "-c", "/usr/sbin/libvirtd --daemon && sleep 2 && pnpm test:coverage"]
84 changes: 71 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@

![Alpha badge][alphabadge]
![CI badge][cibadge]
![Tests badge][testsbadge]
![Codecov badge][codecovbadge]
![License badge][licensebadge]
![Contributors badge][contribadge]
![Issues badge][issuesbadge]
![PR badge][prbadge]
![NPM Version][npmbadge]
![Last Update][lastcommitbadge]

Libvirt bindings for Node.js®.

Expand Down Expand Up @@ -77,7 +81,7 @@ const hypervisor = new libvirt.Hypervisor({ uri });
### Debian / Ubuntu

```bash
sudo apt install build-essential libvirt-dev
sudo apt install build-essential libvirt-dev qemu-system
npm i @unraid/libvirt
```

Expand All @@ -86,21 +90,71 @@ npm i @unraid/libvirt
Install Homebrew and Xcode first if not already installed.

```bash
brew install libvirt
brew install libvirt qemu
npm i @unraid/libvirt
```

## Development

This project uses pnpm as the package manager. Make sure you have it installed:

```bash
npm install -g pnpm
```

### Building

```bash
pnpm install
pnpm build
```

### Testing

The project uses Vitest for testing. You can run tests using:

```bash
# Run tests
pnpm test

# Run tests with coverage
pnpm test:coverage

# Run tests with UI
pnpm test:ui
```

### Examples

The project includes several example scripts that demonstrate different features:

```bash
# List all domains
pnpm examples/list

# Start a domain
pnpm examples/start

# Shutdown a domain
pnpm examples/shutdown

# Create a domain using the builder pattern
pnpm examples/builder
```

## Contribute

Any contribution is welcome! To check wether your contribution conforms our style guide run the following tasks:
Any contribution is welcome! To check whether your contribution conforms to our style guide, run the following tasks:

```bash
pip install cppcheck # required once
git submodule update --init --recursive # required once
# Install dependencies
pnpm install

# Run linting
pnpm lint

pnpm run lint/bindings
pnpm run lint/lib
pnpm run lint/examples
# Run tests
pnpm test
```

---
Expand Down Expand Up @@ -129,8 +183,12 @@ SOFTWARE.

[cover]: cover.png "Cover image"
[alphabadge]: https://img.shields.io/badge/-alpha-green "Alpha badge"
[licensebadge]: https://img.shields.io/github/license/vmngr/libvirt "License badge"
[cibadge]: https://github.com/vmngr/libvirt/workflows/CI/badge.svg "CI badge"
[contribadge]: https://img.shields.io/github/contributors/vmngr/libvirt "Contributors badge"
[issuesbadge]: https://img.shields.io/github/issues/vmngr/libvirt "Issues badge"
[prbadge]: https://img.shields.io/github/issues-pr/vmngr/libvirt "PR badge"
[licensebadge]: https://img.shields.io/github/license/unraid/libvirt "License badge"
[cibadge]: https://github.com/unraid/libvirt/workflows/CI/badge.svg "CI badge"
[testsbadge]: https://img.shields.io/github/actions/workflow/status/unraid/libvirt/integration-test.yml?label=tests "Tests badge"
[codecovbadge]: https://codecov.io/gh/unraid/libvirt/branch/main/graph/badge.svg "Codecov badge"
[contribadge]: https://img.shields.io/github/contributors/unraid/libvirt "Contributors badge"
[issuesbadge]: https://img.shields.io/github/issues/unraid/libvirt "Issues badge"
[prbadge]: https://img.shields.io/github/issues-pr/unraid/libvirt "PR badge"
[npmbadge]: https://img.shields.io/npm/v/@unraid/libvirt "NPM Version badge"
[lastcommitbadge]: https://img.shields.io/github/last-commit/unraid/libvirt "Last Commit badge"
Loading
Loading