modules for ports
This commit is contained in:
261
modules/home-manager/ports.nix
Normal file
261
modules/home-manager/ports.nix
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
# Home Manager Module for Port Management
|
||||||
|
#
|
||||||
|
# This module provides centralized port management for Home Manager configurations.
|
||||||
|
# Define ports once and use them consistently across user services, with support
|
||||||
|
# for host-specific overrides.
|
||||||
|
#
|
||||||
|
# Usage in your Home Manager configuration:
|
||||||
|
#
|
||||||
|
# # In your home.nix or flake:
|
||||||
|
# imports = [ inputs.m3ta-nixpkgs.homeManagerModules.default ];
|
||||||
|
#
|
||||||
|
# m3ta.ports = {
|
||||||
|
# enable = true;
|
||||||
|
#
|
||||||
|
# # Define your default ports
|
||||||
|
# definitions = {
|
||||||
|
# vscodium = 8080;
|
||||||
|
# jupyter = 8888;
|
||||||
|
# dev-server = 3000;
|
||||||
|
# local-api = 8000;
|
||||||
|
# docs-preview = 4000;
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Define host-specific overrides
|
||||||
|
# hostOverrides = {
|
||||||
|
# laptop = {
|
||||||
|
# dev-server = 3001;
|
||||||
|
# vscodium = 8081;
|
||||||
|
# };
|
||||||
|
# desktop = {
|
||||||
|
# jupyter = 9999;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Set the current hostname
|
||||||
|
# currentHost = "laptop"; # Or use config.networking.hostName if available
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Use ports in your configuration:
|
||||||
|
# home.file.".config/myapp/config.json".text = builtins.toJSON {
|
||||||
|
# port = config.m3ta.ports.get "dev-server";
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Generate environment variables:
|
||||||
|
# home.sessionVariables = {
|
||||||
|
# DEV_SERVER_PORT = toString (config.m3ta.ports.get "dev-server");
|
||||||
|
# JUPYTER_PORT = toString (config.m3ta.ports.get "jupyter");
|
||||||
|
# };
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.m3ta.ports;
|
||||||
|
|
||||||
|
# Import the ports library
|
||||||
|
portsLib = import ../../lib/ports.nix {inherit lib;};
|
||||||
|
|
||||||
|
# Create port helpers from the configuration
|
||||||
|
portHelpers =
|
||||||
|
if cfg.enable
|
||||||
|
then
|
||||||
|
portsLib.mkPortHelpers {
|
||||||
|
ports = cfg.definitions;
|
||||||
|
hostPorts = cfg.hostOverrides;
|
||||||
|
}
|
||||||
|
else null;
|
||||||
|
in {
|
||||||
|
options.m3ta.ports = {
|
||||||
|
enable = mkEnableOption "centralized port management for Home Manager";
|
||||||
|
|
||||||
|
definitions = mkOption {
|
||||||
|
type = types.attrsOf types.port;
|
||||||
|
default = {};
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
vscodium = 8080;
|
||||||
|
jupyter = 8888;
|
||||||
|
dev-server = 3000;
|
||||||
|
local-api = 8000;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Default port definitions for user services.
|
||||||
|
These ports will be used unless overridden by host-specific settings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hostOverrides = mkOption {
|
||||||
|
type = types.attrsOf (types.attrsOf types.port);
|
||||||
|
default = {};
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
laptop = {
|
||||||
|
dev-server = 3001;
|
||||||
|
vscodium = 8081;
|
||||||
|
};
|
||||||
|
desktop = {
|
||||||
|
jupyter = 9999;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Host-specific port overrides.
|
||||||
|
Keys are hostnames, values are attribute sets of service-name to port mappings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
currentHost = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
example = "laptop";
|
||||||
|
description = ''
|
||||||
|
The current hostname to use for port resolution.
|
||||||
|
Set to null to disable host-specific overrides.
|
||||||
|
|
||||||
|
Note: In Home Manager, you may need to set this manually unless
|
||||||
|
you pass config.networking.hostName from your NixOS configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Computed option - provides access to port helpers
|
||||||
|
get = mkOption {
|
||||||
|
type = types.functionTo types.port;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Function to get a port for a service.
|
||||||
|
Automatically uses the current host for overrides.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
getForHost = mkOption {
|
||||||
|
type = types.functionTo (types.functionTo types.port);
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Function to get a port for a service on a specific host.
|
||||||
|
Usage: config.m3ta.ports.getForHost "hostname" "service"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
all = mkOption {
|
||||||
|
type = types.attrsOf types.port;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
All ports for the current host (defaults merged with overrides).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
allForHost = mkOption {
|
||||||
|
type = types.functionTo (types.attrsOf types.port);
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Function to get all ports for a specific host.
|
||||||
|
Usage: config.m3ta.ports.allForHost "hostname"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
List of all defined service names.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Convenience option for generating shell variables
|
||||||
|
generateEnvVars = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
Whether to automatically generate environment variables for all ports.
|
||||||
|
Variables will be named as: PORT_<SERVICE_NAME> (uppercase, dashes to underscores).
|
||||||
|
|
||||||
|
Example: service "dev-server" becomes PORT_DEV_SERVER
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
envVarPrefix = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "PORT_";
|
||||||
|
example = "MY_APP_PORT_";
|
||||||
|
description = ''
|
||||||
|
Prefix for generated environment variables when generateEnvVars is enabled.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.definitions != {};
|
||||||
|
message = "m3ta.ports.definitions must not be empty when m3ta.ports.enable is true";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
m3ta.ports = {
|
||||||
|
# Function to get port for current host
|
||||||
|
get = service:
|
||||||
|
assert assertMsg (portHelpers != null) "Port helpers not initialized";
|
||||||
|
assert assertMsg (cfg.definitions ? ${service}) "Service '${service}' not defined in m3ta.ports.definitions";
|
||||||
|
portHelpers.getPort service cfg.currentHost;
|
||||||
|
|
||||||
|
# Function to get port for specific host
|
||||||
|
getForHost = host: service:
|
||||||
|
assert assertMsg (portHelpers != null) "Port helpers not initialized";
|
||||||
|
assert assertMsg (cfg.definitions ? ${service}) "Service '${service}' not defined in m3ta.ports.definitions";
|
||||||
|
portHelpers.getPort service host;
|
||||||
|
|
||||||
|
# All ports for current host
|
||||||
|
all =
|
||||||
|
if portHelpers != null
|
||||||
|
then portHelpers.getHostPorts cfg.currentHost
|
||||||
|
else {};
|
||||||
|
|
||||||
|
# Function to get all ports for specific host
|
||||||
|
allForHost = host:
|
||||||
|
assert assertMsg (portHelpers != null) "Port helpers not initialized";
|
||||||
|
portHelpers.getHostPorts host;
|
||||||
|
|
||||||
|
# List all services
|
||||||
|
services =
|
||||||
|
if portHelpers != null
|
||||||
|
then portHelpers.listServices
|
||||||
|
else [];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: Automatically generate environment variables for all ports
|
||||||
|
home.sessionVariables = mkIf cfg.generateEnvVars (
|
||||||
|
let
|
||||||
|
# Convert service name to env var name: "dev-server" -> "DEV_SERVER"
|
||||||
|
toEnvVarName = service:
|
||||||
|
cfg.envVarPrefix + (lib.toUpper (builtins.replaceStrings ["-"] ["_"] service));
|
||||||
|
in
|
||||||
|
builtins.listToAttrs (
|
||||||
|
map (service: {
|
||||||
|
name = toEnvVarName service;
|
||||||
|
value = toString (cfg.get service);
|
||||||
|
})
|
||||||
|
cfg.services
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
# Create a JSON file with all ports for easy inspection
|
||||||
|
home.file.".config/m3ta/ports.json" = {
|
||||||
|
text = builtins.toJSON {
|
||||||
|
hostname = cfg.currentHost;
|
||||||
|
ports = cfg.all;
|
||||||
|
allDefinitions = cfg.definitions;
|
||||||
|
hostOverrides = cfg.hostOverrides;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
219
modules/nixos/ports.nix
Normal file
219
modules/nixos/ports.nix
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
# NixOS Module for Port Management
|
||||||
|
#
|
||||||
|
# This module provides centralized port management across your NixOS systems.
|
||||||
|
# Define ports once and use them consistently across all services, with
|
||||||
|
# support for host-specific overrides.
|
||||||
|
#
|
||||||
|
# Usage in your NixOS configuration:
|
||||||
|
#
|
||||||
|
# # In your flake.nix or configuration.nix:
|
||||||
|
# imports = [ inputs.m3ta-nixpkgs.nixosModules.default ];
|
||||||
|
#
|
||||||
|
# m3ta.ports = {
|
||||||
|
# enable = true;
|
||||||
|
#
|
||||||
|
# # Define your default ports
|
||||||
|
# definitions = {
|
||||||
|
# nginx = 80;
|
||||||
|
# grafana = 3000;
|
||||||
|
# prometheus = 9090;
|
||||||
|
# homepage = 8080;
|
||||||
|
# ssh = 22;
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Define host-specific overrides
|
||||||
|
# hostOverrides = {
|
||||||
|
# laptop = {
|
||||||
|
# nginx = 8080; # Use non-privileged port on laptop
|
||||||
|
# ssh = 2222;
|
||||||
|
# };
|
||||||
|
# server = {
|
||||||
|
# homepage = 3001;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Optionally set the current hostname for automatic port resolution
|
||||||
|
# currentHost = config.networking.hostName;
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# # Use ports in your configuration:
|
||||||
|
# services.nginx.defaultHTTPListenPort = config.m3ta.ports.get "nginx";
|
||||||
|
# services.grafana.settings.server.http_port = config.m3ta.ports.get "grafana";
|
||||||
|
#
|
||||||
|
# # Or access all ports for the current host:
|
||||||
|
# environment.etc."my-ports.json".text = builtins.toJSON config.m3ta.ports.all;
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.m3ta.ports;
|
||||||
|
|
||||||
|
# Import the ports library
|
||||||
|
portsLib = import ../../lib/ports.nix {inherit lib;};
|
||||||
|
|
||||||
|
# Create port helpers from the configuration
|
||||||
|
portHelpers =
|
||||||
|
if cfg.enable
|
||||||
|
then
|
||||||
|
portsLib.mkPortHelpers {
|
||||||
|
ports = cfg.definitions;
|
||||||
|
hostPorts = cfg.hostOverrides;
|
||||||
|
}
|
||||||
|
else null;
|
||||||
|
in {
|
||||||
|
options.m3ta.ports = {
|
||||||
|
enable = mkEnableOption "centralized port management";
|
||||||
|
|
||||||
|
definitions = mkOption {
|
||||||
|
type = types.attrsOf types.port;
|
||||||
|
default = {};
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
nginx = 80;
|
||||||
|
grafana = 3000;
|
||||||
|
prometheus = 9090;
|
||||||
|
ssh = 22;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Default port definitions for services.
|
||||||
|
These ports will be used unless overridden by host-specific settings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hostOverrides = mkOption {
|
||||||
|
type = types.attrsOf (types.attrsOf types.port);
|
||||||
|
default = {};
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
laptop = {
|
||||||
|
nginx = 8080;
|
||||||
|
ssh = 2222;
|
||||||
|
};
|
||||||
|
server = {
|
||||||
|
nginx = 443;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Host-specific port overrides.
|
||||||
|
Keys are hostnames, values are attribute sets of service-name to port mappings.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
currentHost = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = config.networking.hostName;
|
||||||
|
defaultText = literalExpression "config.networking.hostName";
|
||||||
|
example = "laptop";
|
||||||
|
description = ''
|
||||||
|
The current hostname to use for port resolution.
|
||||||
|
Defaults to the system's hostname.
|
||||||
|
Set to null to disable host-specific overrides.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Computed option - provides access to port helpers
|
||||||
|
get = mkOption {
|
||||||
|
type = types.functionTo types.port;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Function to get a port for a service.
|
||||||
|
Automatically uses the current host for overrides.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
getForHost = mkOption {
|
||||||
|
type = types.functionTo (types.functionTo types.port);
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Function to get a port for a service on a specific host.
|
||||||
|
Usage: config.m3ta.ports.getForHost "hostname" "service"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
all = mkOption {
|
||||||
|
type = types.attrsOf types.port;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
All ports for the current host (defaults merged with overrides).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
allForHost = mkOption {
|
||||||
|
type = types.functionTo (types.attrsOf types.port);
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Function to get all ports for a specific host.
|
||||||
|
Usage: config.m3ta.ports.allForHost "hostname"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
List of all defined service names.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.definitions != {};
|
||||||
|
message = "m3ta.ports.definitions must not be empty when m3ta.ports.enable is true";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
m3ta.ports = {
|
||||||
|
# Function to get port for current host
|
||||||
|
get = service:
|
||||||
|
assert assertMsg (portHelpers != null) "Port helpers not initialized";
|
||||||
|
assert assertMsg (cfg.definitions ? ${service}) "Service '${service}' not defined in m3ta.ports.definitions";
|
||||||
|
portHelpers.getPort service cfg.currentHost;
|
||||||
|
|
||||||
|
# Function to get port for specific host
|
||||||
|
getForHost = host: service:
|
||||||
|
assert assertMsg (portHelpers != null) "Port helpers not initialized";
|
||||||
|
assert assertMsg (cfg.definitions ? ${service}) "Service '${service}' not defined in m3ta.ports.definitions";
|
||||||
|
portHelpers.getPort service host;
|
||||||
|
|
||||||
|
# All ports for current host
|
||||||
|
all =
|
||||||
|
if portHelpers != null
|
||||||
|
then portHelpers.getHostPorts cfg.currentHost
|
||||||
|
else {};
|
||||||
|
|
||||||
|
# Function to get all ports for specific host
|
||||||
|
allForHost = host:
|
||||||
|
assert assertMsg (portHelpers != null) "Port helpers not initialized";
|
||||||
|
portHelpers.getHostPorts host;
|
||||||
|
|
||||||
|
# List all services
|
||||||
|
services =
|
||||||
|
if portHelpers != null
|
||||||
|
then portHelpers.listServices
|
||||||
|
else [];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: Create a JSON file with all ports for easy inspection
|
||||||
|
environment.etc."m3ta/ports.json" = mkIf cfg.enable {
|
||||||
|
text = builtins.toJSON {
|
||||||
|
hostname = cfg.currentHost;
|
||||||
|
ports = cfg.all;
|
||||||
|
allDefinitions = cfg.definitions;
|
||||||
|
hostOverrides = cfg.hostOverrides;
|
||||||
|
};
|
||||||
|
mode = "0444";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user