Skip to content

Commit

Permalink
nixos/ca-gateway: init module
Browse files Browse the repository at this point in the history
  • Loading branch information
minijackson committed Oct 11, 2023
1 parent 751e8c9 commit 6b21739
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
1 change: 1 addition & 0 deletions nixos/module-list.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[
./modules/archiver-appliance.nix
./modules/ca-gateway.nix
./modules/phoebus/alarm-logger.nix
./modules/phoebus/alarm-server.nix
./modules/phoebus/local-kafka.nix
Expand Down
196 changes: 196 additions & 0 deletions nixos/modules/ca-gateway.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.services.ca-gateway;
pkg = pkgs.epnix.ca-gateway;

# the CA gateway doesn't use the long/short options conventions
mkOptionName = k: "-${k}";
# List are for IP address lists
mkList = k: v: [(mkOptionName k) (lib.concatStringsSep " " v)];
toCommandLine = lib.cli.toGNUCommandLine {inherit mkOptionName mkList;};

commandLine = lib.escapeShellArgs (toCommandLine cfg.settings);
in {
options.services.ca-gateway = {
enable = lib.mkEnableOption "the Channel Access PV gateway";

openFirewall = lib.mkOption {
description = ''
Open the firewall for allowing Channel Access communications.
Warning: this opens the firewall on all network interfaces.
'';
type = lib.types.bool;
default = false;
};

settings = lib.mkOption {
description = ''
Configuration for the Channel Access PV gateway.
These options are passed onto the gateway command-line.
Available options can be seen here:
<https://epics.anl.gov/EpicsDocumentation/ExtensionsManuals/Gateway/Gateway.html#Starting>
'';
default = {};
type = lib.types.submodule {
freeformType = with lib.types;
nullOr (oneOf [
bool
int
float
str
path
(listOf str)
]);
options = {
pvlist = lib.mkOption {
description = ''
Name of file with all the allowed PVs in it.
See the sample file gateway.pvlist in the source distribution
for a description of how to create this file:
<https://github.com/epics-extensions/ca-gateway/blob/v${pkg.version}/example/GATEWAY.pvlist>
'';
type = with lib.types; nullOr (either path str);
default = null;
example = lib.literalExpression ''
pkgs.writeText "gateway.pvlist" '''
EVALUATION ORDER DENY, ALLOW
* DENY
MY_PV ALLOW
# ...
'''
'';
};

access = lib.mkOption {
description = ''
Name of file with all the EPICS access security rules in it.
PVs in the pvlist file use groups and rules defined in this file.
See the sample file gateway.pvlist in the source distribution:
<https://github.com/epics-extensions/ca-gateway/blob/v${pkg.version}/example/GATEWAY.access>
'';
type = with lib.types; nullOr (either path str);
default = null;
example = lib.literalExpression ''
pkgs.writeText "gateway.access" '''
UAG(GatewayAdmin) {gateway,smith}
# ...
'''
'';
};

sip = lib.mkOption {
description = ''
IP address list that gateway's CA server listens for PV requests.
Sets env variable `EPICS_CAS_INTF_ADDR_LIST`.
By default, the CA server is accessible from all network interfaces configured into its host.
'';
type = with lib.types; nullOr (listOf str);
default = null;
example = ["192.168.1.1"];
};

signore = lib.mkOption {
description = ''
IP address list that gateway's CA server ignores.
Sets env variable `EPICS_CAS_IGNORE_ADDR_LIST`.
'';
type = with lib.types; nullOr (listOf str);
default = null;
example = ["192.168.1.5" "192.168.1.42"];
};

sport = lib.mkOption {
description = ''
The port which the gateway's CA server uses to listen for PV requests.
Sets environment variable `EPICS_CAS_SERVER_PORT`.
'';
type = lib.types.port;
default = 5064;
};

cip = lib.mkOption {
description = ''
IP address list that the gateway's CA client uses to find the real PVs.
See CA reference manual.
This sets environment variables `EPICS_CA_AUTO_LIST=NO` and `EPICS_CA_ADDR_LIST`.
'';
type = with lib.types; nullOr (listOf str);
default = null;
example = ["192.168.1.4" "192.168.1.3"];
};

cport = lib.mkOption {
description = ''
The port which the gateway's CA client uses to find the real PVs.
Sets environment variable `EPICS_CA_SERVER_PORT`.
'';
type = lib.types.port;
default = 5064;
};
};
};
};
};

config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.settings ? server -> !cfg.settings.server;
message = "the ca-gateway 'server' option is incompatible with systemd";
}
];

systemd.services.ca-gateway = {
description = "Channel Access PV gateway";

wantedBy = ["multi-user.target"];

# When initializing the IOC, PV Access looks for network interfaces that
# have IP addresses. "network.target" may be too early, especially for
# systems with DHCP.
wants = ["network-online.target"];
after = ["network-online.target"];

serviceConfig = {
ExecStart = "${pkg}/bin/gateway ${commandLine}";
DynamicUser = true;
};
};

networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [
cfg.settings.sport
cfg.settings.cport
];

networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [
cfg.settings.sport
cfg.settings.cport

# Repeater port
5065
];
};
}

0 comments on commit 6b21739

Please sign in to comment.