Skip to content

About

OneWare Studio plugin that runs FPGA toolchains (GHDL, Yosys, nextpnr, gmpack, Icarus, Verilator, SymbiYosys) inside containers without changing the user's workflow.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

442 Commits

Folders and files

Repository files navigation

OneWare Container Extension

Build License: MIT .NET 10

A OneWare Studio plugin that runs FPGA toolchains (GHDL, Yosys, nextpnr, gmpack, Icarus, Verilator, SymbiYosys) inside containers without changing the user's workflow. It plugs into OneWare's pluggable tool-execution strategy, maps the project into a container, runs the tool there with its paths mapped into the container, and streams output back to the IDE, so a build behaves identically across machines with no host toolchain install.

Developed as part of the Master's thesis Design and Implementation of a Modular Architecture for the Transparent Integration of Containerized Execution Environments for Heterogeneous Open-Source Binaries in OneWare Studio by Mert Torun at TH Köln (2026), openly available at https://doi.org/10.57683/EPUB-3597. The code has changed since the thesis was submitted.

Icon

Installation

  • From OneWare Studio: open Extras > Extensions, search for "Container Extension", and install. On OneWare Studio before 1.0.43, restart it once, so that the Container Dashboard's tab and menu entry appear. If the search finds nothing, add the extension's manifest as a package source first; the getting-started guide gives the link. The plugin ships as a managed net10.0 assembly; OneWare provides the runtime.
  • Side-load a local build: publish the plugin and copy it into the OneWare plugins directory (~/OneWareStudio/Packages/Plugins/ on Linux/macOS). See docs/articles/getting-started.md.

OneWare Studio 1.0.45 or later is required; the plugin is built against OneWare.Essentials 1.0.45 and implements the tool-execution strategy interface that OneWare introduced in 1.0.40. A running container engine (Docker, Podman, OrbStack, or Colima) is required for containerized execution. Containerized runs use the toolchain image fentwums/oss-cad-suite:latest, which is on no registry: build it once with Build Local Image in the Container Dashboard, or with docker/build_oss_cad_suite.sh.

Repository layout

Each top-level directory carries its own README with the detail; this is the map.

Path Contents
src/ The plugin assemblies. ContainerExtension is the core: IToolExecutionStrategy/DockerExecutionStrategy, the registry client, settings, telemetry, and the Avalonia Docker dashboard (net10.0, IsAotCompatible, source-generated JSON and regex).
tests/ ContainerExtension.UnitTests (xUnit: validators, command building, path mapping, telemetry, registry parsing, SSRF guards, plus gated container E2E).
docker/ Build inputs for the hardened fentwums/oss-cad-suite toolchain image: the digest-pinned Dockerfile, build_oss_cad_suite.sh, and pull_all_images.sh.
docs/ DocFX site sources — prose guides under articles/ and the generated API reference. See Documentation to build and view the HTML.

The runtime design (the execution-strategy integration, the container lifecycle, the hybrid fallback) is summarized under Execution model and detailed in docs/articles/architecture.md.

Execution model

The plugin coordinates execution through a hybrid strategy:

---
config:
  flowchart:
    wrappingWidth: 400
