diff --git a/modules/apps/gaming.nix b/modules/apps/gaming.nix new file mode 100644 index 0000000..d7efb49 --- /dev/null +++ b/modules/apps/gaming.nix @@ -0,0 +1,180 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.gaming; +in { + options.gaming = { + steam = { + enable = lib.mkEnableOption "Steam gaming platform"; + + firewall = { + remotePlay = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Open firewall ports for Steam Remote Play"; + }; + + localNetworkGameTransfers = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Open firewall ports for local network game transfers"; + }; + }; + }; + + gamemode = { + enable = lib.mkEnableOption "Gamemode performance optimization"; + config = lib.mkOption { + type = lib.types.attrs; + default = {}; + description = "Custom Gamemode configuration options"; + }; + }; + + gamescope = { + enable = lib.mkEnableOption "Gamescope gaming compositor"; + settings = { + resolution = lib.mkOption { + type = lib.types.nullOr (lib.types.submodule { + options = { + width = lib.mkOption { + type = lib.types.int; + description = "Gamescope rendering width"; + }; + height = lib.mkOption { + type = lib.types.int; + description = "Gamescope rendering height"; + }; + }; + }); + default = null; + description = "Gamescope rendering resolution"; + }; + + refreshRate = lib.mkOption { + type = lib.types.nullOr lib.types.int; + default = null; + description = "Gamescope rendering refresh rate"; + }; + }; + }; + + lutris = { + enable = lib.mkEnableOption "Lutris game manager and launcher"; + package = lib.mkOption { + type = lib.types.package; + default = pkgs.lutris; + description = "Lutris package to use (allows for custom or alternative packages)"; + }; + + wine = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable Wine support for Lutris"; + }; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.wineWow; + description = "Wine package to use with Lutris"; + }; + }; + + # Compatibility layers for Lutris + compatibility = { + protonSupport = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable Proton-like compatibility layers for Lutris"; + }; + + extraTools = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + description = "Additional compatibility tools for Lutris"; + }; + }; + + # Additional system packages for Lutris + extraPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + description = "Additional packages to install alongside Lutris"; + }; + }; + + minecraft = lib.mkOption { + enable = lib.mkEnableOption "Minecraft in the form of PrismLauncher, a tool for launching Minecraft"; + }; + ffxiv = lib.mkOption { + enable = lib.mkEnableOption "Final Fantasy XIV and it's accompanied (unofficial) launcher"; + }; + }; + + config = { + programs.steam = lib.mkIf cfg.steam.enable { + enable = true; + remotePlay.openFirewall = cfg.steam.firewall.remotePlay; + localNetworkGameTransfers.openFirewall = cfg.steam.firewall.localNetworkGameTransfers; + }; + + programs.gamemode = lib.mkIf cfg.gamemode.enable { + enable = true; + settings = cfg.gamemode.config; + }; + + programs.gamescope = lib.mkIf cfg.gamescope.enable { + enable = true; + + # Apply custom resolution if specified + args = + lib.optional (cfg.gamescope.settings.resolution != null) [ + "-w" + (toString cfg.gamescope.settings.resolution.width) + "-h" + (toString cfg.gamescope.settings.resolution.height) + ] + ++ lib.optional (cfg.gamescope.settings.refreshRate != null) [ + "-r" + (toString cfg.gamescope.settings.refreshRate) + ]; + }; + + environment.systemPackages = + lib.mkIf cfg.lutris.enable ( + # Base Lutris package + [cfg.lutris.package] + ++ + # Wine packages if enabled + (lib.optionals cfg.lutris.wine.enable [ + cfg.lutris.wine.package + pkgs.winetricks + ]) + ++ + # Proton and compatibility tools + (lib.optionals cfg.lutris.compatibility.protonSupport [ + pkgs.proton-ge-custom + ]) + ++ + # Extra compatibility tools + cfg.lutris.compatibility.extraTools + ++ + # User-specified extra packages + cfg.lutris.extraPackages + ) + lib.mkIf + cfg.minecraft.enable [pkgs.prismlauncher] + lib.mkIf + cfg.ffxiv.enable [pkgs.xivlauncher]; + + # Wine configuration + programs.wine = lib.mkIf (cfg.lutris.enable && cfg.lutris.wine.enable) { + enable = true; + package = cfg.lutris.wine.package; + }; + }; +} diff --git a/modules/apps/xdg.nix b/modules/apps/xdg.nix new file mode 100644 index 0000000..e69de29 diff --git a/modules/common/users.nix b/modules/common/users.nix index d8185d8..ce772dd 100644 --- a/modules/common/users.nix +++ b/modules/common/users.nix @@ -5,16 +5,8 @@ hostname, ... } @ args: { - # Set up networking configuration networking.hostName = hostname; - # networking.computerName = hostname; - # networking.firewall.enable = true; # VERY important, do not touch - # networking.firewall.allowedTCPPorts = []; - # networking.firewall.allowedUDPPorts = []; - # networking.networkmanager.enable = pkgs.stdenv.isLinux; # Linux tool for managing network connections - # system.defaults.smb.NetBIOSName = hostname; - # Set up user accounts # Don't forget to set a password with ‘passwd’! users.users."${userName}" = lib.mkMerge [ { diff --git a/modules/machine/cloud/README.md b/modules/machine/cloud/README.md index 6650285..e4a13aa 100644 --- a/modules/machine/cloud/README.md +++ b/modules/machine/cloud/README.md @@ -7,3 +7,7 @@ Licensed by the Mozilla Public License v2 ## Synopsis This directory is where the machine-specific configuration files for hostname `cloud` live, my primary desktop. These files get called by the root `flake.nix` file. + +### `TODO` list + +- Migrate to (disko)[https://github.com/nix-community/disko] diff --git a/modules/machine/cloud/configuration.nix b/modules/machine/cloud/configuration.nix index f62f39e..4ebc39f 100644 --- a/modules/machine/cloud/configuration.nix +++ b/modules/machine/cloud/configuration.nix @@ -3,9 +3,12 @@ pkgs, userName, ... -}: { +}: let + timeZone = null; +in { imports = [ ../../apps/flatpak.nix + ../../pwrMgmt ../../sound/pipewire.nix ../../sound/shairport.nix ../../virtualization/podman.nix @@ -24,7 +27,7 @@ hardware.bluetooth.enable = true; # Set your timezone - time.timeZone = "America/Detroit"; + time.timeZone = timeZone ? "America/Detroit"; # Enable touchpad services.libinput.enable = true; @@ -35,11 +38,6 @@ neovim git wireguard-tools - buildah - podman-tui - podman-compose - podman-desktop - toolbox grim slurp playerctl @@ -83,25 +81,63 @@ # Enable Polkit security.polkit.enable = true; - # Enable power management - powerManagement = { - enable = true; - powertop.enable = false; # TODO: to be enabled on laptops - cpuFreqGovernor = "performace"; + # Gaming module (see ../../apps/gaming.nix) + customGaming = { + steam = { + enable = true; + firewall = { + remotePlay = true; + localNetworkGameTransfers = true; + }; + }; + gamemode.enable = true; + gamescope.enable = true; + lutris = { + enable = true; + wine = { + enable = true; + package = pkgs.wine; + }; + compatibility = { + protonSupport = true; + extraTools = with pkgs; [ + proton-ge-custom + ]; + }; + extraPackages = with pkgs; [ + gamemode + mangohud + ]; + }; + + minecraft.enable = true; }; - # Enable Steam and open various firewall ports when applicable - programs.steam = { + # Power management (see ../../pwrMgmt/default.nix) + customPowerManagement = { enable = true; - remotePlay.openFirewall = true; - localNetworkGameTransfers.openFirewall = true; + cpuFreqGovernor = "performance"; + powertop.enable = false; }; - # Enable gamemode (gamemode, gamemoded, gamemoderun) when needed - programs.gamemode.enable = true; + podman = { + podman = { + enable = true; + extraPackages = with pkgs; [ + docker-credential-helpers + toolbox + cosign + crane + podman-tui + podman-desktop + ]; + }; + }; - # Enable gamescope (compositor) when needed - programs.gamescope.enable = true; + customNetworking = { + firewall.enable = true; + networkManager.enable = true; + }; # Enable dconf programs.dconf.enable = true; @@ -135,17 +171,5 @@ networking.firewall.allowedUDPPorts = []; networking.networkmanager.enable = true; # Linux tool for managing network connections - # Enable Podman (OCI containers) - virtualisation.podman = { - enable = true; - dockerSocket.enable = true; - defaultNetwork.settings.dns_enabled = true; - }; - - # users.users."${userName}" = { - # group = "${userName}"; - # isNormalUser = true; - # }; - system.stateVersion = "24.05"; } diff --git a/modules/machine/sephiroth/configuration.nix b/modules/machine/sephiroth/configuration.nix index d234627..26c7a51 100644 --- a/modules/machine/sephiroth/configuration.nix +++ b/modules/machine/sephiroth/configuration.nix @@ -167,6 +167,17 @@ system.stateVersion = 5; + containers.podman = { + enable = true; + dockerCompat = false; + extraPackages = with pkgs; [ + podman-tui + docker-credential-helpers + cosign + crane + ]; + }; + # Set your time zone. time.timeZone = "America/Detroit"; } diff --git a/modules/networking/README.md b/modules/networking/README.md new file mode 100644 index 0000000..fff25ce --- /dev/null +++ b/modules/networking/README.md @@ -0,0 +1,90 @@ +# Network and networking modules + +This directory houses all network, firewall, DHCP, DNS, and all other related networking enablement. + +## `core.nix` + +This is where the firewall and NetworkManager live. For the firewall, you have pre-defined options that will open ports for you by enabling some network service. + +For example: + +```nix +tcpPorts.web.enable = true; +udpPorts.dns.enable = true; +``` + +Here's a more featureful example of how you would enable a firewall and set up NetworkManager: + +```nix + customNetworking = { + firewall = { + enable = true; + + # Open web service ports + tcpPorts.web.enable = true; + + # Custom TCP ports + tcpPorts.allowedPorts = [ 8080 22 ]; + + # Custom UDP ports + udpPorts.allowedPorts = [ 5000 ]; + }; + + networkManager = { + enable = true; + extraPlugins = with pkgs; [ + # Additional NetworkManager plugins + networkmanager-openvpn + networkmanager-openconnect + ]; + }; + }; +``` + +As shown above, you'll have to open ports for services you would want to access remotely. + +## DNS + +There are two options here: BIND9 (or simply Bind) or Technitium DNS server. Enabling both DNS servers will throw an error and your configuration will not build. + +You'll have to import `./dns.nix` for the services to be enabled. + +Here's an example of what configuration might look like: + +```nix + dns.bind = { + enable = true; + settings = { + interfaces = [ "127.0.0.1" "192.168.100.100" ]; + zones = [ + { + name = "example.com"; + type = "master"; + file = "/etc/named/zones/example.com.zone"; + } + ]; + extraConfig = '' + // Additional BIND configuration + options { + directory "/var/named"; + recursion yes; + } + ''; + } + }; +``` + +_or_ + +```nix + dns.technitium = { + enable = true; + settings = { + address = "192.168.100.0"; + port = 5380; + extraOptions = { + LOG_LEVEL = "info"; + }; + } + }; +``` diff --git a/modules/networking/core.nix b/modules/networking/core.nix new file mode 100644 index 0000000..c7e0500 --- /dev/null +++ b/modules/networking/core.nix @@ -0,0 +1,145 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.customNetworking; +in { + options.customNetworking = { + # Firewall Configuration + firewall = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable system firewall"; + }; + + tcpPorts = { + # Predefined, default common service ports + ssh = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open SSH service port (22)"; + }; + }; + web = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open common web service ports (80, 443)"; + }; + }; + smtp = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open SMTP service ports (25, 465, 587)"; + }; + }; + imap = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open IMAP service ports (143, 993)"; + }; + }; + mysql = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open MySQL service port (3306)"; + }; + }; + mssql = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open Microsoft SQL Server service port (1433)"; + }; + }; + postgres = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open Postgres service port (5432)"; + }; + }; + allowedPorts = lib.mkOption { + type = lib.types.listOf lib.types.port; + default = []; + description = "List of custom TCP ports to open"; + }; + }; + + udpPorts = { + dns = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open DNS service port (53)"; + }; + }; + ntp = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open NTP service port (123)"; + }; + }; + allowedPorts = lib.mkOption { + type = lib.types.listOf lib.types.port; + default = []; + description = "List of custom UDP ports to open"; + }; + }; + }; + + networkManager = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable NetworkManager for network connection management"; + }; + + extraPlugins = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + description = "Additional NetworkManager plugins to install"; + }; + }; + }; + + config = { + networking.firewall = { + enable = cfg.firewall.enable; + + allowedTCPPorts = + ( + lib.optionals + cfg.firewall.tcpPorts.ssh.enable [22] + cfg.firewall.tcpPorts.web.enable [80 443] + cfg.firewall.tcpPorts.smtp.enable [25 465 587] + cfg.firewall.tcpPorts.imap.enable [143 993] + cfg.firewall.tcpPorts.mysql.enable [3306] + cfg.firewall.tcpPorts.mssql.enable [1433] + cfg.firewall.tcpPorts.postgres.enable [5432] + ) + ++ cfg.firewall.tcpPorts.allowedPorts; + + allowedUDPPorts = + ( + lib.optionals + cfg.firewall.udpPorts.dns.enable [53] + cfg.firewall.udpPorts.ntp.enable [123] + ) + ++ cfg.firewall.udpPorts.allowedPorts; + }; + + networking.networkmanager = { + enable = cfg.networkManager.enable; + packages = cfg.networkManager.extraPlugins; + }; + }; +} diff --git a/modules/networking/dns.nix b/modules/networking/dns.nix new file mode 100644 index 0000000..1a94c8b --- /dev/null +++ b/modules/networking/dns.nix @@ -0,0 +1,133 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.dns; +in { + options.dns = { + bind = { + enable = lib.mkEnableOption "BIND DNS server"; + settings = { + interfaces = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = ["127.0.0.1"]; + description = "Network interfaces BIND should listen on"; + }; + + zones = lib.mkOption { + type = lib.types.listOf (lib.types.submodule { + options = { + name = lib.mkOption { + type = lib.types.str; + description = "Name of the DNS zone"; + }; + type = lib.mkOption { + type = lib.types.enum ["master" "slave"]; + default = "master"; + description = "Type of DNS zone"; + }; + file = lib.mkOption { + type = lib.types.str; + default = ""; + description = "Path to zone file"; + }; + }; + }); + default = []; + description = "DNS zones to configure"; + }; + + extraConfig = lib.mkOption { + type = lib.types.lines; + default = ""; + description = "Additional BIND configuration options"; + }; + }; + }; + + technitium = { + enable = lib.mkEnableOption "Technitium DNS server"; + settings = { + address = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "IP address Technitium should listen on"; + }; + port = lib.mkOption { + type = lib.types.port; + default = 5380; + description = "Port for Technitium DNS server"; + }; + extraOptions = lib.mkOption { + type = lib.types.attrs; + default = {}; + description = "Additional Technitium configuration options"; + }; + }; + }; + }; + + # Validate that only one DNS server is enabled + imports = [ + (lib.mkIf (cfg.bind.enable && cfg.technitium.enable) (throw "Only one DNS server can be enabled at a time")) + ]; + + # Implementation of the configuration + config = lib.mkMerge [ + # BIND DNS Server Configuration + (lib.mkIf cfg.bind.enable { + services.named = { + enable = true; + interfaces = cfg.bind.settings.interfaces; + zones = + map (zone: { + name = zone.name; + type = zone.type; + file = zone.file; + }) + cfg.bind.settings.zones; + extraConfig = cfg.bind.settings.extraConfig; + }; + networking.firewall = { + allowedTCPPorts = [53]; + allowedUDPPorts = [53]; + }; + environment.systemPackages = [pkgs.bind]; + }) + + # Technitium DNS Server Configuration + (lib.mkIf cfg.technitium.enable { + # Create a systemd service for Technitium + systemd.services.technitium-dns = { + description = "Technitium DNS Server"; + wantedBy = ["multi-user.target"]; + + serviceConfig = { + ExecStart = "${pkgs.technitium}/bin/dns-server-start.sh"; + Restart = "on-failure"; + }; + + # Environment configuration + environment = + { + DNS_LISTEN_ADDRESS = cfg.technitium.settings.address; + DNS_LISTEN_PORT = toString cfg.technitium.settings.port; + } + // lib.mapAttrs' ( + name: value: + lib.nameValuePair "DNS_${lib.toUpper name}" (toString value) + ) + cfg.technitium.settings.extraOptions; + }; + + networking.firewall = { + allowedTCPPorts = [cfg.technitium.settings.port]; + allowedUDPPorts = [cfg.technitium.settings.port]; + }; + + environment.systemPackages = [pkgs.technitium]; + }) + ]; +} diff --git a/modules/pwrMgmt/README.md b/modules/pwrMgmt/README.md new file mode 100644 index 0000000..04349d0 --- /dev/null +++ b/modules/pwrMgmt/README.md @@ -0,0 +1,48 @@ +# Power management modules + +This directory houses my own custom defined power management settings. These are set in the machine-specific configurations (typically). + +## Examples + +Given that this configuration is in the `machine/` directory (where hostname is the name of the computer your configuring): + +### Desktop configuration + +```nix + imports = [ + ../../pwrMgmt + # other configuration files here... + ]; + + customPowerManagement = { + enable = true; + cpuFreqGovernor = "performance"; + powertop.enable = false; + }; +``` + +### Laptop configuration + +```nix + imports = [ + ../../pwrMgmt + # other configuration files here... + ]; + + customPowerManagement = { + enable = true; + cpuFreqGovernor = "powersave"; + powertop = { + enable = true; + autotuneOnBoot = true; + }; + battery = { + enable = true; + startChargeThreshold = 40; + stopChargeThreshold = 75; + }; + }; + +``` + +Remember, these are just examples. Please suit these examples to fit your specific hardware. diff --git a/modules/pwrMgmt/default.nix b/modules/pwrMgmt/default.nix new file mode 100644 index 0000000..8a9f2b9 --- /dev/null +++ b/modules/pwrMgmt/default.nix @@ -0,0 +1,73 @@ +{ + config, + lib, + ... +}: let + # Define a more flexible power management module + cfg = config.pwrMgnt; +in { + # Define options for customizable power management + options.pwrMgnt = { + enable = lib.mkEnableOption "Custom power management configuration"; + + cpuFreqGovernor = lib.mkOption { + type = lib.types.enum [ + "performance" + "powersave" + "ondemand" + "conservative" + ]; + default = "performance"; + description = "CPU frequency scaling governor to use"; + }; + + # PowerTop Configuration + powertop = { + enable = lib.mkEnableOption "PowerTop power management tool"; + + autotuneOnBoot = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Automatically tune power settings on boot"; + }; + }; + + # Battery-specific settings (for laptops) + battery = { + enable = lib.mkEnableOption "Battery-specific power management"; + + startChargeThreshold = lib.mkOption { + type = lib.types.int; + default = 20; + description = "Percentage at which to start charging"; + }; + + stopChargeThreshold = lib.mkOption { + type = lib.types.int; + default = 80; + description = "Percentage at which to stop charging"; + }; + }; + }; + + config = lib.mkIf cfg.enable { + powerManagement = { + enable = true; + cpuFreqGovernor = cfg.cpuFreqGovernor; + }; + + services.powertop.enable = cfg.powertop.enable; + systemd.services.battery-charge-threshold = lib.mkIf cfg.battery.enable { + description = "Set battery charge thresholds"; + wantedBy = ["multi-user.target"]; + script = '' + if [ -f /sys/class/power_supply/BAT0/charge_start_threshold ]; then + echo ${toString cfg.battery.startChargeThreshold} > /sys/class/power_supply/BAT0/charge_start_threshold + fi + if [ -f /sys/class/power_supply/BAT0/charge_stop_threshold ]; then + echo ${toString cfg.battery.stopChargeThreshold} > /sys/class/power_supply/BAT0/charge_stop_threshold + fi + ''; + }; + }; +} diff --git a/modules/sound/README.md b/modules/sound/README.md new file mode 100644 index 0000000..2859c8c --- /dev/null +++ b/modules/sound/README.md @@ -0,0 +1,19 @@ +# Sound and audio modules + +This directory houses all sound and audio modules for a given system. + +## Pipewire + +Pipewire is the new kid on the block, and frankly, this new kid cleans the streets. With Pulseaudio and ALSA compatibility, this is basically the _defacto_ audio solution for every Linux workstation. + +Although, for some use cases, expect me to write a Pulseaudio or an ALSA module here soon :P + +All that's needed to get this working to import the `./pipewire.nix` into your machine's configuration. + +## Shairport + +This is a program where your computer is enabled with AirPlay! How cool is that?? + +All that's needed to get this working to import the `./shairport.nix` into your machine's configuration. + +Note that this _only_ works with Pipewire. diff --git a/modules/virtualization/README.md b/modules/virtualization/README.md new file mode 100644 index 0000000..807ab08 --- /dev/null +++ b/modules/virtualization/README.md @@ -0,0 +1,51 @@ +# Virtualization modules + +This directory houses all virtualization and container related enablement. Cloud native anyone?? + +## Hardware virtualization + +This is for running virtual machines on the bare metal. + +All that's needed to get this working to import the `./hardware.nix` into your machine's configuration. + +## Docker (OCI containers) + +This is for running the Docker runtime (rootful or rootless, rootful by default) to run OCI containers. + +All that's needed to get this working to import the `./docker.nix` into your machine's configuration. + +Note: I don't use Docker too much as I use Podman for development. I'd check the Podman documentation. + +## Podman/Buildah (OCI containers) + +This is for running the Podman runtime (rootless) to run OCI containers. + +You will need to import `./podman.nix` into your machine configuration. Additionally, there's some added configuration to suit your needs. + +Example: + +```nix + podman = { + podman = { + enable = true; + extraPackages = with pkgs; [ + docker-credential-helpers + toolbox + cosign + crane + podman-tui + podman-desktop + ]; + }; + }; +``` + +To get a full, comprehensive list of what you can do with the podman module, please check out (podman.nix)[./podman.nix]! + +## Kubernetes + +Coming soon! + +## LXC/LXD + +I don't have anything in the way of a nix configuration for LXC/LXD as I don't have a use-case for them. Come back later! diff --git a/modules/virtualization/docker.nix b/modules/virtualization/docker.nix index 25f7831..ab223bf 100644 --- a/modules/virtualization/docker.nix +++ b/modules/virtualization/docker.nix @@ -2,5 +2,6 @@ virtualisation.docker = { enable = true; enableOnBoot = true; + rootless = false; }; } diff --git a/modules/virtualization/podman.nix b/modules/virtualization/podman.nix index b9e685a..495c4fd 100644 --- a/modules/virtualization/podman.nix +++ b/modules/virtualization/podman.nix @@ -1,7 +1,39 @@ -{...}: { - virtualisation.podman = { - enable = true; - dockerSocket.enable = true; - defaultNetwork.settings.dns_enabled = true; +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.containers; +in { + options.containers = { + podman = { + enable = lib.mkEnableOption "Podman container runtime"; + dockerCompat = lib.mkEnableOption "Enable Docker compatibility"; + extraPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + description = "Additional packages to install when Podman is enabled"; + }; + }; + }; + + config = lib.mkIf cfg.podman.enable { + virtualisation.podman = { + enable = true; + dockerCompat = cfg.podman.dockerCompat; + enableOnBoot = true; + defaultNetwork.settings.dns_enabled = true; + }; + + environment.systemPackages = + [ + pkgs.podman-compose + pkgs.buildah + pkgs.skopeo + pkgs.dive + pkgs.container-diff + ] + ++ cfg.podman.extraPackages; }; }