...
This document states workflows to develop a OPI to be integrated into a k8s ECS EPIK8S deploy.
Common and preparatory steps
Create a GIT repository
Every OPI MUST have a GIT repository associated. A project must be created under https://baltig.infn.it/lnf-da-control or a different group like for instance:
https://baltig.infn.it/infn-epics
https://baltig.infn.it/epics-containers
Pay attention to not set the project private otherwise will not be possible to load it into the ECS k8s.
Setup Phoebus
Please refer to this guide: Phoebus Setup.
Setup environment
Depending on the target beamline (i.e. sparc environ EPIK8s Sparc):
- Setup EPICS_CA_ADDR_LIST
- Identify your target ECS information page (i.e EPIK8s Sparc ) retrieving "GIT Control Source" URL, clone it
Python SoftIOC workflow
Setup a target container
For this kind of IOC it's recommended to use the docker image: baltig.infn.it:4567/epics-containers/epics-py-base since it contains the required packages and will be also the image that will be used to run this kind of softioc.
Here below an example of configuration of the devontainer devcontainer.json
Architecture
Each beamline in EPIK8S has a GIT project associated. This GIT project has a opi directory that point to a OPI git project that contains the interface of the given beamline.
Code Block | ||||
---|---|---|---|---|
| ||||
├── README.md
├── config
│ ├── applications
│ ├── iocs
│ └── services
├── deploy
│ ├── Chart.yaml
│ ├── templates
│ └── values.yaml
├── opi | ||||
Code Block | ||||
| ||||
// For format details, see https://containers.dev/implementors/json_reference/ { "name": "python container", "image": "baltig.infn.it:4567/epics-containers/epics-py-base", "remoteEnv": { // allows X11 apps to run inside the container "DISPLAY": "${localEnv:DISPLAY}", // provides a name for epics-containers to use in bash prompt etc. "EC_PROJECT": "${localWorkspaceFolderBasename}" }, "features": { }, // IMPORTANT for this devcontainer to work with docker EC_REMOTE_USER must be // set to vscode. For podman it should be left blank. "remoteUser": "${localEnv:EC_REMOTE_USER}", "customizations": { "vscode": { // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-python.python", "ms-python.vscode-pylance", "tamasfe.even-better-toml", "redhat.vscode-yaml", "ryanluker.vscode-coverage-gutters", "epicsdeb.vscode-epics", "ms-python.black-formatter" ] } }, // Make sure the files we are mapping into the container exist on the host // You can place any other outside of the container before-launch commands here //"initializeCommand": "bash .devcontainer/initializeCommand ${devcontainerId}", // Hooks the global .bashprofile_dev_container but also can add any other commands // to run in the container at creation in here //"postCreateCommand": "bash .devcontainer/postCreateCommand ${devcontainerId}", //"forwardPorts": [5064, 5065], "runArgs": [ // Allow the container to access the host X11 display and EPICS CA //"--net=host", // Make sure SELinux does not disable with access to host filesystems like tmp "--security-opt=label=disable" ], "workspaceMount": "source=${localWorkspaceFolder},target=/app/${localWorkspaceFolderBasename},type=bind", "workspaceFolder": "/app/${localWorkspaceFolderBasename}", "mounts": [ // Mount some useful local files from the user's home directory // By mounting the parent of the workspace we can work on multiple peer projects "source=${localWorkspaceFolder}/../,target=/repos,type=bind", // this provides eternal bash history in and out of the container "source=${localEnv:HOME}/.bash_eternal_history,target=/root/.bash_eternal_history,type=bind", // this bashrc hooks up the .bashrc_dev_container in the following mount "source=${localWorkspaceFolder}/.devcontainer/.bashrc,target=/root/.bashrc,type=bind", // provides a place for you to put your shell customizations for all your dev containers "source=${localEnv:HOME}/.bashrc_dev_container,target=/root/.bashrc_dev_container,type=bind", // provides a place to install any packages you want to have across all your dev containers "source=${localEnv:HOME}/.bashprofile_dev_container,target=/root/.bashprofile_dev_container,type=bind", // provides the same command line editing experience as your host "source=${localEnv:HOME}/.inputrc,target=/root/.inputrc,type=bind" ] } |
A fully functional example:
<--- This is the OPI git submodule (this case https://baltig.infn.it/lnf-da-control/sparc-epics-opi.git)
│ ├── Launcher.bob <--- OPI entry point
│ ├── README.md
│ ├── deploy
│ ├── env.sh
│ ├── phoebus_mrf_interface
│ ├── ptts
│ ├── rp-opi
│ ├── settings.ini <--- phoebus initialization (see beamline info i.e https://confluence.infn.it/display/SCS/EPIK8s+Sparc)
│ ├── settings_template.ini
│ └── start.sh <--- phoebus start (generally works on EPIK8s, Linux and MAC)
└── sparc-deploy.yaml |
This structure allows:
- separate development of OPIs and IOCs
- update control room OPIs accessing just the GIT repository of the OPI.
OPI GIT project
Every OPI MUST have a GIT repository associated. A project for an internal facility must be created or exist under https://baltig.infn.it/lnf-da-control.
For instance the OPI git project for SPARC is: https://baltig.infn.it/infnlnf-da-epicscontrol/pysparc-ioc-collector
Follow development guidelines
SOFT IOC Development SoftIOC in a Linux-like environment
Deploy on the target ECS
Once your IOC/application is tested and ready to be published on the target ECS.
In your application repository create a bash file named start.sh (bash script) that will be used to start your application. Add it to your repo.
An simple example took from (epics-opi.git while for dafne is https://baltig.infn.it/lnf-da-control/dafne-k8s-ecs/-/tree/main/config/ioc/ioc-dafne-accumulator-orbit?ref_type=heads):
Code Block | ||||
---|---|---|---|---|
| ||||
#!/bin/bash
script_dir=$(dirname "$0")
cd $script_dir
echo "Starting Accumulator Orbit addr: $EPICS_CA_ADDR_LIST"
python ./scripts/py-ioc-collector.py -c accumulator_orbit.json
|
If the application/ioc is generic a more generic approach should be followed decoupling the source and the startup. In this approach the configuration of the IOC resides in a dedicated directory <TARGET ECS>/config/ioc of the target K8s ECS see for instance https://baltig.infn.it/lnf-da-control/dafne-k8s-ecs/-/tree/main/config/ioc
Follow this steps:
Pay attention to not set the project private otherwise will not be possible to load it into the EPIK8S.
Setup Phoebus
Please refer to this guide: Phoebus. Particular sensitive is the settings.ini. This file must exists and initialised as EPIK8s information page suggests (i.e EPIK8s Sparc ).
For Linux and MAC system the start.sh can be used to launch phoebus and initialise correctly with the settings.ini.
.
Setup environment
Depending on the target beamline (i.e. sparc environ EPIK8s Sparc).
- Setup EPICS_CA_ADDR_LIST
- Identify your target EPIK8s Identify your target ECS information page (i.e EPIK8s Sparc ) retrieving "GIT Control Source" URL, clone it:
Code Block language bash title Full CS git clone https://baltig.infn.it/lnf-da-control/<BEAMLINE>-k8s-ecs.git --recurse-submodules
- go in deploy/templates create a manifest yaml for your application like this
- .
- This project includes a opi directories that is a git submodule that points to a GIT project intended to include all the CSS/phoebus interfaces that compose the Control System interfaces of the EPIK8S beamline. The entry point to the beamline control interface is Launcher.bob. The settings.ini is built by start.sh depending on the environment variables:
- EPICS_CA_ADDR_LIST that must include the addresses of the IOC you want to access or the address of the ca-gateway listed on the target ECS information page
- OPIHOME the directory where the OPIs are.
EPICS_ARCHIVER the Entry point of the archiver.
PHOEBUS_SAVE_AND_RESTORE service of save and restore
PHOEBUS_SCAN_SERVER service
- Test your environment trying to open Launcher.bob and open some control interface.
Develop your OPI and deploy
The development flow depends on you. You may have your OPI in a git project (very suggested way) or you may have developed something really custom for the beamline so that you may include it directly in the OPI beamline project.
If you developed your OPI and resides in a GIT repository you should include your repository into the Beamline OPI as submodule:
Code Block | |
---|---|
|
...
|
...
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <myapplicationname>-ioc
namespace: argocd
labels:
rootapp: {{ .Chart.Name }}
rootappver: {{ .Chart.Version | quote }}
beamline: {{ .Values.beamline | quote }}
spec:
project: default
source:
repoURL: 'https://baltig.infn.it/epics-containers/ioc-chart.git'
path: .
targetRevision: HEAD
helm:
values: |
image: baltig.infn.it:4567/epics-containers/epics-py-base
beamline: {{ .Values.beamline | quote }}
replicaCount: {{ .Values.consoleReplica }}
configCA:
existingConfigMap: {{ .Values.configCA.configName | quote}}
address_list: {{ .Values.configCA.gatewayName }} ## override with gateway
gitRepoConfig:
url: 'http://<your repo url>'
path: '<path to reach your app and conf... usually just .>'
branch: 'main'
init: 'true'
start: '/epics/ioc/config/start.sh'
destination:
server: 'https://kubernetes.default.svc'
namespace: {{ .Values.namespace | quote }}
syncPolicy:
automated:
prune: true # Optional: Automatically remove resources not specified in Helm chart
selfHeal: true
| |
cd opi
git pull --recurse-submodules ## to update remote changes
git submodule update --init ## to update eventually new submodules
## here add your new submodule
git submodule add <your repository_URL> [<submodule_path>]
git commit -m "your comment Add submodule <submodule_name>"
git push origin <your remote branch i.e main/master> |
In case you want add your OPI to the Beamline OPI, so your files we'll be part of the Beamline OPI just use:
Code Block | ||||
---|---|---|---|---|
| ||||
cd opi
git pull --recurse-submodules ## to update remote changes
git submodule update --init ## to update eventually new submodules
## here add your folder/files
git add <your files/folder>
git commit -m "your comment " .
git push origin <your remote branch i.e main/master> |
Update an existing OPI submodule:
Code Block | ||||
---|---|---|---|---|
| ||||
cd /<your git directory>/epik8-<beamline name> ## for example epik8-sparc
git pull --recurse-submodules ## to update remote changes
git submodule update --init ## to update eventually new submodules
cd opi/<OPI TYPE>/<submodule name> ## fro example RF/sparc-rf-opi
git pull ## to update the submodule
cd ..
git add <submodule name>
git commit -m "<your message>"
git push origin ## add HEAD:main to this command line if you are in a detached HEAD
cd ../.. ## to go in the master repository
git add opi/
git commit -m "<your message>"
git push origin |
If, in any moment in the update procedure, git says that you are not in a branch you can type:
Code Block | ||||
---|---|---|---|---|
| ||||
git branch ## to verify the available branches (typically "main" for the submodule and "master" for the main repository)
git switch <name of the branch> |
to enter in the correct branch
...
Setup Phoebus and develop the OPI for your softioc
Install Phoebus: Phoebus Setup.
If you want to develop the OPI for your IOC however each K8S ECS installation has in its GIT Control Source project a directory opi (that is a git subproject with other subproject) that contain a Launcher.bob and a start.sh, this setup is intended to start the main control interface of a given beamline.
If you are developing an gui interface that must be integrated in the control a OPI Development Workflow must be followed.