nixos/WORK_TOOLS_MODULE_DESIGN.md

9.8 KiB

Work Tools Module Design Document

Overview

A modular NixOS configuration for work-specific development tools and services. This allows clean separation between personal and work machines while enabling easy reuse across multiple work systems.


Module Structure

Proposed Location

shared/modules/work/work_tools.nix

This places it in the shared modules directory since it could be used across multiple work machines.

Alternative Location

nate-work/modules/work/work_tools.nix

Use this if the tools are specific to a single work environment.


Module Design

Basic Structure

{ inputs, lib, config, pkgs, ... }:
let
  unstable = import inputs.nixpkgs-unstable {
    system = "x86_64-linux";
    config.allowUnfree = true;
  };
in
{
  options.work_tools = {
    enable = lib.mkEnableOption "Enable work development tools and services";

    enableDocker = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable Docker and related containerization tools";
    };

    enableVirtualization = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable QEMU/KVM virtualization";
    };

    enableGoTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable Go development toolchain";
    };

    enableNodeTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable Node.js development tools";
    };

    enableDatabaseTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable database clients and tools";
    };

    user = lib.mkOption {
      type = lib.types.str;
      description = "Username for service configurations";
    };
  };

  config = lib.mkIf config.work_tools.enable {
    # Docker configuration
    virtualisation.docker = lib.mkIf config.work_tools.enableDocker {
      enable = true;
      enableOnBoot = true;
      package = unstable.docker_25;
    };

    users.groups.docker.members = lib.mkIf config.work_tools.enableDocker
      [ config.work_tools.user ];

    # Virtualization
    virtualisation.libvirtd = lib.mkIf config.work_tools.enableVirtualization {
      enable = true;
      qemu = {
        swtpm.enable = true;
      };
    };

    virtualisation.spiceUSBRedirection.enable =
      lib.mkIf config.work_tools.enableVirtualization true;

    users.groups.libvirtd.members = lib.mkIf config.work_tools.enableVirtualization
      [ config.work_tools.user ];

    programs.virt-manager.enable =
      lib.mkIf config.work_tools.enableVirtualization true;

    # NFS support (if needed for remote dev environments)
    boot.initrd.supportedFilesystems = lib.mkIf config.work_tools.enableVirtualization
      { nfs = true; };

    # System packages that don't fit into categories
    environment.systemPackages = with pkgs; lib.lists.flatten [
      (lib.optionals config.work_tools.enableDocker [
        docker-compose
      ])
    ];
  };
}

Home Manager Companion Module

Create a companion home-manager module for user-level packages:

shared/modules/work/work_tools_home.nix
{ inputs, lib, config, pkgs, ... }:
let
  unstable = import inputs.nixpkgs-unstable {
    system = "x86_64-linux";
    config.allowUnfree = true;
  };
in
{
  options.work_tools_home = {
    enable = lib.mkEnableOption "Enable work development tools in home";

    enableGoTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable Go development toolchain";
    };

    enableNodeTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable Node.js development tools";
    };

    enableDatabaseTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable database clients";
    };

    enableAwsTools = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "Enable AWS CLI and related tools";
    };
  };

  config = lib.mkIf config.work_tools_home.enable {
    home.packages = with pkgs; lib.lists.flatten [
      # Development tools
      (lib.optionals config.work_tools_home.enableGoTools [
        go
        unstable.delve
        gotools
        go-tools
        govulncheck
        unstable.golangci-lint
        go-swag
        gopls
      ])

      (lib.optionals config.work_tools_home.enableNodeTools [
        nodejs_24
        husky
        pnpm
        yarn
        typescript-language-server
      ])

      (lib.optionals config.work_tools_home.enableDatabaseTools [
        mariadb
      ])

      (lib.optionals config.work_tools_home.enableAwsTools [
        awscli2
      ])

      # General dev tools
      vscode-fhs
      jq
      gnumake
      cmake
      gcc
      gh
      trivy
      oxker  # docker TUI

      # Additional LSPs
      yaml-language-server
      ltex-ls
    ];

    # Work-specific zsh configuration
    programs.zsh.initExtra = lib.mkIf config.work_tools_home.enable ''
      # Work environment variables
      if [ -f ~/.vasion_env ]; then
        source ~/.vasion_env
      fi

      # Work functions
      if [ -f ~/.config/zsh_functions.zsh ]; then
        source ~/.config/zsh_functions.zsh
      fi

      export GOBIN=~/go/bin
      export PATH=$PATH:$GOBIN
    '';
  };
}

