feat: flake inputs/outputs and settings.nix entry point
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
7d26ef84f1
commit
d37ac719d3
3 changed files with 3083 additions and 0 deletions
575
flake.nix
Normal file
575
flake.nix
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
{
|
||||
description = "Omnixient - NixOS configuration for modern development";
|
||||
|
||||
inputs = {
|
||||
# Nixpkgs
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||
|
||||
# True bleeding-edge nixpkgs-unstable channel. omni's primary
|
||||
# `nixpkgs` is nixos-unstable (tested unstable); this is the
|
||||
# untested channel used by lib/overlays.nix to pin a handful of
|
||||
# fast-moving packages (claude-code, gh, direnv). Unused until
|
||||
# mkSystem is wired in (phase D).
|
||||
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
|
||||
# Unified server-deploy flake. Source of truth for which refs
|
||||
# ship to which host; dev-env walks this flake's inputs to
|
||||
# auto-populate the project list (see modules/dev-env/config.nix)
|
||||
# and resolves --override-input targets for `dev-deploy --local`.
|
||||
# Named after the forgejo repo so DEVENV_DEPLOY_FLAKE_INPUT and
|
||||
# the on-disk clone directory match.
|
||||
server-deploy.url = "git+ssh://forgejo@git.atitlan.io/aiolabs/server-deploy";
|
||||
|
||||
# Home manager
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# nixos-hardware — per-model NixOS modules (kernel pins, GPU/CPU
|
||||
# defaults, firmware tooling) for common hardware. bohm is a
|
||||
# Framework Desktop (AMD Ryzen AI Max 300 series), so we import
|
||||
# `nixosModules.framework-desktop-amd-ai-max-300-series` in
|
||||
# hosts/omni/default.nix. gizmo is a Framework Laptop 12, but
|
||||
# runs Arch — if it ever migrates to NixOS, the matching module
|
||||
# is `nixosModules.framework-12-13th-gen-intel`.
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
|
||||
# Hyprland
|
||||
# Pinned to v0.54.3 — v0.55.0 (rev 70fd412) crashes on `togglegroup`
|
||||
# teardown: CGroup::destroy() throws an uncaught std::out_of_range.
|
||||
# Remove the tag to track latest once the upstream group regression is fixed.
|
||||
hyprland = {
|
||||
url = "github:hyprwm/Hyprland/v0.54.3";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# Hyprland plugins
|
||||
hyprland-plugins = {
|
||||
url = "github:hyprwm/hyprland-plugins";
|
||||
inputs.hyprland.follows = "hyprland";
|
||||
};
|
||||
|
||||
# Nix colors for automatic color scheme generation
|
||||
nix-colors = {
|
||||
url = "github:misterio77/nix-colors";
|
||||
};
|
||||
|
||||
# Stylix for theming
|
||||
stylix = {
|
||||
url = "github:danth/stylix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# NUR for additional packages
|
||||
nur.url = "github:nix-community/NUR";
|
||||
|
||||
# Walker app launcher + Elephant backend
|
||||
elephant = {
|
||||
url = "github:abenz1267/elephant";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
walker = {
|
||||
url = "github:abenz1267/walker";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.elephant.follows = "elephant";
|
||||
};
|
||||
|
||||
# sops-nix — declarative secrets via age-encrypted YAML files.
|
||||
# Decryption happens at activation time on the target host; secret
|
||||
# values are exposed to services as files under /run/secrets/.
|
||||
# The omni host's age key lives at
|
||||
# ~/.config/sops/age/keys.txt (same `admin` recipient as
|
||||
# ~/dev/deploy/server-deploy/.sops.yaml). See .sops.yaml +
|
||||
# modules/secrets.nix for wiring.
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# LazyVim packaged as a home-manager module. Tracks LazyVim
|
||||
# releases upstream and pins every plugin via the nix store
|
||||
# ("dev mode" symlinks) so there is no runtime download. We
|
||||
# pin to a specific tag rather than tracking `main` so a
|
||||
# broken upstream release can never silently break a fresh
|
||||
# install. Bump intentionally on each LazyVim release.
|
||||
lazyvim = {
|
||||
url = "github:pfassina/lazyvim-nix/v15.15.0";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# nix-bitcoin — hardened Bitcoin/Lightning node modules, consumed by
|
||||
# the default-disabled bitcoin pack. Follows our nixpkgs for a single
|
||||
# package set; nix-bitcoin pins its own nixpkgs upstream for tested
|
||||
# builds, so if a service fails to build once the pack is enabled,
|
||||
# consider dropping this `follows`.
|
||||
nix-bitcoin = {
|
||||
url = "github:fort-nix/nix-bitcoin/release";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
home-manager,
|
||||
...
|
||||
}@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
settings = import ./settings.nix;
|
||||
|
||||
# Overlays applied uniformly to every host built via mkSystem.
|
||||
# Combines the lib/overlays.nix nixpkgs-unstable pins with the
|
||||
# nur overlay omni already used. The neovim-nightly-overlay
|
||||
# was dropped because it cascade-rebuilds every neovim plugin
|
||||
# from source (cache miss on cache.nixos.org), which surfaced
|
||||
# broken upstream tests (fzf-lua screenshot test) and balloons
|
||||
# build time. LazyVim is provided declaratively via the
|
||||
# `lazyvim` flake input (a home-manager module) — see
|
||||
# home.nix `programs.lazyvim` — so we don't need a system
|
||||
# neovim with the full plugin set baked in.
|
||||
overlays = (import ./lib/overlays.nix { inherit inputs; }) ++ [
|
||||
inputs.nur.overlays.default
|
||||
];
|
||||
|
||||
# Uniform host constructor. See lib/mksystem.nix for the shape.
|
||||
mkSystem = import ./lib/mksystem.nix { inherit nixpkgs overlays inputs; };
|
||||
|
||||
# pkgs used for devShells, packages, and apps outputs below.
|
||||
# The nixosConfigurations get their own pkgs via mksystem's
|
||||
# `{ nixpkgs.overlays = overlays; }` module injection.
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
inherit overlays;
|
||||
};
|
||||
|
||||
# Interactive regtest dev VM (`nix run .#regtest`). Shares the node
|
||||
# config with the CI test (tests/regtest-node.nix); the interactive
|
||||
# layer (SSH, operator login, helpers) is tests/regtest-interactive.nix.
|
||||
regtestVm = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs settings; };
|
||||
modules = [
|
||||
{ nixpkgs.hostPlatform = system; }
|
||||
{ nixpkgs.config.allowUnfree = true; }
|
||||
# qemu-vm.nix provides `system.build.vm` plus the virtualisation.*
|
||||
# options (cores/memorySize/graphics/forwardPorts) that the node
|
||||
# and interactive modules set. The nixosTest framework imports it
|
||||
# automatically; a plain nixosSystem must do so explicitly.
|
||||
(
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];
|
||||
}
|
||||
)
|
||||
inputs.nix-bitcoin.nixosModules.default
|
||||
./tests/regtest-node.nix
|
||||
./tests/regtest-interactive.nix
|
||||
];
|
||||
};
|
||||
|
||||
# `nix run .#regtest` — boot the VM headless, drop into an operator
|
||||
# SSH shell, tear the VM down on exit. Ephemeral disk in a tmp file.
|
||||
regtestRunner = pkgs.writeShellApplication {
|
||||
name = "regtest";
|
||||
runtimeInputs = with pkgs; [
|
||||
sshpass
|
||||
openssh
|
||||
coreutils
|
||||
];
|
||||
text = ''
|
||||
vm_script=${regtestVm.config.system.build.vm}/bin/run-regtest-vm
|
||||
img=$(mktemp -u --suffix=.qcow2)
|
||||
log=$(mktemp)
|
||||
export NIX_DISK_IMAGE="$img"
|
||||
ssh_opts=(-p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR)
|
||||
|
||||
cleanup() {
|
||||
if [ -n "''${vm_pid:-}" ]; then kill "$vm_pid" 2>/dev/null || true; fi
|
||||
rm -f "$img" "$log"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "🥾 booting regtest VM (headless) — first boot generates node secrets + mines 110 blocks…"
|
||||
"$vm_script" >"$log" 2>&1 &
|
||||
vm_pid=$!
|
||||
|
||||
echo "⏳ waiting for SSH on localhost:2222…"
|
||||
ready=
|
||||
for _ in $(seq 1 120); do
|
||||
if ! kill -0 "$vm_pid" 2>/dev/null; then
|
||||
echo "❌ VM exited early; last log lines:"; tail -n 20 "$log"; exit 1
|
||||
fi
|
||||
if sshpass -p password ssh "''${ssh_opts[@]}" -o ConnectTimeout=2 operator@localhost true 2>/dev/null; then
|
||||
ready=1; break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
if [ "$ready" != 1 ]; then
|
||||
echo "❌ SSH never came up; last log lines:"; tail -n 20 "$log"; exit 1
|
||||
fi
|
||||
|
||||
echo "✅ connected — run 'regtest-fund' to set up a channel; 'exit' to shut down."
|
||||
sshpass -p password ssh "''${ssh_opts[@]}" operator@localhost || true
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
# NixOS configurations.
|
||||
nixosConfigurations = {
|
||||
# Main dev box. Uses the mksystem convention (hosts/omni/ +
|
||||
# users/user/home-manager.nix shims — see commit dc9d70b).
|
||||
#
|
||||
# modules = [ ... ] is the escape hatch for host-specific
|
||||
# home-manager options that mksystem doesn't expose directly,
|
||||
# like sharedModules for nix-colors integration.
|
||||
omni = mkSystem "omni" {
|
||||
inherit system;
|
||||
user = settings.user;
|
||||
devEnv = true;
|
||||
extraSpecialArgs = { inherit settings; };
|
||||
extraHmArgs = { inherit settings; };
|
||||
modules = [
|
||||
{
|
||||
home-manager.sharedModules = [
|
||||
inputs.nix-colors.homeManagerModules.default
|
||||
inputs.lazyvim.homeManagerModules.default
|
||||
inputs.walker.homeManagerModules.default
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# Copy-me template host (hosts/example/). Kept as a real,
|
||||
# build-checked target so the template can't silently rot — its
|
||||
# placeholder hardware-configuration.nix uses by-label devices
|
||||
# that won't match real hardware, so don't `switch` to it. Adopters
|
||||
# copy hosts/example → hosts/<name> and rename this block. See
|
||||
# hosts/example/default.nix and docs/getting-started.md.
|
||||
example = mkSystem "example" {
|
||||
inherit system;
|
||||
user = settings.user;
|
||||
extraSpecialArgs = { inherit settings; };
|
||||
extraHmArgs = { inherit settings; };
|
||||
modules = [
|
||||
{
|
||||
home-manager.sharedModules = [
|
||||
inputs.nix-colors.homeManagerModules.default
|
||||
inputs.lazyvim.homeManagerModules.default
|
||||
inputs.walker.homeManagerModules.default
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# ISO image for live USB/DVD. This is a variant rather than a
|
||||
# normal host, so it stays as a direct nixosSystem call — we
|
||||
# don't force every variant through mksystem. It reuses
|
||||
# omni's home.nix but under a "nixos" user that only exists
|
||||
# in the ISO context.
|
||||
omni-iso = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
settings = settings // {
|
||||
user = "nixos";
|
||||
};
|
||||
currentSystemName = "omni-iso";
|
||||
currentSystemUser = "nixos";
|
||||
};
|
||||
modules = [
|
||||
{ nixpkgs.hostPlatform = system; }
|
||||
{ nixpkgs.overlays = overlays; }
|
||||
{ nixpkgs.config.allowUnfree = true; }
|
||||
./iso.nix
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
extraSpecialArgs = {
|
||||
inherit inputs;
|
||||
settings = settings // {
|
||||
user = "nixos";
|
||||
};
|
||||
currentSystemName = "omni-iso";
|
||||
currentSystemUser = "nixos";
|
||||
};
|
||||
users.nixos = import ./home.nix;
|
||||
sharedModules = [
|
||||
inputs.nix-colors.homeManagerModules.default
|
||||
inputs.lazyvim.homeManagerModules.default
|
||||
inputs.walker.homeManagerModules.default
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Reusable packs as importable NixOS modules (Misterio77-style,
|
||||
# framework-free). A second host (gizmo) and third parties consume
|
||||
# the same definitions with different subsets. The lnbits / aiolabs
|
||||
# / bitcoin packs are standalone-importable — usable on a non-omni
|
||||
# NixOS without enabling omni core.
|
||||
nixosModules = {
|
||||
lnbits = import ./modules/packs/lnbits.nix;
|
||||
aiolabs = import ./modules/packs/aiolabs.nix;
|
||||
bitcoin = import ./modules/packs/bitcoin.nix;
|
||||
media = import ./modules/packs/media.nix;
|
||||
development = import ./modules/packs/development.nix;
|
||||
gaming = import ./modules/packs/gaming.nix;
|
||||
office = import ./modules/packs/office.nix;
|
||||
containers = import ./modules/packs/containers.nix;
|
||||
};
|
||||
|
||||
# Flake checks — run by `nix flake check`. Lightweight targets
|
||||
# that exercise the dev-env module schema end-to-end without
|
||||
# loading the full omni system. Each check renders a small
|
||||
# file (JSON or bash), so they build in a second or two even
|
||||
# without a binary cache. See modules/dev-env/tests/smoke.nix
|
||||
# for what is exercised.
|
||||
checks.${system} =
|
||||
let
|
||||
devEnvSmoke = import ./modules/dev-env/tests/smoke.nix {
|
||||
inherit nixpkgs;
|
||||
home-manager = inputs.home-manager;
|
||||
};
|
||||
in
|
||||
{
|
||||
dev-env-projects-json = devEnvSmoke.config.environment.etc."dev-env/projects.json".source;
|
||||
dev-env-config-sh = devEnvSmoke.config.environment.etc."dev-env/config.sh".source;
|
||||
dev-env-tmux-sessions = devEnvSmoke.config.environment.etc."dev-env/tmux-sessions.json".source;
|
||||
|
||||
# Headless VM boot test — pass/fail signal for autonomous refactor
|
||||
# runs in ~/nixos-refactor/. See tests/refactor-smoke.nix.
|
||||
refactor-smoke = import ./tests/refactor-smoke.nix {
|
||||
inherit nixpkgs system;
|
||||
};
|
||||
|
||||
# NixOS-native Lightning regtest suite (aiolabs/omnixient#27):
|
||||
# bitcoind(regtest) + Core Lightning + LND in one VM, driving a
|
||||
# real fund → open-channel → pay → settle flow. See
|
||||
# tests/regtest-core.nix.
|
||||
regtest-core = import ./tests/regtest-core.nix {
|
||||
inherit nixpkgs system;
|
||||
nix-bitcoin = inputs.nix-bitcoin;
|
||||
};
|
||||
};
|
||||
|
||||
# Development shells
|
||||
devShells.${system} = {
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
# Development tools
|
||||
git
|
||||
# neovim (configured via home-manager)
|
||||
ripgrep
|
||||
fd
|
||||
bat
|
||||
eza
|
||||
fzf
|
||||
zoxide
|
||||
starship
|
||||
lazygit
|
||||
gh
|
||||
|
||||
# Language servers and formatters
|
||||
nil # Nix LSP
|
||||
nixfmt
|
||||
statix
|
||||
deadnix
|
||||
|
||||
# Build tools
|
||||
gnumake
|
||||
gcc
|
||||
nodejs
|
||||
python3
|
||||
rustc
|
||||
cargo
|
||||
go
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "🚀 Welcome to Omnixient development environment!"
|
||||
echo ""
|
||||
echo "Available commands:"
|
||||
echo " omni-rebuild - Rebuild system configuration"
|
||||
echo " omni-update - Update flake inputs"
|
||||
echo " omni-clean - Garbage collect nix store"
|
||||
echo ""
|
||||
|
||||
# Setup aliases
|
||||
alias omni-rebuild="sudo nixos-rebuild switch --flake .#omni"
|
||||
alias omni-update="nix flake update"
|
||||
alias omni-clean="nix-collect-garbage -d"
|
||||
|
||||
# Initialize starship prompt
|
||||
eval "$(starship init bash)"
|
||||
'';
|
||||
};
|
||||
|
||||
# Python development
|
||||
python = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
python3
|
||||
python3Packages.pip
|
||||
python3Packages.virtualenv
|
||||
python3Packages.ipython
|
||||
python3Packages.black
|
||||
python3Packages.pylint
|
||||
python3Packages.pytest
|
||||
ruff
|
||||
];
|
||||
};
|
||||
|
||||
# Node.js development
|
||||
node = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
nodejs
|
||||
pnpm
|
||||
yarn
|
||||
typescript
|
||||
eslint
|
||||
prettier
|
||||
];
|
||||
};
|
||||
|
||||
# Rust development
|
||||
rust = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
rustc
|
||||
cargo
|
||||
rustfmt
|
||||
rust-analyzer
|
||||
clippy
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Packages that can be built
|
||||
packages.${system} = {
|
||||
# Omnixient scripts as packages
|
||||
omni-scripts = pkgs.callPackage ./packages/scripts.nix { };
|
||||
|
||||
# Plymouth theme package
|
||||
plymouth-theme-omni = pkgs.callPackage ./packages/plymouth-theme.nix { };
|
||||
|
||||
# ISO image
|
||||
iso = self.nixosConfigurations.omni-iso.config.system.build.isoImage;
|
||||
|
||||
# Interactive regtest dev VM run-script (booted by `nix run .#regtest`).
|
||||
regtest-vm = regtestVm.config.system.build.vm;
|
||||
|
||||
# Default package points to ISO
|
||||
default = self.packages.${system}.iso;
|
||||
};
|
||||
|
||||
# Apps that can be run
|
||||
apps.${system} = {
|
||||
# Interactive Lightning regtest dev VM — boots the stack headless
|
||||
# and drops you into an operator SSH shell. See docs/regtest.md.
|
||||
regtest = {
|
||||
type = "app";
|
||||
program = "${regtestRunner}/bin/regtest";
|
||||
};
|
||||
|
||||
# Installer
|
||||
installer = {
|
||||
type = "app";
|
||||
program = "${pkgs.writeShellScriptBin "omni-install" ''
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
echo "🚀 Omnixient NixOS Installer"
|
||||
echo "========================"
|
||||
echo ""
|
||||
|
||||
# Check if running on NixOS
|
||||
if [ ! -f /etc/nixos/configuration.nix ]; then
|
||||
echo "Error: This installer must be run on a NixOS system"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "This will install Omnixient configuration to your NixOS system."
|
||||
read -p "Continue? (y/n) " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Backup existing configuration
|
||||
echo "📦 Backing up existing configuration..."
|
||||
sudo cp -r /etc/nixos /etc/nixos.backup.$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# Copy new configuration
|
||||
echo "📝 Installing Omnixient configuration..."
|
||||
sudo cp -r ${self}/* /etc/nixos/
|
||||
|
||||
# Initialize flake
|
||||
echo "🔧 Initializing flake..."
|
||||
cd /etc/nixos
|
||||
sudo git init
|
||||
sudo git add -A
|
||||
|
||||
# Rebuild
|
||||
echo "🏗️ Rebuilding system..."
|
||||
sudo nixos-rebuild switch --flake /etc/nixos#omni
|
||||
|
||||
echo ""
|
||||
echo "✅ Installation complete!"
|
||||
echo "🎉 Welcome to Omnixient!"
|
||||
''}/bin/omni-install";
|
||||
};
|
||||
|
||||
# ISO builder
|
||||
build-iso = {
|
||||
type = "app";
|
||||
program = "${pkgs.writeShellScriptBin "omni-build-iso" ''
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
echo "🏗️ Building Omnixient ISO Image"
|
||||
echo "============================"
|
||||
echo ""
|
||||
|
||||
echo "📦 Building ISO image..."
|
||||
echo " This may take a while depending on your system..."
|
||||
echo ""
|
||||
|
||||
# Build the ISO
|
||||
nix build .#iso
|
||||
|
||||
# Check if build was successful
|
||||
if [ -L "./result" ]; then
|
||||
iso_path=$(readlink -f ./result)
|
||||
iso_file=$(find "$iso_path" -name "*.iso" | head -1)
|
||||
|
||||
if [ -n "$iso_file" ]; then
|
||||
iso_size=$(du -h "$iso_file" | cut -f1)
|
||||
echo ""
|
||||
echo "✅ ISO build complete!"
|
||||
echo "📁 Location: $iso_file"
|
||||
echo "📏 Size: $iso_size"
|
||||
echo ""
|
||||
echo "🚀 You can now:"
|
||||
echo " • Flash to USB: dd if='$iso_file' of=/dev/sdX bs=4M status=progress"
|
||||
echo " • Burn to DVD: Use your favorite burning software"
|
||||
echo " • Test in VM: qemu-system-x86_64 -cdrom '$iso_file' -m 4G -enable-kvm"
|
||||
echo ""
|
||||
else
|
||||
echo "❌ ISO file not found in build result"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "❌ Build failed - result symlink not found"
|
||||
exit 1
|
||||
fi
|
||||
''}/bin/omni-build-iso";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue