{ description = "A flake providing a NixOS Qemu VM for DTCC onboarding."; inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; }; outputs = { self, nixpkgs }: let # (note): Keep this up to date constants = { citrixDownloadPageUrl = "https://www.citrix.com/downloads/workspace-app/legacy-workspace-app-for-linux/workspace-app-for-linux-250810.html"; citrixTarballHash = "sha256-bd3ClxBRJgvjJW+waKBE31k9ePam+n2pHeSjlkvkDRo="; disclaimer = '' WARNING: ICA files are only good to be used ONCE. If you've logged into the DTCC virtual desktop using it before, you will get a connection error from Citrix upon trying to log in with it again. To get a fresh ICA file, you need to _refresh_ your myvdi.dtcc.com page and download it via 'Open' again. The ICA files listed below are ordered from newest to oldest for your convenience, so '1' is usually the correct choice. This file will get copied into the VM. You are free to remove old/stale ICA files from your system. ''; }; pkgs = import nixpkgs { system = "x86_64-linux"; config = { allowUnfree = true; allowBroken = true; permittedInsecurePackages = [ "libsoup-2.74.3" ]; }; overlays = [ (self: super: { citrix_workspace = super.citrix_workspace.overrideAttrs (_: { src = scripts.citrixTarballScraper; }); }) ]; }; scripts.citrixTarballScraper = pkgs.stdenvNoCC.mkDerivation { name = "citrix-workspace-src.tar.gz"; outputHashMode = "flat"; outputHashAlgo = "sha256"; outputHash = constants.citrixTarballHash; nativeBuildInputs = [ pkgs.curl pkgs.cacert ]; # (credit): Based on the scraper used in the AUR PKGBUILD for `icaclient-beta` buildCommand = '' _body="$(curl -sL "${constants.citrixDownloadPageUrl}")" _dl_urls="$(grep -F ".tar.gz?__gda__" <<< "$_body")" _tarball_url=https:"$(sed -En 's|^.*rel="(//.*/linuxx64-[^"]*)".*$|\1|p' <<< "$_dl_urls")" curl -L "$_tarball_url" -o "$out" ''; }; scripts.launchVm = pkgs.writeShellScriptBin "launch-vm" '' # Vibecoded w/ Claude select_ica_file() { local download_dir="''${XDG_DOWNLOAD_DIR:-$HOME/Downloads}" local -a files mapfile -t files < <( { find "$download_dir" -maxdepth 1 -name "*.ica" -type f -printf "%T@\t%p\n" 2>/dev/null find "$PWD" -maxdepth 1 -name "*.ica" -type f -printf "%T@\t%p\n" 2>/dev/null } \ | sort -u -t$'\t' -k2 \ | sort -rn -t$'\t' -k1 \ | cut -f2- ) if [[ ''${#files[@]} -eq 0 ]]; then echo "No .ica files found in $download_dir or $PWD" >&2 return 1 fi echo "Available .ica files:" >&2 for i in "''${!files[@]}"; do echo " $((i+1))) ''${files[$i]}" >&2 done local selection while true; do read -rp "Select file [1-''${#files[@]}] (default: 1): " selection >&2 selection="''${selection:-1}" if [[ "$selection" =~ ^[0-9]+$ ]] && \ (( selection >= 1 && selection <= ''${#files[@]} )); then break fi echo "Invalid selection, please enter a number between 1 and ''${#files[@]}" >&2 done echo "''${files[$((selection-1))]}" } echo "${constants.disclaimer}" ica_file=$(select_ica_file) mkdir -p /tmp/dtcc-onboarding cp "$ica_file" /tmp/dtcc-onboarding/dtcc-ica.ica ${self.nixosConfigurations.dtcc-onboarding.config.system.build.vm}/bin/run-nixos-vm ''; in { nixosConfigurations.dtcc-onboarding = nixpkgs.lib.nixosSystem { inherit pkgs; system = "x86_64-linux"; modules = [ "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ({ pkgs, ... }: { services = { displayManager.gdm = { enable = true; wayland = true; }; displayManager.autoLogin = { enable = true; user = "nixos"; }; desktopManager.gnome.enable = true; }; system.activationScripts = { gnome-skip-welcome = '' mkdir -p /home/nixos/.config touch /home/nixos/.config/gnome-initial-setup-done chown nixos:users /home/nixos/.config/gnome-initial-setup-done ''; }; programs.dconf = { enable = true; profiles.user.databases = [{ settings = { "org/gnome/shell" = { enabled-extensions = [ "no-overview@fthx" ]; }; }; }]; }; environment.systemPackages = with pkgs; [ citrix_workspace gnomeExtensions.no-overview ]; users.users.nixos = { isNormalUser = true; extraGroups = [ "wheel" ]; password = ""; }; security.sudo.wheelNeedsPassword = false; systemd.user.services.launch-citrix = { description = "Launch Citrix ICA session"; wantedBy = [ "graphical-session.target" ]; after = [ "graphical-session.target" ]; serviceConfig = { ExecStart = "${pkgs.bash}/bin/bash -c '${pkgs.citrix_workspace}/bin/wfica /mnt/ica/dtcc-ica.ica'"; Restart = "no"; Type = "oneshot"; }; }; system.stateVersion = "25.11"; virtualisation = { cores = 8; memorySize = 10 * 1024; msize = 128 * 1024; diskSize = 12 * 1024; qemu.options = [ "-vga virtio" ]; sharedDirectories = { default = { source = "/tmp/dtcc-onboarding"; target = "/mnt/ica"; }; }; }; }) ]; }; packages.x86_64-linux = { inherit (scripts) citrixTarballScraper; }; apps.x86_64-linux = { default = { type = "app"; program = "${scripts.launchVm}/bin/launch-vm"; }; }; }; }