Integration Steps

1. Create the module files

  • Create shared/modules/work/work_tools.nix
  • Create shared/modules/work/work_tools_home.nix

2. Import in nate-work system configuration

In nate-work/desktop-configuration.nix:

imports = [
  # ... existing imports
  ../shared/modules/work/work_tools.nix
];

config = {
  # ... existing config

  work_tools = {
    enable = true;
    enableDocker = true;
    enableVirtualization = true;
    enableGoTools = true;
    enableNodeTools = true;
    enableDatabaseTools = true;
    user = deskCfg.userName;
  };
};

3. Import in nate-work home-manager configuration

In nate-work/modules/home-manager/home.nix:

imports = [
  # ... existing imports
  ../../../shared/modules/work/work_tools_home.nix
];

work_tools_home = {
  enable = true;
  enableGoTools = true;
  enableNodeTools = true;
  enableDatabaseTools = true;
  enableAwsTools = true;
};

4. Remove work packages from nirihome.homePackages

Clean up the existing package list by removing packages now provided by work_tools_home.

5. Test the configuration

# Dry-run to check for errors
nix build .#nixosConfigurations.nate-work.config.system.build.toplevel --dry-run

# If successful, rebuild
sudo nixos-rebuild switch --flake .#nate-work

Benefits

Modularity

  • Easy to enable/disable categories of tools
  • Can be reused across multiple work machines
  • Keeps personal configs clean

Flexibility

  • Granular control via boolean flags
  • Can enable only needed tool categories
  • Easy to add new tool categories

Maintainability

  • Single source of truth for work tools
  • Easier to update work tooling across systems
  • Clear separation of concerns

Future Enhancements

Additional Tool Categories

enablePythonTools = lib.mkOption {
  type = lib.types.bool;
  default = false;
  description = "Enable Python development tools";
};

enableRustTools = lib.mkOption {
  type = lib.types.bool;
  default = false;
  description = "Enable Rust development toolchain";
};

enableCloudTools = lib.mkOption {
  type = lib.types.bool;
  default = false;
  description = "Enable cloud provider CLIs (Azure, GCP)";
};

Company-Specific Customization

company = lib.mkOption {
  type = lib.types.enum [ "vasion" "other" ];
  default = "vasion";
  description = "Company-specific tool configurations";
};

Environment File Management

Could integrate automated setup of .vasion_env or similar:

work_tools_home.envFile = lib.mkOption {
  type = lib.types.nullOr lib.types.path;
  default = null;
  description = "Path to work environment variables file";
};

Verification Checklist

After creating the module:

  • Module imports correctly in desktop-configuration.nix
  • Module imports correctly in home.nix
  • Options can be toggled without errors
  • Docker service starts correctly
  • Libvirtd service starts correctly
  • Go tools are in PATH
  • Node tools are in PATH
  • AWS CLI works
  • User is in correct groups (docker, libvirtd)
  • No duplicate packages between work_tools and personal configs
  • Build succeeds with nix flake check
  • System rebuilds successfully

Migration Path

Current State (nate-work)

Work tools scattered across:

  • nate-work/modules/niri/niri_conf.nix (docker, virt-manager)
  • nate-work/modules/home-manager/home.nix (go, node, aws tools)

Target State

Work tools consolidated in:

  • shared/modules/work/work_tools.nix (system-level)
  • shared/modules/work/work_tools_home.nix (user-level)

Steps

  1. Create module files
  2. Import modules
  3. Enable with appropriate flags
  4. Remove duplicate package declarations
  5. Test rebuild
  6. Verify all tools still work
  7. Commit changes

Questions to Answer

Before implementing:

  1. Should this be in shared/ or nate-work/modules/?

    • Recommendation: shared/ if you might have multiple work machines
    • Use nate-work/modules/ if this is Vasion-specific
  2. Do you want separate modules per tool category?

    • Could split into: work_docker.nix, work_go.nix, etc.
    • Tradeoff: More files vs. better separation
  3. Should work tools include LSPs?

    • Currently LSPs are in home.nix
    • Could move to work_tools_home for consistency
  4. Do you want cloud-specific tool categories?

    • AWS tools separate from GCP/Azure?
    • Or generic "cloud tools" category?
  5. Should VPN proxy module be part of work_tools?

    • Currently separate module
    • Could integrate or keep separate