main
  1{
  2  config,
  3  lib,
  4  pkgs,
  5  ...
  6}:
  7
  8with lib;
  9let
 10  cfg = config.services.microshift;
 11in
 12{
 13  options = {
 14    services.microshift = {
 15      enable = mkEnableOption "MicroShift via CRC";
 16
 17      cpus = mkOption {
 18        type = types.int;
 19        default = 4;
 20        description = "Number of CPU cores for MicroShift";
 21      };
 22
 23      memory = mkOption {
 24        type = types.int;
 25        default = 8192; # 8GB
 26        description = "Memory in MB for MicroShift";
 27      };
 28
 29      diskSize = mkOption {
 30        type = types.int;
 31        default = 40; # GB
 32        description = "Disk size in GB for MicroShift";
 33      };
 34
 35      pullSecret = mkOption {
 36        type = types.nullOr types.path;
 37        default = null;
 38        description = "Path to Red Hat pull secret (required for MicroShift preset)";
 39      };
 40
 41      user = mkOption {
 42        type = types.str;
 43        default = "vincent";
 44        description = "User to run CRC as";
 45      };
 46    };
 47  };
 48
 49  config = mkIf cfg.enable {
 50    assertions = [
 51      {
 52        assertion = cfg.cpus >= 2 && cfg.cpus <= 16;
 53        message = "services.microshift.cpus must be between 2 and 16";
 54      }
 55      {
 56        assertion = cfg.memory >= 4096;
 57        message = "services.microshift.memory must be at least 4096 MB (4GB)";
 58      }
 59      {
 60        assertion = cfg.diskSize >= 20;
 61        message = "services.microshift.diskSize must be at least 20 GB";
 62      }
 63    ];
 64
 65    # Ensure required services are enabled
 66    virtualisation.podman.enable = true;
 67    virtualisation.libvirtd.enable = true;
 68
 69    # Ensure user has libvirt access
 70    users.users.${cfg.user}.extraGroups = [ "libvirtd" ];
 71
 72    # Allow CRC to use sudo for admin helper setup without password
 73    # CRC needs chown/chmod for the admin helper executable
 74    security.sudo.extraRules = [
 75      {
 76        users = [ cfg.user ];
 77        commands = [
 78          {
 79            command = "ALL";
 80            options = [ "NOPASSWD" ];
 81          }
 82        ];
 83      }
 84    ];
 85
 86    environment.systemPackages = with pkgs; [
 87      crc
 88      kubectl
 89    ];
 90
 91    # Systemd service to manage CRC lifecycle
 92    systemd.services.crc-microshift = {
 93      description = "MicroShift via CRC";
 94      after = [
 95        "network.target"
 96        "libvirtd.service"
 97      ];
 98      wantedBy = [ "multi-user.target" ];
 99
100      serviceConfig = {
101        Type = "oneshot";
102        RemainAfterExit = true;
103        User = cfg.user;
104        WorkingDirectory = "/home/${cfg.user}";
105      };
106
107      path = with pkgs; [ crc ];
108
109      environment = {
110        PATH = lib.mkForce "/run/wrappers/bin:/run/current-system/sw/bin";
111      };
112
113      script = ''
114        # Setup CRC with MicroShift preset
115        ${pkgs.crc}/bin/crc config set preset microshift
116        ${pkgs.crc}/bin/crc config set cpus ${toString cfg.cpus}
117        ${pkgs.crc}/bin/crc config set memory ${toString cfg.memory}
118        ${pkgs.crc}/bin/crc config set disk-size ${toString cfg.diskSize}
119
120        ${optionalString (cfg.pullSecret != null) ''
121          ${pkgs.crc}/bin/crc config set pull-secret-file ${cfg.pullSecret}
122        ''}
123
124        # Setup (downloads images if needed)
125        ${pkgs.crc}/bin/crc setup
126
127        # Start MicroShift
128        ${pkgs.crc}/bin/crc start
129      '';
130
131      preStop = ''
132        ${pkgs.crc}/bin/crc stop
133      '';
134    };
135
136    # Environment setup for kubectl access
137    environment.extraInit = ''
138      if [ -f ~/.crc/machines/crc/kubeconfig ]; then
139        export KUBECONFIG=~/.crc/machines/crc/kubeconfig
140      fi
141    '';
142  };
143}