---
flowchart TD
    A[OneWare runs an FPGA tool] -->|dispatches to the selected<br/>IToolExecutionStrategy| B[DockerExecutionStrategy]
    B --> C{Container engine<br/>reachable?}
    C -->|yes| D[Resolve image<br/>env var → per-call → per-tool →<br/>plugin → default → built-in fallback]
    D --> E[Map project into /workspace<br/>host UID/GID via --user,<br/>not on Windows or rootless<br/>cap-drop ALL · no-new-privileges<br/>PID cap]
    E --> F[Run the tool<br/>in the container<br/>tini as PID 1]
    C -->|no, native fallback enabled| G[Run the tool<br/>from the host PATH]
    C -->|no, fallback disabled| H[Fail: daemon<br/>unreachable]
    F --> I[Stream stdout/stderr to the IDE<br/>with the tool's exit code]
    G --> I
    I --> J[Record JSON Lines telemetry<br/>at the configured level]
Loading
  • Containerized (opt-in per tool): each tool's Execution Strategy setting defaults to native; selecting the Docker strategy routes that tool through a container, which pulls and runs the toolchain image, pinning the container process to the host UID/GID via --user so output files are not root-owned. On rootless runtimes and on Windows hosts --user is left out and the image's default user applies, oneware in the toolchain image. tini runs as PID 1 to reap children and forward signals.
  • Native fallback: if the daemon is unreachable and Allow Native Fallback is enabled, the tool is located on the host PATH and run natively so work is not blocked.
  • Telemetry: execution records are written as JSON Lines with a configurable level (Off, Errors Only, Info, Verbose) and retention. See docs/articles/telemetry.md.

Security

  • Containers run as the host UID/GID via --user, except on rootless runtimes and Windows hosts, where the image's default user applies (oneware in the toolchain image); tini as PID 1. Every container drops all capabilities (--cap-drop=ALL), forbids privilege escalation (--security-opt no-new-privileges), and caps the task count as a fork-bomb backstop.
  • Host paths that escape the mounted workspace are remapped to an in-workspace sentinel rather than their real location; an explicit device/library allowlist is the only pass-through. The behaviour is pinned by an adversarial path-containment test corpus that runs in CI.
  • A mount deny list rejects binds of critical host paths (/etc, /proc, /sys, /run, the Docker socket, …); on Linux a project on a removable drive under /run/media/, where udisks2 mounts it, may be bound.
  • The registry client uses HTTPS, and plain HTTP only for a registry named as localhost or a loopback address; it scopes forwarded credentials to the matching host and rejects any other host name that resolves to a loopback or internal address (SSRF defense).
  • Supply chain: NuGetAudit, an SBOM and OIDC build attestations on releases, and CodeQL plus Trivy scans in CI. The runtime image pins its base by digest and verifies the toolchain tarball against a committed SHA-256 (fail-closed); image integrity is anchored on these committed digests and the per-run recorded image digest. Provenance is TLS-trusted, not yet cosign-signed.

Supported container runtimes

Runtime Endpoint Notes
Docker /var/run/docker.sock, ~/.docker/run/docker.sock; on Linux also ~/.docker/desktop/docker.sock (Docker Desktop) and /run/user/{uid}/docker.sock (rootless) Probed first
Podman /run/user/{uid}/podman/podman.sock, podman-machine Rootless
OrbStack / Colima per-runtime sockets Probed via a priority list
Custom Custom Daemon Socket setting Overrides probing

On Windows the daemon is reached over the named pipe; the connection path is validated before use.

Building and testing

git clone --recurse-submodules https://github.com/FEntwumS/FEntwumS.ContainerExtension.git
cd FEntwumS.ContainerExtension

dotnet format OneWare.ContainerExtension.slnx --verify-no-changes
dotnet build  OneWare.ContainerExtension.slnx -warnaserror -c Release
dotnet test   OneWare.ContainerExtension.slnx -c Release

The container E2E tests are skipped in CI (Docker Hub rate limits and image-pull flakiness). What they need to run locally is listed under Running the container tests.

Documentation

Prose guides live under docs/articles: getting started, configuration, architecture, telemetry, and limitations. The full site bundles those guides with an API reference generated from the source by DocFX:

dotnet tool install -g docfx     # once
docfx docs/docfx.json --serve    # build and serve at http://localhost:8080

docfx docs/docfx.json (omitting --serve) regenerates the API metadata and produces the static HTML under docs/_site/. The bare docfx build subcommand skips metadata generation, so run the full command above for a complete site with the API reference.

Citation

If you use this software, cite it via CITATION.cff.

License

MIT © 2025–2026 Mert Torun

About

OneWare Studio plugin that runs FPGA toolchains (GHDL, Yosys, nextpnr, gmpack, Icarus, Verilator, SymbiYosys) inside containers without changing the user's workflow.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages