System reference
Most installations do not need anything on this page. Use it when preparing managed, offline, minimal or hardware-connected machines, or when diagnosing an environment-specific issue.
Operating systems
Orcraft supports Windows, Linux and macOS. Every release is built for Windows x64, Linux x86_64, Linux ARM64 and macOS on Apple silicon and Intel, one wheel per platform, and pip installs the one for the machine. It has been validated in these environments:
| OS | Version | Kernel / build | Architecture |
|---|---|---|---|
| Windows | 11 | build 26200 | x86_64 |
| Windows | 10 | build 19045 | x86_64 |
| Ubuntu | 24.04 | kernel 6.17 and 7.0 | x86_64 |
| macOS | 26.2 | Darwin 25.2.0 | arm64 |
Other versions and architectures - arm64 Linux, Windows on Arm, Intel Macs - are expected to work wherever Python and PySide6 are available; they simply have not been through the validation matrix above yet.
Windows 10 left mainstream support in October 2025, but it stays in the matrix on purpose: lab and instrument machines often cannot be upgraded, and endpoints run on it perfectly well.
The controller GUI's best experience is on Windows. It needs a desktop session to run. Endpoints have no GUI, so they can run headless - on a server or over SSH.
Linux desktop libraries (controller only)
Desktop Linux installations already include the Qt libraries used by the controller. Use these
commands only on a minimal image where startup fails with
Could not load the Qt platform plugin "xcb". Endpoints have no GUI and need none of
these packages.
| Distribution | Command |
|---|---|
| Debian, Ubuntu | sudo apt install libgl1 libxkbcommon-x11-0 libxcb-cursor0 |
| Fedora, RHEL | sudo dnf install mesa-libGL libxkbcommon-x11 xcb-util-cursor |
First start after an install
The first start of the controller or the endpoint application after an install or an update takes longer: the operating system checks the newly installed code before it runs. The package's compiled code is one file, so the check is paid once: on Windows, Microsoft Defender takes a few seconds on a desktop and up to about half a minute on a small virtual machine; macOS takes about ten seconds; antivirus software on any operating system does the same. The terminal says so and counts the wait. Every later start is immediate.
Endpoint connectivity
What Orcraft opens on the network and how the controller finds an endpoint. Use it to plan
firewall rules, choose ports and addresses on machines with several interfaces, and decide whether
endpoints are added by name or by IP address. The endpoint's -port and
-ip options are given on its command line, in the same way as on
Adding endpoints/Run the endpoint.
Ports, addresses and names
| Endpoint port | TCP 50051 by default; configurable with -port. The controller must be given
the same port when the endpoint is added |
|---|---|
| Endpoint applications per machine | A controller registers each machine once. A second copy of the endpoint application on another port lets another controller use the same machine - see Several endpoint applications on one machine below |
| Address families | The endpoint listens dual-stack, IPv4 and IPv6; restrict it to one address with
-ip (-bind is an alias). The controller's reachability ping is
IPv4-only, so an endpoint reachable only over IPv6 shows as Offline |
| Controller | Outbound connections only; no inbound controller rule |
| Discovery | No broadcast, multicast or discovery ports of its own. Host-name lookups go through the
operating system's resolver, including its mDNS (.local) fallback |
| Host names | Optional - endpoints can be added by IP address. A DNS record or local
hosts entry works when names are preferred; a name absent from DNS is also tried
as name.local - see
Hosts with more than one address and
Stale name lookups below |
Commands
Commands that follow from the table:
| Show every option | orcraft-endpoint - run without a subcommand, the endpoint prints its help
and exits |
|---|---|
| Listen on another port | orcraft-endpoint run -port 50052 |
| Listen on one address only | orcraft-endpoint run -ip 10.100.102.73 |
| Name without a DNS record (Windows) | Add a line to C:\Windows\System32\drivers\etc\hosts |
| Name without a DNS record (macOS, Linux) | Add a line to /etc/hosts |
For the firewall steps needed by remote endpoints, see Prerequisites/Remote endpoints.
Host-name resolution
An endpoint added by host name is resolved on the machine that runs the controller, by that
machine's own resolver: its DNS server, its hosts file and, on most systems, mDNS
(name.local) as a fallback. The controller pings the name, then name.local,
then the last address it knew. A name that works from one PC can therefore fail from another, and
the place to check is always the controller's machine. Ping the name there; the first line of the
output shows which address the name resolved to:
| Windows | ping -4 ENDPOINT-HOST |
|---|---|
| macOS | ping -c 1 ENDPOINT-HOST |
| Linux | ping -4 -c 1 ENDPOINT-HOST |
Hosts with more than one address
A machine connected by both Ethernet and Wi-Fi has two IPv4 addresses, and a name lookup can return either of them. The controller and the endpoint talk over whichever address answers, but the address shown on the card is the one the controller's last lookup returned, so it can differ from one lookup to the next. When one of the interfaces is disconnected, the name can keep resolving to that interface's address until the cached answer expires, and the card shows Offline while the machine is reachable on its other address. To hold a host to one address, add the endpoint by IP address instead of by name, or keep only one of its interfaces on the network the controller uses.
Stale name lookups
Resolvers cache their answers. After an endpoint machine changes address, disconnects an interface or is renamed, the controller's machine can keep pinging the old address for minutes. Flush the cache on the controller's machine, then wait for the card's next poll:
| Windows | ipconfig /flushdns |
|---|---|
| macOS | sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder |
| Linux (systemd-resolved) | resolvectl flush-caches |
On Windows, ping counts a "Destination host unreachable" reply from the controller's own machine as an answer, so a stale address can show the card as Online rather than Offline. The flush applies in the same way.
IPv6 link-local answers
Some resolvers return an IPv6 link-local address (fe80::…) ahead of the IPv4 one;
a plain ping of the name shows it in the first line. Such an address is tied to one network interface
of the controller's machine and stops working when that machine moves between Wi-Fi and Ethernet.
If connections to an endpoint are unstable while its name resolves that way, add the endpoint by its
IPv4 address.
Several endpoint applications on one machine
The endpoint application is the program started with orcraft-endpoint run. One
running copy listens on one port. A machine normally runs one copy, and the controller registers
that machine as one endpoint.
Each machine is added once
A controller registers a machine as one endpoint. If the machine is already in the Endpoints frame, adding it again is refused, even with a different port.
Several tests can still use the same machine. By default, runs wait for each other on that
endpoint. If tests may run on the machine at the same time, set the
shared
option on the endpoint field in the test.
A second endpoint application for another controller
A machine can run a second copy of the endpoint application on another port, so that another controller can use the machine. Each controller then talks to its own endpoint application. The two controllers work independently, and packages uploaded through one endpoint application do not affect the other.
Start the second copy with a port of its own, and register it in the second controller with that port:
orcraft-endpoint run -port 50052
Use this only when the tests of the two controllers do not compete for the same resource on the
machine, such as a device, a port or a file. If they do, register the same endpoint application in
both controllers instead. Runs from both controllers then wait for each other, or run at the same
time when the test marks the endpoint shared.
Both copies report the same host name to the controller. The Info dialog of an endpoint shows its Port, which tells the two copies apart.
Requirements for a second endpoint application
The endpoint application keeps its files under the directory it was started from and in the Python environment it was installed in. A second copy therefore needs the following:
| Its own port | A port that is already in use is refused at startup |
|---|---|
| Its own launch directory | The endpoint application writes its Logs under the directory it was started
from, so start each copy from a different directory. Received packages are unpacked under
.orcraft/packages in the user's home directory, in a folder named after the
port, so each copy keeps its own |
| Its own installation, to update independently | An update from the controller reinstalls the endpoint application into the Python environment it runs from, and restarts only that copy. If two copies run from the same installation, both receive the new version, but the second one keeps running the old code until it is restarted. Install each copy in its own virtual environment to update them independently |
| Its own start | orcraft-endpoint startup registers one auto-start entry. Running it again for
a second port replaces the first entry. Start the second copy by hand or with your own
scheduler |
| A machine other than the controller's | The controller refuses to add localhost, 127.0.0.1 or
::1, because it already has a built-in local endpoint |
Security material
The authorization token and the certificates are stored once per machine. All copies of the endpoint application on the machine use the same ones.
Endpoints reached through SSH
An endpoint added with Connect through SSH
(Adding endpoints/Connecting an endpoint via SSH) is
reached through a tunnel the controller opens with the ssh client of its own computer. The
controller only supervises that client: it starts it, notices when it exits and starts it again after a
pause that grows from a few seconds to half a minute, and turns its last words into the sentence the
card shows.
| On the controller's computer | An OpenSSH client on PATH (ssh), with a key pair. Windows 10 and later,
macOS and desktop Linux ship one. The client runs in batch mode, so it never prompts: a host that
wants a password fails at once with a message saying a key is needed, and Install SSH
Key on the card's menu puts the public key there. The user's ~/.ssh/config,
agent and known_hosts apply; a host seen for the first time is accepted and
recorded, a host whose key changed is refused |
|---|---|
| On the SSH host | An SSH server that allows TCP forwarding (AllowTcpForwarding is on by default) and
accepts the key. The host may be the endpoint machine itself or a bastion that can reach the
endpoint's port |
| The tunnel | One ssh -N -L 127.0.0.1:<local port>:<endpoint>:<port> per card,
with keep-alives, a ten-second connect deadline and ExitOnForwardFailure, started
when the card is created and stopped when it is removed. The local port is one the operating
system hands out, shown in the card's Info as SSH Tunnel. The
endpoint's host name or address is resolved on the SSH host, not here |
| Ping | Not used for a tunnelled card: Offline means the tunnel is down, and the status pill's tooltip carries the reason |
Permissions and storage
Orcraft itself does not require administrator or root access.
| Controller and endpoint | Run as the logged-in user - no elevation or system service required |
|---|---|
| Profile data | Security material and downloaded wheels use %APPDATA%\Orcraft, or
~/.orcraft elsewhere |
| Working directory | The controller writes Logs, Sessions, Reports,
Results_Export and Endpoints where it was launched; endpoints unpack received packages there too. Launch from a writable
directory |
| Listening port | Non-privileged by default; any port above 1023 needs no elevation |
| Test steps | Inherit the endpoint user's rights. Hardware tests may need additional device permissions or an elevated endpoint session |
Shells and terminals
Terminal output
The endpoint and test framework use ANSI colors and Unicode box-drawing characters.
| Terminal | Colored output |
|---|---|
| Windows Terminal, PowerShell 7 | Works as-is |
| Windows legacy console (conhost) | May print raw codes such as ←[92m - see below |
| macOS Terminal.app, iTerm2 | Works as-is |
| Linux emulators - gnome-terminal, konsole, xfce4-terminal, kitty, alacritty, xterm | Works as-is |
If a Windows console shows raw escape sequences, use Windows Terminal or enable virtual-terminal processing once for the current user:
reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1
If box-drawing characters appear as ?, use Windows Terminal or run
chcp 65001 in the classic console. The controller GUI renders output itself and is
unaffected.
Log files
Runs are saved as .ansi files with their colors embedded.
| Reading a saved log | How |
|---|---|
| Controller | Renders logs directly in its GUI and opens saved .ansi files |
| Linux, macOS | cat or less -R to scroll with colors intact |
| Windows | Get-Content in Windows Terminal |
| Text editors | Show the escape codes unless the editor understands ANSI |
Endpoint environment
A program that a test starts inherits the environment of the endpoint application. If a test
needs a variable on the endpoint machine, such as a tool path or a display setting for a graphical
program, define it where the auto-started endpoint reads its environment, then restart the
endpoint. The example below defines MY_TOOL_HOME; replace the name and value with
your own.
Windows
The Task Scheduler task starts the endpoint executable directly, so the variable must be in the account's environment. Define it once from a command prompt:
setx MY_TOOL_HOME C:\Tools\MyTool
Then stop the endpoint with Ctrl+C in its console window, close the window, and sign out and in again. The task starts the endpoint at logon with the new variable.
Linux
The systemd user service opens the endpoint in an interactive bash shell, which reads
~/.bashrc. Add the variable there and start the service again:
echo 'export MY_TOOL_HOME=/opt/mytool' >> ~/.bashrc
systemctl --user start orcraft-endpoint
Stop the running endpoint first with Ctrl+C in its terminal window and close the window, otherwise the new instance finds the port in use.
macOS
The launch agent opens the endpoint in Terminal.app, whose login shell reads
~/.zshrc. Add the variable there and start the agent again:
echo 'export MY_TOOL_HOME=/opt/mytool' >> ~/.zshrc
launchctl kickstart -k gui/$(id -u)/com.orcraft.endpoint
Stop the running endpoint first with Ctrl+C in its Terminal window and close the window.
The same files apply to the restart the endpoint performs after an update from the controller.
An endpoint launched by hand from a terminal uses that terminal's environment instead, so a
variable exported in that terminal before orcraft-endpoint run also works.
Python libraries
pip installs these libraries automatically along with the orcraft package.
| Library | Used for |
|---|---|
| PySide6 | The controller's GUI |
| grpcio, protobuf | RPC communication between the controller and its endpoints |
| cryptography | mTLS and token-based security |
Packages a suite needs on top of these, for a tool it drives or a protocol it speaks, come from the
suite's requirements.txt: the controller installs them into the endpoint application's
Python when it uploads the suite. See
Suite requirements.
Optional integrations
Internet access
Connected machines install with pip install orcraft; isolated machines install from
a copied wheel file. Test traffic stays on your own network. Two controller conveniences make
outbound calls and fail quietly when unavailable:
| Call | When | Reaches | If unavailable |
|---|---|---|---|
| Update check | Controller startup | pypi.org |
Reported as failed; nothing downloads or installs without user action |
| Suite repository status | A Git-backed suite is added | That repository's remote | Status shown as unavailable |
Git
Only needed for suites kept in Git repositories. Archive-based suites skip this integration.
| Needs | git on the controller's PATH and access to the repository remote |
|---|---|
| Behavior | Checks remote status in the background and offers a fast-forward pull; never prompts for credentials or blocks a run |
| If unavailable | Repository status is unavailable; the suite still works |
Installing for the first time? Start with Prerequisites, then Getting started.