Skip to content

Commit acb9e5a

Browse files
committed
docs: add user-guide for IOC services
1 parent 02145d0 commit acb9e5a

File tree

5 files changed

+303
-5
lines changed

5 files changed

+303
-5
lines changed

docs/conf.py

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
pygments_style = "pygments_styles.EpnixNordLight"
5050
pygments_dark_style = "pygments_styles.EpnixNordDarker"
5151

52+
manpages_url = "https://manpages.debian.org/{path}"
53+
5254
# -- Options for MyST --------------------------------------------------------
5355
# https://myst-parser.readthedocs.io/en/latest/configuration.html
5456

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
IOC services
2+
============
3+
4+
.. seealso::
5+
To learn how to deploy IOCs on NixOS,
6+
see the :doc:`../user-guides/ioc-services` guide.
7+
8+
.. nix:automodule:: services.iocs

docs/nixos-services/user-guides/index.rst

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ User guides
88
----
99

1010
.. toctree::
11-
:maxdepth: 1
11+
:maxdepth: 2
12+
:glob:
1213

13-
./ca-gateway.rst
14-
./channel-finder.rst
15-
./phoebus-alarm.rst
16-
./phoebus-save-and-restore.rst
14+
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
IOC services
2+
============
3+
4+
This guide covers how to install EPICS IOCs as a systemd service
5+
on a NixOS machine.
6+
7+
.. include:: ./pre-requisites.rst
8+
9+
Exposing a service from your IOC
10+
--------------------------------
11+
12+
If your EPICS top and your NixOS configuration are in two different repositories,
13+
the recommended way to integrate your IOC is
14+
to add the configuration inside your EPICS top repository.
15+
This configuration will be exposed,
16+
so that you can use it inside your NixOS configuration repository.
17+
18+
From your EPICS top repository,
19+
make sure your :file:`flake.nix` has these lines:
20+
21+
.. code-block:: nix
22+
:caption: :file:`flake.nix` --- Exposed NixOS settings from your EPICS top
23+
:emphasize-lines: 5-12
24+
25+
overlays.default = final: _prev: {
26+
myIoc = final.callPackage ./ioc.nix {};
27+
};
28+
29+
nixosModules.iocService = {config, ...}: {
30+
services.iocs.myIoc = {
31+
description = "An optional description of your IOC";
32+
package = self.packages.x86_64-linux.default;
33+
# Directory where to find the 'st.cmd' file
34+
workingDirectory = "iocBoot/iocMyIoc";
35+
};
36+
};
37+
38+
Make sure ``description`` and ``workingDirectory`` are correct.
39+
The ``workingDirectory`` must point
40+
to the directory containing the ``st.cmd`` file to run.
41+
42+
If you need a file other than ``st.cmd``,
43+
see :ref:`custom_cmd`.
44+
45+
.. seealso::
46+
For a complete list of all IOC service-related options,
47+
see :nix:option:`services.iocs`.
48+
49+
Importing the exposed service
50+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51+
52+
From your NixOS configuration repository,
53+
in your :file:`flake.nix`,
54+
add your EPICS top as a flake input,
55+
and import the exposed service:
56+
57+
.. code-block:: nix
58+
:caption: :file:`flake.nix` --- Importing the IOC service from your NixOS configuration
59+
:emphasize-lines: 5,12,17
60+
61+
{
62+
# ...
63+
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
64+
inputs.epnix.url = "github:epics-extensions/EPNix/nixos-24.11";
65+
inputs.myTop.url = "git+ssh://git@my-gitlab-server.com/EPICS/myTop.git";
66+
67+
# ...
68+
outputs = {
69+
self,
70+
nixpkgs,
71+
epnix,
72+
myTop,
73+
}: {
74+
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
75+
modules = [
76+
epnix.nixosModules.nixos
77+
myTop.nixosModules.iocService
78+
79+
# ...
80+
];
81+
};
82+
};
83+
}
84+
85+
Then apply your NixOS configuration.
86+
87+
Adding an external IOC
88+
----------------------
89+
90+
As an alternative,
91+
if the IOC you want to run doesn't expose a pre-configured service,
92+
or if you don't wan't to use that configuration,
93+
you can define it directly in your NixOS configuration.
94+
95+
From your NixOS configuration repository,
96+
add your EPICS top to your flake inputs and overlays.
97+
For example:
98+
99+
.. code-block:: nix
100+
:caption: :file:`flake.nix` --- Adding your top to your flake inputs and overlays
101+
:emphasize-lines: 5,12,19-28
102+
103+
{
104+
# ...
105+
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
106+
inputs.epnix.url = "github:epics-extensions/EPNix/nixos-24.11";
107+
inputs.myTop.url = "git+ssh://git@my-gitlab-server.com/EPICS/myTop.git";
108+
109+
# ...
110+
outputs = {
111+
self,
112+
nixpkgs,
113+
epnix,
114+
myTop,
115+
}: {
116+
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
117+
modules = [
118+
epnix.nixosModules.nixos
119+
# ...
120+
121+
{
122+
nixpkgs.overlays = [
123+
(final: prev: {
124+
# Add 'myTop' to the set of 'pkgs'
125+
myTop = myTop.packages.x86_64-linux.default;
126+
# Add your other tops here, for example:
127+
#myOtherTop = myOtherTop.packages.x86_64-linux.default;
128+
})
129+
];
130+
}
131+
];
132+
};
133+
};
134+
}
135+
136+
Then create an :file:`{myIoc}.nix` file:
137+
138+
.. code-block:: nix
139+
:caption: :file:`{myIoc}.nix` --- IOC configuration example
140+
141+
{ pkgs, ... }:
142+
{
143+
# Replace 'myIoc' below with the name of your IOC
144+
services.iocs.myIoc = {
145+
description = "An optional description of your IOC";
146+
package = pkgs.myTop;
147+
# Directory where to find the 'st.cmd' file
148+
workingDirectory = "iocBoot/iocMyIoc";
149+
};
150+
}
151+
152+
Make sure to import it in your :file:`flake.nix`.
153+
154+
.. seealso::
155+
For a list of all IOC-related options,
156+
see :nix:option:`services.iocs`.
157+
158+
.. _custom_cmd:
159+
160+
Custom cmd file
161+
---------------
162+
163+
If your IOC is started through a script other than a file :file:`st.cmd`,
164+
set the option :nix:option:`services.iocs.<name>.startupScript` to you cmd script.
165+
166+
Custom procServ options
167+
-----------------------
168+
169+
To change the procServ port,
170+
use :nix:option:`services.iocs.<name>.procServ.port`.
171+
172+
To change or add procServ options,
173+
use :nix:option:`services.iocs.<name>.procServ.options`.
174+
175+
For example:
176+
177+
.. code-block:: nix
178+
:caption: Changing the default ``procServ`` options
179+
180+
services.iocs.myIoc = {
181+
package = pkgs.myTop;
182+
# Directory where to find the 'st.cmd' file
183+
workingDirectory = "iocBoot/iocMyIoc";
184+
185+
procServ = {
186+
# Set the port procServ listens to
187+
port = 2001;
188+
# Add an option `--killcmd "^b"`
189+
options.killcmd = "^b";
190+
};
191+
};
192+
193+
Passing environment variables
194+
-----------------------------
195+
196+
You can set environment variables for your IOC
197+
by using the option :nix:option:`services.iocs.<name>.environment`.
198+
For example:
199+
200+
.. code-block:: nix
201+
:caption: Setting environment variables
202+
:emphasize-lines: 5
203+
204+
services.iocs.myIoc = {
205+
package = pkgs.myTop;
206+
workingDirectory = "iocBoot/iocMyIoc";
207+
208+
environment.EPICS_CA_MAX_ARRAY_BYTES = 10000;
209+
};
210+
211+
Adding programs to the PATH
212+
---------------------------
213+
214+
If your IOC calls external programs,
215+
you need to add those programs to your IOC's PATH.
216+
217+
To do this,
218+
use the option :nix:option:`services.iocs.<name>.path`.
219+
For example:
220+
221+
.. code-block:: nix
222+
:caption: Adding programs to the IOC's PATH
223+
:emphasize-lines: 1,7
224+
225+
{pkgs, ...}:
226+
{
227+
services.iocs.myIoc = {
228+
package = pkgs.myTop;
229+
workingDirectory = "iocBoot/iocMyIoc";
230+
231+
path = [pkgs.pciutils];
232+
};
233+
}
234+
235+
.. tip::
236+
237+
Programs installed via the ``environment.systemPackages`` option are *not* available
238+
to systemd services.
239+
240+
Further customization
241+
---------------------
242+
243+
For other customization of IOC services,
244+
you can edit the generated systemd service
245+
by setting the options under :samp:`systemd.services.{myIoc}`.
246+
247+
For example,
248+
to make your machine reboot
249+
if your IOC fails to start:
250+
251+
.. code-block:: nix
252+
:caption: Customizing the IOC systemd service
253+
254+
services.iocs.myIoc = {
255+
package = pkgs.myTop;
256+
workingDirectory = "iocBoot/iocMyIoc";
257+
};
258+
259+
# These options will modify the generated systemd service
260+
systemd.services.myIoc = {
261+
# These options will modify the [Unit] section
262+
# See `man systemd.unit` for available options in this section
263+
unitConfig = {
264+
# If the IOC reboot 5 times
265+
StartLimitBurst = 5;
266+
# in 30 seconds
267+
StartLimitIntervalSec = 30;
268+
# reboot
269+
StartLimitAction = "reboot";
270+
};
271+
};
272+
273+
For more information,
274+
see the `systemd.services options`_,
275+
and the man pages :manpage:`systemd.unit(5)`,
276+
:manpage:`systemd.service(5)`,
277+
and other related systemd documentation.
278+
279+
.. _systemd.services options: https://search.nixos.org/options?query=systemd.services.

docs/release-notes/2505.rst

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@
66
.. role:: nix(code)
77
:language: nix
88

9+
New features
10+
------------
11+
12+
- New module :option:`services.iocs`
13+
to deploy EPICS IOCs as systemd services.
14+
15+
If you deployed EPICS IOCs manually by using ``systemd.services``,
16+
or used the configuration :samp:`epnix.nixos.services.{ioc}.config`
17+
generated from the now deprecated IOC module system,
18+
read the :doc:`../nixos-services/user-guides/ioc-services` NixOS guide.
19+
920
Breaking changes
1021
----------------
1122

0 commit comments

Comments
 (0)