Infrastructure
The whole infrastructure stack is under intensive development, including its integration with Diem. I am turning repeated setup work into reusable C# modules: discover a version, prepare an image, configure machines, operate them and compose services.
Diem provides the product direction for this work. The goal is a software factory Lab with GitLab, GitLab CI and nodes that I can describe in a project such as MyLocalHost.Diem.Lab, tailored precisely to my laptop.
From Versions to a Local Lab
| Operation | Components being developed | Artifact or result |
|---|---|---|
| Discover versions | Alpine.Version, VirtualBox.Version, Wrapper.Versioning | Release metadata, download URLs, checksums or an installed version |
| Prepare images | Packer.Bundle, Packer.Alpine, Packer.Alpine.DockerHost, Packer wrapper | HCL2, answer files, provisioning scripts, then an image when Packer is run |
| Describe machines | Vos configuration, VosFile/Bundle, Alpine contributors | Machine types, instances and provider settings |
| Operate machines | Vos services, Vagrant backend, CLI and PowerShell adapters | Lifecycle operations, events and per-instance results |
| Compose services | DockerCompose.Bundle, Traefik.Bundle, GitLab.DockerCompose, GitLab.Ci.Yaml | Service, routing, Omnibus and CI configuration |
These are implemented pieces of an integration still being built. The complete machine-specific Lab lifecycle remains the convergence target. Product presentation · Lab architecture.
Alpine.Version
Alpine.Version queries the Alpine CDN and parses release information, with filters for versions, architectures, flavors and release candidates. Its results carry download information and checksums. HTTP access uses the FrenchExDev abstraction; discovery uses asynchronous parallel processing.
For a configured IHttpClient httpClient, the implemented search and builder signatures support this excerpt:
using FrenchExDev.Net.Alpine.Version;
var searcher = new AlpineVersionSearcher(httpClient);
var releases = await searcher.SearchAsync(filters => filters
.WithMinimumVersion("3.18.0")
.WithArch(AlpineArchitectures.x86_64)
.WithFlavor(AlpineFlavors.Standard)
.WithRc(false));using FrenchExDev.Net.Alpine.Version;
var searcher = new AlpineVersionSearcher(httpClient);
var releases = await searcher.SearchAsync(filters => filters
.WithMinimumVersion("3.18.0")
.WithArch(AlpineArchitectures.x86_64)
.WithFlavor(AlpineFlavors.Standard)
.WithRc(false));The minimum version is an example filter. Multiple architectures use WithArchs(List<AlpineArchitectures>); multiple flavors use WithFlavors(List<AlpineFlavors>). Discovery depends on the CDN responses and parsing behavior, and has not been run for this update. Source (ouvre dans une nouvelle fenêtre).
VirtualBox.Version
IVirtualBoxSystemVersionDiscoverer describes local version discovery. Its concrete implementation invokes VBoxManage --version and parses the result into VirtualBoxVersionRecord. The family also defines version-information search contracts.
A call to new VirtualBoxSystemVersionDiscoverer().DiscoverAsync() therefore requires VBoxManage on the process path and a version output format the parser understands. This supplies host metadata for image and VM configuration. Source (ouvre dans une nouvelle fenêtre).
Packer.Alpine (FrenchExDev.Net.Packer.Alpine)
Packer.Alpine contributes unattended installation answers, Alpine setup scripts, Vagrant SSH configuration and image-building settings. It uses Packer.Bundle to collect configuration and companion files.
Packer.Alpine.DockerHost adds Docker installation and service setup. This composition comes directly from DockerContributorTests:
using FrenchExDev.Net.Packer.Alpine;
using FrenchExDev.Net.Packer.Alpine.DockerHost;
using FrenchExDev.Net.Packer.Bundle;
var bundle = new PackerBundle();
bundle.Apply(
new AlpineBaseContributor(),
new DockerContributor());using FrenchExDev.Net.Packer.Alpine;
using FrenchExDev.Net.Packer.Alpine.DockerHost;
using FrenchExDev.Net.Packer.Bundle;
var bundle = new PackerBundle();
bundle.Apply(
new AlpineBaseContributor(),
new DockerContributor());The tests inspect required plugins, variables, source blocks and ordered scripts, including apk add docker, Compose tooling and OpenRC setup. Materializing the bundle produces inputs for Packer; building an image additionally needs Packer, its plugins, the ISO and the selected hypervisor.
Alpine source and tests (ouvre dans une nouvelle fenêtre) · Docker host source and tests (ouvre dans une nouvelle fenêtre) · Packer command wrapper.
Vos (FrenchExDev.Net.Vos)
Vos separates configuration from machine operations. VosVmService reads a configuration through IVosFileReader, creates an orchestrator, resolves target instances and delegates operations to IVosBackend. The repository includes configuration and file handling, a Vagrant adapter, CLI and C# PowerShell integrations, and VosFile/Bundle projects.
The IVosVmService contract exposes status, start/stop, provisioning, SSH, upload and snapshot operations. VosVmServiceTests supplies a fake file reader and backend, then exercises calls such as:
// Excerpt inside VosVmServiceTests, after its fixture setup.
_reader.SetConfig("c.yaml", CreateConfig());
var started = await _svc.UpAsync("c.yaml", "main-01");
var statuses = await _svc.StatusAsync("c.yaml");// Excerpt inside VosVmServiceTests, after its fixture setup.
_reader.SetConfig("c.yaml", CreateConfig());
var started = await _svc.UpAsync("c.yaml", "main-01");
var statuses = await _svc.StatusAsync("c.yaml");A successful outer Result means the service returned the list; each item's VosActionResult.Success must also be inspected. The tests explicitly exercise a backend failure inside a successful outer result, as well as lifecycle events and missing configuration.
Vos.Alpine
AlpineVirtualBoxContributor contributes an Alpine box, VirtualBox provider settings, VBoxManage options and Vagrant plugins. Tests examine these settings and preservation of an explicitly supplied box name. Source (ouvre dans une nouvelle fenêtre).
Vos.Alpine.DockerHost
DockerHostContributor layers Docker host configuration and provisioning onto the Alpine machine model. It is the machine-configuration counterpart to the Packer image contribution. Source (ouvre dans une nouvelle fenêtre).
Vos source and tests (ouvre dans une nouvelle fenêtre) · Existing PowerShell automation.
Service Composition and Diem
The service layer combines several outputs: Compose describes containers, Traefik describes routing, GitLab.DockerCompose renders Omnibus settings, and GitLab.Ci.Yaml describes pipelines. Their configuration APIs develop alongside the wrappers that operate the underlying tools.
The intended product workflow is to describe a Lab, generate its configurations, prepare the selected nodes, then operate GitLab and CI services through that composition. In the proposed Diem architecture, the Lab is mandatory; exposure, authentication and authorization are configurable.
MyLocalHost.Diem.Lab is the concrete destination: my own C# project describing a software factory that fits and runs on my laptop. The current components and PowerShell Kubernetes scripts are steps toward that destination; an integrated C# lifecycle for the whole Lab is still being developed. Product, usages and specification.
Source review: 9 September 2026. The cited tests were inspected; no VM, image build or service deployment was run for this documentation update.