diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5955ad1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/buiild.yml b/.github/workflows/buiild.yml new file mode 100644 index 0000000..4e9c483 --- /dev/null +++ b/.github/workflows/buiild.yml @@ -0,0 +1,64 @@ +name: Check that ibek-support support modules will build in a container + +on: + push: + pull_request: + +jobs: + check-docker-build: + # pull requests are a duplicate of a branch push if within the same repo. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository + permissions: + contents: read + packages: write + env: + CACHE: /tmp/.buildx-cache + strategy: + fail-fast: false + matrix: + include: + # rtems is cross compiled on ubuntu-latest + # linux is natively compiled on ubuntu-latest and macos-latest + + # enable below for RTEMS + # - architecture: rtems + # os: ubuntu-latest + # platform: linux/amd64 + + - architecture: linux + os: ubuntu-latest + platform: linux/amd64 + + # enable below for MACOS native build on M1 macs + # M1 Macs are coming!: https://github.com/github/roadmap/issues/528 + # - architecture: linux + # os: macos-latest-x1 + # platform: linux/arm64 + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup docker (missing on MacOS) + if: runner.os == 'macos' + uses: docker-practice/actions-setup-docker@fd7ecdac7caf8e2c541a48c9bcc280aae59a8461 + + - name: Log in to GitHub Docker Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io/${{ github.repository_owner }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker Test Build Script + env: + ARCH: ${{ matrix.architecture }} + PLATFORM: ${{ matrix.platform }} + CACHE: ${{ env.CACHE }} + run: | + # ioc folder is found in the super module usually so for testing + # on github we need to copy it above the root of the repo + cp -r ioc .. + tests/_test_support_build.sh diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 15d406f..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "cSpell.words": [ - "swapint" - ] -} \ No newline at end of file diff --git a/ADAravis/ADAravis.sh b/ADAravis/ADAravis.sh index b39bfe9..47c8c41 100644 --- a/ADAravis/ADAravis.sh +++ b/ADAravis/ADAravis.sh @@ -1,23 +1,77 @@ -echo ' -BUILD_IOCS=NO +#!/bin/bash -CROSS_COMPILER_TARGET_ARCHS = +########################################################################## +##### install script for ADAravis support module########################## +########################################################################## -GLIBPREFIX=/usr +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=ADAravis + +# log output and abort on failure +set -xe + +# install required system dependencies +ibek support apt-install --only=dev \ + libboost-all-dev \ + libxext-dev \ + libglib2.0-dev \ + libusb-1.0 \ + libxml2-dev \ + libx11-dev \ + meson \ + intltool \ + pkg-config \ + xz-utils + +# declare packages for installation in the Dockerfile's runtime stage +ibek support apt-install --only=run libglib2.0-bin libusb-1.0 libxml2 + +# build aravis library +( + cd /usr/local && + git clone -b ARAVIS_0_8_1 --depth 1 https://github.com/AravisProject/aravis && + cd aravis && + meson build && + cd build && + ninja && + ninja install && + rm -fr /usr/local/aravis + echo /usr/local/lib64 > /etc/ld.so.conf.d/usr.conf && + ldconfig + # is this necessary? + pip install telnetlib3 +) + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} +ibek support register ${NAME} + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs ADAravis +ibek support add-dbds ADAravisSupport.dbd +# add any required changes to CONFIG_SITE +CONFIG=' +AREA_DETECTOR=$(SUPPORT) +CROSS_COMPILER_TARGET_ARCHS = +GLIBPREFIX=/usr USR_INCLUDES += -I$(GLIBPREFIX)/include/glib-2.0 USR_INCLUDES += -I$(GLIBPREFIX)/lib/x86_64-linux-gnu/glib-2.0/include/ - glib-2.0_DIR = $(GLIBPREFIX)/lib/x86_64-linux-gnu - ARAVIS_INCLUDE = /usr/local/include/aravis-0.8/ +' -' > configure/CONFIG_SITE.linux-x86_64.Common +ibek support add-to-config-site ${NAME} "${CONFIG}" -echo ' -# Generic RELEASE.local file for areadetector modules +# TODO may need +# ioc_SYS_LIBS += aravis-0.8 +# in the Makefile + +# compile the support module +ibek support compile ${NAME} + +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} -SUPPORT=NotYetSet -AREA_DETECTOR=$(SUPPORT) -include $(SUPPORT)/configure/RELEASE -' > configure/RELEASE.local \ No newline at end of file diff --git a/ADCore/ADCore.sh b/ADCore/ADCore.sh deleted file mode 100644 index 81140ff..0000000 --- a/ADCore/ADCore.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -echo ' -CROSS_COMPILER_TARGET_ARCHS = - -# Enable file plugins and source them all from ADSupport -# this minimizes dependency issues with system libraries - -WITH_HDF5 = YES -HDF5_EXTERNAL = NO - -WITH_SZIP = YES -SZIP_EXTERNAL = NO - -WITH_JPEG = YES -JPEG_EXTERNAL = NO - -WITH_TIFF = YES -TIFF_EXTERNAL = NO - -XML2_EXTERNAL = NO - -WITH_ZLIB = YES -ZLIB_EXTERNAL = NO - -WITH_BLOSC = YES -BLOSC_EXTERNAL= NO - -WITH_CBF = YES -CBF_EXTERNAL = NO - -WITH_PVA = YES -WITH_BOOST = YES -' > configure/CONFIG_SITE.linux-x86_64.Common - -echo ' -# Generic RELEASE.local file that should work for all Support modules and IOCs - -SUPPORT=NotYetSet -AREA_DETECTOR=$(SUPPORT) -include $(SUPPORT)/configure/RELEASE -' > configure/RELEASE.local diff --git a/ADCore/install.sh b/ADCore/install.sh new file mode 100755 index 0000000..9b32d24 --- /dev/null +++ b/ADCore/install.sh @@ -0,0 +1,79 @@ +#!/bin/bash +########################################################################## +##### install script for ADCore support module ########################### +########################################################################## + +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=ADCore + +# log output and abort on failure +set -xe + +# install required system dependencies +HDF=http://ftp.de.debian.org/debian/pool/main/h/hdf5 +ibek support apt-install --only=dev \ + libaec-dev \ + libblosc-dev \ + libglib2.0-dev \ + libjpeg-dev \ + libtiff5-dev \ + libusb-1.0 \ + libxml2-dev \ + libx11-dev \ + libxext-dev \ + libz-dev \ + $HDF/libhdf5-103_1.10.4+repack-10_amd64.deb \ + $HDF/libhdf5-cpp-103_1.10.4+repack-10_amd64.deb \ + $HDF/libhdf5-dev_1.10.4+repack-10_amd64.deb + +# declare packages for installation in the Dockerfile's runtime stage +ibek support apt-install --only=run libtiff5 libsz2 libblosc1 libxml2 libhdf5-103-1 + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} --org http://github.com/areaDetector/ +ibek support register ${NAME} + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs ntndArrayConverter ADBase NDPlugin pvAccessCA \ + pvAccessIOC pvAccess +ibek support add-dbds NDPluginPva.dbd ADSupport.dbd NDPluginSupport.dbd \ + NDFileNull.dbd NDPosPlugin.dbd NDFileHDF5.dbd NDFileJPEG.dbd NDFileTIFF.dbd \ + PVAServerRegister.dbd + +# add any required changes to CONFIG_SITE +CONFIG=' +AREA_DETECTOR=$(SUPPORT) +CROSS_COMPILER_TARGET_ARCHS = +WITH_GRAPHICSMAGICK = NO +WITH_HDF5 = YES +HDF5_EXTERNAL = YES +HDF5_LIB = /usr/lib/x86_64-linux-gnu/hdf5/serial/ +HDF5_INCLUDE = /usr/include/hdf5/serial/ +WITH_SZIP = YES +SZIP_EXTERNAL = YES +WITH_JPEG = YES +JPEG_EXTERNAL = YES +WITH_TIFF = YES +TIFF_EXTERNAL = YES +XML2_EXTERNAL = YES +XML2_INCLUDE = /usr/include/libxml2/ +WITH_ZLIB = YES +ZLIB_EXTERNAL = YES +WITH_BLOSC = YES +BLOSC_EXTERNAL= YES +WITH_CBF = YES +CBF_EXTERNAL = YES +WITH_PVA = YES +WITH_BOOST = NO +' +ibek support add-to-config-site ${NAME} "${CONFIG}" + +# compile the support module +ibek support compile ${NAME} + +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} + + diff --git a/ADSimDetector/install.sh b/ADSimDetector/install.sh new file mode 100755 index 0000000..a552f21 --- /dev/null +++ b/ADSimDetector/install.sh @@ -0,0 +1,27 @@ +#!/bin/bash +########################################################################## +###### install script for ADSimDetector Module ########################### +########################################################################## + +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=ADSimDetector + +# log output and abort on failure +set -xe + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} --org http://github.com/areaDetector/ +ibek support register ${NAME} + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs simDetector +ibek support add-dbds simDetectorSupport.dbd + +# compile the support module +ibek support compile ${NAME} +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} + + diff --git a/ADSimdetector/ADSimdetector.sh b/ADSimdetector/ADSimdetector.sh deleted file mode 100644 index d7059a9..0000000 --- a/ADSimdetector/ADSimdetector.sh +++ /dev/null @@ -1,43 +0,0 @@ - -#!/bin/bash - -echo ' -CROSS_COMPILER_TARGET_ARCHS = - -# Enable file plugins and source them all from ADSupport -# this minimizes dependency issues with system libraries - -WITH_HDF5 = YES -HDF5_EXTERNAL = NO - -WITH_SZIP = YES -SZIP_EXTERNAL = NO - -WITH_JPEG = YES -JPEG_EXTERNAL = NO - -WITH_TIFF = YES -TIFF_EXTERNAL = NO - -XML2_EXTERNAL = NO - -WITH_ZLIB = YES -ZLIB_EXTERNAL = NO - -WITH_BLOSC = YES -BLOSC_EXTERNAL= NO - -WITH_CBF = YES -CBF_EXTERNAL = NO - -WITH_PVA = YES -WITH_BOOST = YES -' > configure/CONFIG_SITE.linux-x86_64.Common - -echo ' -# Generic RELEASE.local file that should work for all Support modules and IOCs - -SUPPORT=NotYetSet -AREA_DETECTOR=$(SUPPORT) -include $(SUPPORT)/configure/RELEASE -' > configure/RELEASE.local diff --git a/ADSupport/ADSupport.sh b/ADSupport/ADSupport.sh deleted file mode 100644 index c0c7964..0000000 --- a/ADSupport/ADSupport.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -echo ' -CROSS_COMPILER_TARGET_ARCHS = - -# Enable file plugins and source them all from ADSupport -# this minimizes dependency issues with system libraries - -WITH_GRAPHICSMAGICK = YES -GRAPHICSMAGICK_EXTERNAL = NO - -WITH_HDF5 = YES -HDF5_EXTERNAL = NO - -WITH_SZIP = YES -SZIP_EXTERNAL = NO - -WITH_JPEG = YES -JPEG_EXTERNAL = NO - -WITH_TIFF = YES -TIFF_EXTERNAL = NO - -XML2_EXTERNAL = NO - -WITH_ZLIB = YES -ZLIB_EXTERNAL = NO - -WITH_BLOSC = YES -BLOSC_EXTERNAL= NO - -WITH_CBF = YES -CBF_EXTERNAL = NO - -WITH_PVA = YES -WITH_BOOST = YES -' > configure/CONFIG_SITE.linux-x86_64.Common - -echo ' -# Generic RELEASE.local file that should work for all Support modules and IOCs - -SUPPORT=NotYetSet -AREA_DETECTOR=$(SUPPORT) -include $(SUPPORT)/configure/RELEASE -' > configure/RELEASE.local diff --git a/ADURL/ADURL.sh b/ADURL/ADURL.sh deleted file mode 100644 index e075a2c..0000000 --- a/ADURL/ADURL.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -echo ' -CROSS_COMPILER_TARGET_ARCHS = - -# Enable file plugins and source them all from ADSupport - -WITH_GRAPHICSMAGICK = YES -GRAPHICSMAGICK_EXTERNAL = NO - -WITH_JPEG = YES -JPEG_EXTERNAL = NO - -WITH_PVA = YES -WITH_BOOST = YES -' > configure/CONFIG_SITE.linux-x86_64.Common - -echo ' -# Generic RELEASE.local file that should work for all Support modules and IOCs - -SUPPORT=NotYetSet -AREA_DETECTOR=$(SUPPORT) -include $(SUPPORT)/configure/RELEASE -' > configure/RELEASE.local diff --git a/README.md b/README.md index c8bb0f1..9fd60f5 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,70 @@ -# ibek-defs -## ibek definition files +# ibek-support -A central repository to hold the definition and patch files that enable ibek -to build EPICS support modules inside of a container. +Holds details of how to build EPICS support modules within +an epics-containers Generic IOC Dockerfile. Plus details of +how to use features from each support module at runtime inside +an epics-containers IOC instance. -## How to use +## Scope -This repository should be included into every epics-containers generic IOC -as a folder called \/ibek-defs. +This project targets +support modules that are available on github or other public +repositories. Facilities may choose to have an internal version of this +repo for support modules that are not public. Private Generic IOCs +would be free to mix support from both public and private ibek-support. + +We expect that commonly used generic IOCs would be published to the +epics-containers github organisation or other public registry. +Such generic IOCs would be required to use public ibek-support only. + + + +## Structure + +Each EPICS support module has a folder in this repo. By convention, +the folder name is the same as the support module github repo name +(or other repo name). -The best way to achieve this is demonstrated in -https://github.com/epics-containers/ioc-template. -This uses a git submodule to pull ibek-defs and lock in the version that -was last used. This is then copied into the container in a Dockerfile step. +Each support module folder contains:- -## Purpose +- install.sh: + - a script that builds the support module inside of a container. + This script is invoked by every Generic IOC build that requires the + support module. The script can contain any commands that are required + but would usually be a series of calls to `ibek support` functions. + For an example see + [install.sh](https://github.com/epics-containers/ibek-support/blob/main/asyn/install.sh) + for the Asyn support module. -TODO: this explanation could do with tidying up and I'm not sure it -belongs here anyway. perhaps move this to the epics-containers workflow -documentation and reference from here. +- \.ibek.support.yaml: + - a definition file that describes how the support module is used by + an IOC instance. This file is read by ibek when building an IOC instance + and is used to generate the startup script and database file. For an + example see + [asyn.ibek.def.yaml](https://github.com/epics-containers/ibek-support/blob/main/asyn/asyn.ibek.support.yaml) + +- other: + - any other files that are required to build the support module in the + environment provided by the epics-base container image. + The most straightforward support folders should only require the above two + files. But perhaps a patch file might be required to make a support module + build inside of a container for example. + + + +## How to use + +This repository should be included into every epics-containers generic IOC +as a submodule of the IOC's git repository. The generic IOC's Dockerfile +should then copy the ibek-support folder for each support module it +requires into the container and call its install.sh script. -When A generic IOC is building it passes a ibek modules file -"\.ibek.modules.yaml. This will contain references to -the support modules that the IOC depends upon and may also include -a patch script file for each of those support modules. +For an example Dockerfile that demonstrates this see +[ioc-adsimdetector](https://github.com/epics-containers/ioc-adsimdetector/blob/main/Dockerfile) -This repo supports generic IOCs as follows:- +For details of the ibek module support functions +[ibek's github page](https://github.com/epics-containers/ibek) -- at IOC build time it provides a patch file script that makes any changes - to the support source required to build it in the container. This is - most likely involves creating a release/CONFIG_SITE.xxx file. -- at run time it provides a definition file per support module which - allows the IOC to specify how it uses that support. This file will be name - "\.ibek.def.yaml. The set of definition files are - read by ibek in order to interpret the IOC instance yaml file and - build an individual IOC's startup script. diff --git a/_global/README.md b/_global/README.md index 6243be3..79bbc90 100644 --- a/_global/README.md +++ b/_global/README.md @@ -7,9 +7,10 @@ epics.ibek.support.yaml: This yaml file describes some global definitions that allow things like adding arbitrary commands to the startup script. - THis is not associated with any particular Support module and should be + This is not associated with any particular Support module and should be included in the definition set for all IOCs. global.sh: - A global patch file to apply to all support modules \ No newline at end of file + A global patch file to apply to all support modules + diff --git a/_global/all.ibek.support.schema.json b/_global/all.ibek.support.schema.json deleted file mode 100644 index dec373d..0000000 --- a/_global/all.ibek.support.schema.json +++ /dev/null @@ -1,1964 +0,0 @@ -{ - "type": "object", - "properties": { - "ioc_name": { - "type": "string", - "description": "Name of IOC instance" - }, - "description": { - "type": "string", - "description": "Description of what the IOC does" - }, - "entities": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "PORT": { - "type": "string", - "description": "Port Name for teh camera", - "vscode_ibek_plugin_type": "type_id" - }, - "P": { - "type": "string", - "description": "The PV prefix" - }, - "R": { - "type": "string", - "description": "The PV suffix" - }, - "ID": { - "type": "string", - "description": "Cam ip address, hostname, MAC address, or ID -,\n(e.g. Prosilica-02-2166A-06844)\n" - }, - "BUFFERS": { - "type": "integer", - "description": "Max NDArray buffers to be created for plugin callbacks", - "default": 50 - }, - "MEMORY": { - "type": "integer", - "description": "Max memory to allocate, should be maxw*maxh*nbuffer\nfor driver and all attached plugins or -1 for unlimited\n", - "default": -1 - }, - "TIMEOUT": { - "type": "integer", - "description": "timeout for communication with camera", - "default": 1 - }, - "PV_ALIAS": { - "type": "string", - "description": "TODO this need to look into the purpose of this in builder.py\ndetermine its function and see if we can do the equivalent in ibek\n", - "default": "" - }, - "type": { - "type": "string", - "const": "ADAravis.ADAravis", - "default": "ADAravis.ADAravis" - } - }, - "required": [ - "PORT", - "P", - "R", - "ID" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "camera": { - "type": "string", - "description": "reference to ADAravis.ADAravis instance", - "vscode_ibek_plugin_type": "type_object" - }, - "type": { - "type": "string", - "const": "ADAravis.MantaG235B", - "default": "ADAravis.MantaG235B" - } - }, - "required": [ - "camera" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "camera": { - "type": "string", - "description": "reference to ADAravis.ADAravis instance", - "vscode_ibek_plugin_type": "type_object" - }, - "type": { - "type": "string", - "const": "ADAravis.Mako_G234B", - "default": "ADAravis.Mako_G234B" - } - }, - "required": [ - "camera" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Name to refer to when making a channel", - "vscode_ibek_plugin_type": "type_id" - }, - "carrier": { - "type": "string", - "description": "Carrier Board Identifier", - "vscode_ibek_plugin_type": "type_object" - }, - "ip_site_number": { - "type": "integer", - "description": "IP Site Number 0=A, 1=B, 2=C, 3=D" - }, - "vector": { - "type": "string", - "description": "Interrupt Vector", - "vscode_ibek_plugin_type": "type_object" - }, - "int_enable": { - "type": "boolean", - "description": "Interrupt Enable", - "default": false - }, - "external_clock": { - "type": "boolean", - "description": "Use External Clock", - "default": false - }, - "clock_rate": { - "type": "integer", - "description": "Clock Rate", - "default": 15 - }, - "inhibit": { - "type": "boolean", - "description": "Enable front panel inhibit signal", - "default": false - }, - "sample_size": { - "type": "integer", - "description": "Number of samples for triggered capture", - "default": 0 - }, - "card_id": { - "type": "string", - "description": "Card Identifier", - "default": "{{ carrier.slot }}{{ ip_site_number }}" - }, - "type": { - "type": "string", - "const": "Hy8401ip.Hy8401ip", - "default": "Hy8401ip.Hy8401ip" - } - }, - "required": [ - "name", - "carrier", - "ip_site_number", - "vector" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "card": { - "type": "string", - "description": "8401 card identifier", - "vscode_ibek_plugin_type": "type_object" - }, - "signal": { - "type": "integer", - "description": "8401 signal number (0-7)" - }, - "type": { - "type": "string", - "const": "Hy8401ip.Hy8401Channel", - "default": "Hy8401ip.Hy8401Channel" - } - }, - "required": [ - "card", - "signal" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Name to refer to when making a channel", - "vscode_ibek_plugin_type": "type_id" - }, - "carrier": { - "type": "string", - "description": "Carrier Board Identifier", - "vscode_ibek_plugin_type": "type_object" - }, - "ip_site_number": { - "type": "integer", - "description": "IP Site Number 0=A, 1=B, 2=C, 3=D" - }, - "vector": { - "type": "string", - "description": "Interrupt Vector", - "vscode_ibek_plugin_type": "type_object" - }, - "aitype": { - "type": "integer", - "description": "0=differential, 1=single ended, 2=PT100, 3=Thermocouple, 4=PT100 with 8212 Transition Card, 5=Thermocouples with 8212 Transition Card" - }, - "memsize": { - "type": "integer", - "description": "1=1MB memory, 2=2MB memory" - }, - "clock_source": { - "type": "integer", - "description": "0=internal, 1=external" - }, - "clock_rate": { - "type": "integer", - "description": "Xilinx scanning frequency in Hertz. Valid values: 1,2,5,10,20,50,100 and 200 Hz." - }, - "gain": { - "type": "integer", - "description": "Gain for all ADC inputs. Valid values are: 1,2,4,8,16,32,64, 128" - }, - "vref": { - "type": "integer", - "description": "Determine the internal ADC reference voltage: =1: 1.25V =2: 2.5V" - }, - "card_id": { - "type": "string", - "description": "Card Identifier", - "default": "{{ carrier.slot }}{{ ip_site_number }}" - }, - "type": { - "type": "string", - "const": "Hy8403ip.Hy8403ip", - "default": "Hy8403ip.Hy8403ip" - } - }, - "required": [ - "name", - "carrier", - "ip_site_number", - "vector", - "aitype", - "memsize", - "clock_source", - "clock_rate", - "gain", - "vref" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "device": { - "type": "string", - "description": "Device Name, PV Suffix" - }, - "card": { - "type": "string", - "description": "8403 card identifier", - "vscode_ibek_plugin_type": "type_object" - }, - "type": { - "type": "string", - "const": "Hy8403ip.Hy8403Channel", - "default": "Hy8403ip.Hy8403Channel" - } - }, - "required": [ - "device", - "card" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "PT": { - "type": "string", - "description": "Process Variable prefix" - }, - "ADC_REF_CHAN": { - "type": "string", - "description": "adc reference channel PV" - }, - "ADC_CHAN": { - "type": "string", - "description": "ADC channel PV" - }, - "deadband": { - "type": "number", - "description": "hysteresis value for monitor updates in Deg.C" - }, - "hihi": { - "type": "number", - "description": "hihi alarm" - }, - "hi": { - "type": "number", - "description": "hi alarm" - }, - "lo": { - "type": "number", - "description": "lo alarm" - }, - "lolo": { - "type": "number", - "description": "lolo alarm" - }, - "scan": { - "type": "number", - "description": "scan period in seconds", - "default": 1.0 - }, - "prec": { - "type": "integer", - "description": "record display precision", - "default": 0 - }, - "hopr": { - "type": "number", - "description": "high operating range", - "default": 100.0 - }, - "lopr": { - "type": "number", - "description": "low operating range", - "default": 0.0 - }, - "type": { - "type": "string", - "const": "PT100.PT100", - "default": "PT100.PT100" - } - }, - "required": [ - "PT", - "ADC_REF_CHAN", - "ADC_CHAN", - "deadband", - "hihi", - "hi", - "lo", - "lolo" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "device": { - "type": "string", - "description": "The device PV prefix", - "vscode_ibek_plugin_type": "type_id" - }, - "event_receiver": { - "type": "string", - "description": "reference to EventReceiverPMC entry", - "vscode_ibek_plugin_type": "type_object" - }, - "er": { - "type": "string", - "description": "Event Receiver record suffix", - "default": "SET-ER" - }, - "type": { - "type": "string", - "const": "TimingTemplates.DefaultEVR", - "default": "TimingTemplates.DefaultEVR" - } - }, - "required": [ - "device", - "event_receiver" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "default_evr": { - "type": "string", - "description": "reference to DefaultEVR entry", - "vscode_ibek_plugin_type": "type_object" - }, - "type": { - "type": "string", - "const": "TimingTemplates.EvrAlive", - "default": "TimingTemplates.EvrAlive" - } - }, - "required": [ - "default_evr" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "device": { - "type": "string", - "description": "device name", - "vscode_ibek_plugin_type": "type_id" - }, - "gt": { - "type": "string", - "description": "generalTime PV Prefix", - "default": "GT:" - }, - "scan": { - "type": "string", - "description": "scan rate", - "default": "10 second" - }, - "type": { - "type": "string", - "const": "TimingTemplates.GeneralTime", - "default": "TimingTemplates.GeneralTime" - } - }, - "required": [ - "device" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "ioc": { - "type": "string", - "description": "Device Prefix for this IOC" - }, - "type": { - "type": "string", - "const": "devIocStats.IocAdminSoft", - "default": "devIocStats.IocAdminSoft" - } - }, - "required": [ - "ioc" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "max_bytes": { - "type": "integer", - "description": "Max size in bytes for sending arrays over channel access", - "default": 6000000 - }, - "type": { - "type": "string", - "const": "epics.EpicsCaMaxArrayBytes", - "default": "epics.EpicsCaMaxArrayBytes" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "minutes_west": { - "type": "integer", - "description": "relative time zone minutes", - "default": 0 - }, - "type": { - "type": "string", - "const": "epics.EpicsTsMinWest", - "default": "epics.EpicsTsMinWest" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "pv": { - "type": "string", - "description": "Name of PV" - }, - "value": { - "type": "string", - "description": "Value to set" - }, - "type": { - "type": "string", - "const": "epics.Dbpf", - "default": "epics.Dbpf" - } - }, - "required": [ - "pv", - "value" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Name of environment variable" - }, - "value": { - "type": "string", - "description": "Value of environment variable" - }, - "type": { - "type": "string", - "const": "epics.EpicsEnvSet", - "default": "epics.EpicsEnvSet" - } - }, - "required": [ - "name", - "value" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "command": { - "type": "string", - "description": "command string", - "default": "" - }, - "type": { - "type": "string", - "const": "epics.StartupCommand", - "default": "epics.StartupCommand" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "command": { - "type": "string", - "description": "command string", - "default": "" - }, - "type": { - "type": "string", - "const": "epics.PostStartupCommand", - "default": "epics.PostStartupCommand" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "A name for an interrupt vector variable", - "vscode_ibek_plugin_type": "type_id" - }, - "count": { - "type": "integer", - "description": "The number of interrupt vectors to reserve", - "default": 1 - }, - "type": { - "type": "string", - "const": "epics.InterruptVectorVME", - "default": "epics.InterruptVectorVME" - } - }, - "required": [ - "name" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "port": { - "type": "string", - "description": "The port name for this asyn object" - }, - "input_eos": { - "type": "string", - "description": "Input end of string (terminator)" - }, - "output_eos": { - "type": "string", - "description": "Output end of string (terminator)" - }, - "priority": { - "type": "integer", - "description": "Priority", - "default": 100 - }, - "no_auto_connect": { - "type": "boolean", - "description": "Set to stop auto connect" - }, - "no_process_eos": { - "type": "boolean", - "description": "Set to avoid processing end of string" - }, - "simulation": { - "type": "string", - "description": "IP port to connect to if in simulation mode" - }, - "baud": { - "type": "integer", - "description": "Baud Rate" - }, - "bits": { - "type": "integer", - "description": "Bits [8,7,6,5]" - }, - "parity": { - "type": "string", - "description": "Parity [null,even,odd]" - }, - "stop": { - "type": "integer", - "description": "Stop Bits [1,2]" - }, - "crtscts": { - "type": "boolean", - "description": "Set hardware flow control on" - }, - "type": { - "type": "string", - "const": "asyn.AsynSerial", - "default": "asyn.AsynSerial" - } - }, - "required": [ - "port" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "port": { - "type": "string", - "description": "Serial port tty name / IP address optionally followed by protocol" - }, - "name": { - "type": "string", - "description": "Name for the Asyn Port" - }, - "input_eos": { - "type": "string", - "description": "Input end of string (terminator)" - }, - "output_eos": { - "type": "string", - "description": "Output end of string (terminator)" - }, - "priority": { - "type": "integer", - "description": "Priority", - "default": 100 - }, - "no_auto_connect": { - "type": "boolean", - "description": "Set to stop auto connect" - }, - "no_process_eos": { - "type": "boolean", - "description": "Set to avoid processing end of string" - }, - "simulation": { - "type": "string", - "description": "IP port to connect to if in simulation mode" - }, - "type": { - "type": "string", - "const": "asyn.AsynIP", - "default": "asyn.AsynIP" - } - }, - "required": [ - "port", - "name" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "IPAC identifier (suggested: IPAC)", - "vscode_ibek_plugin_type": "type_id" - }, - "slot": { - "type": "integer", - "description": "Crate Slot number" - }, - "int_level": { - "type": "integer", - "description": "Interrupt level", - "default": 2 - }, - "type": { - "type": "string", - "const": "ipac.Hy8002", - "default": "ipac.Hy8002" - } - }, - "required": [ - "name", - "slot" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "priority": { - "type": "integer", - "description": "Time provider priority", - "default": 10 - }, - "type": { - "type": "string", - "const": "mrfTiming.EventReceiverInit", - "default": "mrfTiming.EventReceiverInit" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "A name to reference this EVR", - "vscode_ibek_plugin_type": "type_id" - }, - "card_id": { - "type": "integer", - "description": "EPICS Card id" - }, - "card_index": { - "type": "integer", - "description": "PMC slot number", - "default": 0 - }, - "type": { - "type": "string", - "const": "mrfTiming.EventReceiverPMC", - "default": "mrfTiming.EventReceiverPMC" - } - }, - "required": [ - "name", - "card_id" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Asyn port name", - "vscode_ibek_plugin_type": "type_id" - }, - "IP": { - "type": "string", - "description": "IP address of Power pmac" - }, - "USERNAME": { - "type": "string", - "description": "Username for login", - "default": "root" - }, - "PASSWORD": { - "type": "string", - "description": "Password for login", - "default": "deltatau" - }, - "PRIORITY": { - "type": "integer", - "description": "Priority of the port", - "default": 0 - }, - "NOAUTOCONNECT": { - "type": "integer", - "description": "Disables autoconnect if set to 1", - "default": 0 - }, - "NOEOS": { - "type": "integer", - "description": "No EOS used if set to 1", - "default": 0 - }, - "type": { - "type": "string", - "const": "pmac.PmacAsynSSHPort", - "default": "pmac.PmacAsynSSHPort" - } - }, - "required": [ - "name", - "IP" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Asyn port name", - "vscode_ibek_plugin_type": "type_id" - }, - "IP": { - "type": "string", - "description": "IP address of pmac" - }, - "PORT": { - "type": "integer", - "description": "TCP port for connection", - "default": 1025 - }, - "type": { - "type": "string", - "const": "pmac.PmacAsynIPPort", - "default": "pmac.PmacAsynIPPort" - } - }, - "required": [ - "name", - "IP" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Name to use for the geobrick's asyn port", - "vscode_ibek_plugin_type": "type_id" - }, - "PORT": { - "type": "string", - "description": "Asyn port name for PmacAsynIPPort to connect to", - "vscode_ibek_plugin_type": "type_object" - }, - "P": { - "type": "string", - "description": "PV Prefix for all pmac db templates" - }, - "numAxes": { - "type": "integer", - "description": "number of axes to initialize for the controller", - "default": 8 - }, - "idlePoll": { - "type": "integer", - "description": "Idle Poll Period in ms", - "default": 500 - }, - "movingPoll": { - "type": "integer", - "description": "Moving Poll Period in ms", - "default": 100 - }, - "TIMEOUT": { - "type": "integer", - "description": "timeout in seconds for asyn", - "default": 4 - }, - "FEEDRATE": { - "type": "integer", - "description": "feedrate below which we go into error", - "default": 100 - }, - "CSG0": { - "type": "string", - "description": "Name for Coordinate System Group 0", - "default": "" - }, - "CSG1": { - "type": "string", - "description": "Name for Coordinate System Group 1", - "default": "" - }, - "CSG2": { - "type": "string", - "description": "Name for Coordinate System Group 2", - "default": "" - }, - "CSG3": { - "type": "string", - "description": "Name for Coordinate System Group 3", - "default": "" - }, - "CSG4": { - "type": "string", - "description": "Name for Coordinate System Group 3", - "default": "" - }, - "type": { - "type": "string", - "const": "pmac.Geobrick", - "default": "pmac.Geobrick" - } - }, - "required": [ - "name", - "PORT", - "P" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Object name and gui association name" - }, - "Controller": { - "type": "string", - "description": "PMAC Controller to attach to", - "vscode_ibek_plugin_type": "type_object" - }, - "axis": { - "type": "integer", - "description": "which axis number this motor drives" - }, - "P": { - "type": "string", - "description": "PV prefix name for this motor" - }, - "M": { - "type": "string", - "description": "PV motor name for this motor" - }, - "DESC": { - "type": "string", - "description": "Description, displayed on EDM screen", - "default": "" - }, - "MRES": { - "type": "number", - "description": "Motor Step Size (EGU)", - "default": 0.0001 - }, - "VELO": { - "type": "number", - "description": "axis Velocity (EGU/s)", - "default": 1.0 - }, - "PREC": { - "type": "integer", - "description": "Display Precision", - "default": 3 - }, - "EGU": { - "type": "string", - "description": "Engineering Units", - "default": "mm" - }, - "TWV": { - "type": "number", - "description": "Tweak Step Size (EGU)", - "default": 1.0 - }, - "DTYP": { - "type": "string", - "description": "Datatype of record", - "default": "asynMotor" - }, - "DIR": { - "type": "integer", - "description": "User direction", - "default": 0 - }, - "VBAS": { - "type": "number", - "description": "Base Velocity (EGU/s)", - "default": 1.0 - }, - "VMAX": { - "type": "string", - "description": "Max Velocity (EGU/s)", - "default": "{{VELO}}" - }, - "ACCL": { - "type": "number", - "description": "Seconds to Velocity", - "default": 0.5 - }, - "BDST": { - "type": "number", - "description": "BL Distance (EGU)", - "default": 0.0 - }, - "BVEL": { - "type": "number", - "description": "BL Velocity(EGU/s)", - "default": 0.0 - }, - "BACC": { - "type": "number", - "description": "BL Seconds to Veloc", - "default": 0.0 - }, - "DHLM": { - "type": "number", - "description": "Dial High Limit", - "default": 10000.0 - }, - "DLLM": { - "type": "number", - "description": "Dial low limit", - "default": -10000.0 - }, - "HLM": { - "type": "number", - "description": "User High Limit", - "default": 0.0 - }, - "LLM": { - "type": "number", - "description": "User Low Limit", - "default": 0.0 - }, - "HLSV": { - "type": "string", - "description": "HW Lim, Violation Svr", - "default": "MAJOR" - }, - "INIT": { - "type": "string", - "description": "Startup commands", - "default": "" - }, - "SREV": { - "type": "integer", - "description": "Steps per Revolution", - "default": 1000 - }, - "RRES": { - "type": "number", - "description": "Readback Step Size (EGU", - "default": 0.0 - }, - "ERES": { - "type": "number", - "description": "Encoder Step Size (EGU)", - "default": 0.0 - }, - "JAR": { - "type": "number", - "description": "Jog Acceleration (EGU/s^2)", - "default": 0.0 - }, - "UEIP": { - "type": "integer", - "description": "Use Encoder If Present", - "default": 0 - }, - "URIP": { - "type": "integer", - "description": "Use RDBL If Present", - "default": 0 - }, - "RDBL": { - "type": "string", - "description": "Readback Location, set URIP =1 if you specify this", - "default": "0" - }, - "RLNK": { - "type": "string", - "description": "Readback output link", - "default": "" - }, - "RTRY": { - "type": "integer", - "description": "Max retry count", - "default": 0 - }, - "DLY": { - "type": "number", - "description": "Readback settle time (s)", - "default": 0.0 - }, - "OFF": { - "type": "number", - "description": "User Offset (EGU)", - "default": 0.0 - }, - "RDBD": { - "type": "number", - "description": "Retry Deadband (EGU)", - "default": 0.0 - }, - "FOFF": { - "type": "integer", - "description": "Freeze Offset, 0=variable, 1=frozen", - "default": 0 - }, - "ADEL": { - "type": "number", - "description": "Alarm monitor deadband (EGU)", - "default": 0.0 - }, - "NTM": { - "type": "integer", - "description": "New Target Monitor, only set to 0 for soft motors", - "default": 1 - }, - "FEHIGH": { - "type": "number", - "description": "HIGH limit for following error", - "default": 0.0 - }, - "FEHIHI": { - "type": "number", - "description": "HIHI limit for following error", - "default": 0.0 - }, - "FEHHSV": { - "type": "string", - "description": "HIHI alarm severity for following error", - "default": "NO_ALARM" - }, - "FEHSV": { - "type": "string", - "description": "HIGH alarm severity for following error", - "default": "NO_ALARM" - }, - "SCALE": { - "type": "integer", - "default": 1 - }, - "HOMEVIS": { - "type": "integer", - "description": "If 1 then home is visible on the gui", - "default": 1 - }, - "HOMEVISSTR": { - "type": "string", - "default": "Use motor summary screen" - }, - "alh": { - "type": "string", - "description": "Set this to alh to add the motor to the alarm handler and send emails", - "default": "" - }, - "HOME": { - "type": "string", - "description": "Prefix for autohome instance. Defaults to $(P) If unspecified", - "default": "{{P}}" - }, - "ALLOW_HOMED_SET": { - "type": "string", - "description": "Set to a blank to allow this axis to have its homed", - "default": "#" - }, - "RLINK": { - "type": "string", - "description": "not sure what this is", - "default": "" - }, - "type": { - "type": "string", - "const": "pmac.DlsPmacAsynMotor", - "default": "pmac.DlsPmacAsynMotor" - } - }, - "required": [ - "name", - "Controller", - "axis", - "P", - "M" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Object name and gui association name" - }, - "CsController": { - "type": "string", - "description": "Coordinate system controller to attach to", - "vscode_ibek_plugin_type": "type_object" - }, - "axis": { - "type": "integer", - "description": "which axis number this motor drives" - }, - "P": { - "type": "string", - "description": "PV prefix name for this motor" - }, - "M": { - "type": "string", - "description": "PV motor name for this motor" - }, - "DESC": { - "type": "string", - "description": "Description, displayed on EDM screen", - "default": "" - }, - "MRES": { - "type": "number", - "description": "Motor Step Size (EGU)", - "default": 0.0001 - }, - "VELO": { - "type": "number", - "description": "axis Velocity (EGU/s)", - "default": 1.0 - }, - "PREC": { - "type": "integer", - "description": "Display Precision", - "default": 3 - }, - "EGU": { - "type": "string", - "description": "Engineering Units", - "default": "mm" - }, - "TWV": { - "type": "number", - "description": "Tweak Step Size (EGU)", - "default": 1.0 - }, - "DTYP": { - "type": "string", - "description": "Datatype of record", - "default": "asynMotor" - }, - "DIR": { - "type": "integer", - "description": "User direction", - "default": 0 - }, - "VBAS": { - "type": "number", - "description": "Base Velocity (EGU/s)", - "default": 1.0 - }, - "VMAX": { - "type": "string", - "description": "Max Velocity (EGU/s)", - "default": "{{VELO}}" - }, - "ACCL": { - "type": "number", - "description": "Seconds to Velocity", - "default": 0.5 - }, - "BDST": { - "type": "number", - "description": "BL Distance (EGU)", - "default": 0.0 - }, - "BVEL": { - "type": "number", - "description": "BL Velocity(EGU/s)", - "default": 0.0 - }, - "BACC": { - "type": "number", - "description": "BL Seconds to Veloc", - "default": 0.0 - }, - "DHLM": { - "type": "number", - "description": "Dial High Limit", - "default": 10000.0 - }, - "DLLM": { - "type": "number", - "description": "Dial low limit", - "default": -10000.0 - }, - "HLM": { - "type": "number", - "description": "User High Limit", - "default": 0.0 - }, - "LLM": { - "type": "number", - "description": "User Low Limit", - "default": 0.0 - }, - "HLSV": { - "type": "string", - "description": "HW Lim, Violation Svr", - "default": "MAJOR" - }, - "INIT": { - "type": "string", - "description": "Startup commands", - "default": "" - }, - "SREV": { - "type": "integer", - "description": "Steps per Revolution", - "default": 1000 - }, - "RRES": { - "type": "number", - "description": "Readback Step Size (EGU", - "default": 0.0 - }, - "ERES": { - "type": "number", - "description": "Encoder Step Size (EGU)", - "default": 0.0 - }, - "JAR": { - "type": "number", - "description": "Jog Acceleration (EGU/s^2)", - "default": 0.0 - }, - "UEIP": { - "type": "integer", - "description": "Use Encoder If Present", - "default": 0 - }, - "URIP": { - "type": "integer", - "description": "Use RDBL If Present", - "default": 0 - }, - "RDBL": { - "type": "string", - "description": "Readback Location, set URIP =1 if you specify this", - "default": "0" - }, - "RLNK": { - "type": "string", - "description": "Readback output link", - "default": "" - }, - "RTRY": { - "type": "integer", - "description": "Max retry count", - "default": 0 - }, - "DLY": { - "type": "number", - "description": "Readback settle time (s)", - "default": 0.0 - }, - "OFF": { - "type": "number", - "description": "User Offset (EGU)", - "default": 0.0 - }, - "RDBD": { - "type": "number", - "description": "Retry Deadband (EGU)", - "default": 0.0 - }, - "FOFF": { - "type": "integer", - "description": "Freeze Offset, 0=variable, 1=frozen", - "default": 0 - }, - "ADEL": { - "type": "number", - "description": "Alarm monitor deadband (EGU)", - "default": 0.0 - }, - "NTM": { - "type": "integer", - "description": "New Target Monitor, only set to 0 for soft motors", - "default": 1 - }, - "FEHEIGH": { - "type": "number", - "description": "HIGH limit for following error", - "default": 0.0 - }, - "FEHIHI": { - "type": "number", - "description": "HIHI limit for following error", - "default": 0.0 - }, - "FEHHSV": { - "type": "string", - "description": "HIHI alarm severity for following error", - "default": "NO_ALARM" - }, - "FEHSV": { - "type": "string", - "description": "HIGH alarm severity for following error", - "default": "NO_ALARM" - }, - "SCALE": { - "type": "integer", - "default": 1 - }, - "HOMEVIS": { - "type": "integer", - "description": "If 1 then home is visible on the gui", - "default": 1 - }, - "HOMEVISSTR": { - "type": "string", - "default": "Use motor summary screen" - }, - "alh": { - "type": "string", - "description": "Set this to alh to add the motor to the alarm handler and send emails", - "default": "" - }, - "HOME": { - "type": "string", - "description": "Prefix for autohome instance. Defaults to $(P) If unspecified", - "default": "{{P}}" - }, - "ALLOW_HOMED_SET": { - "type": "string", - "description": "Set to a blank to allow this axis to have its homed", - "default": "#" - }, - "type": { - "type": "string", - "const": "pmac.DlsCsPmacAsynMotor", - "default": "pmac.DlsCsPmacAsynMotor" - } - }, - "required": [ - "name", - "CsController", - "axis", - "P", - "M" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "Controller": { - "type": "string", - "description": "Geobrick on which to disable limits", - "vscode_ibek_plugin_type": "type_object" - }, - "Axis": { - "type": "integer", - "description": "Axis to have limits disabled" - }, - "type": { - "type": "string", - "const": "pmac.pmacDisableLimitsCheck", - "default": "pmac.pmacDisableLimitsCheck" - } - }, - "required": [ - "Controller", - "Axis" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "Controller": { - "type": "string", - "description": "the PMAC Controller", - "vscode_ibek_plugin_type": "type_object" - }, - "PLC": { - "type": "integer", - "description": "PLC number of the auto home PLC" - }, - "P": { - "type": "string", - "description": "Prefix for auto home PVs" - }, - "GRP1": { - "type": "string", - "description": "name of the 'ALL' group of auto home axes", - "default": "All" - }, - "GRP2": { - "type": "string", - "description": "name of the second group of auto home axes", - "default": "" - }, - "GRP3": { - "type": "string", - "description": "name of the third group of auto home axes", - "default": "" - }, - "GRP4": { - "type": "string", - "description": "name of the fourth group of auto home axes", - "default": "" - }, - "GRP5": { - "type": "string", - "description": "name of the fourth group of auto home axes", - "default": "" - }, - "GRP6": { - "type": "string", - "description": "name of the fourth group of auto home axes", - "default": "" - }, - "GRP7": { - "type": "string", - "description": "name of the fourth group of auto home axes", - "default": "" - }, - "GRP8": { - "type": "string", - "description": "name of the fourth group of auto home axes", - "default": "" - }, - "GRP9": { - "type": "string", - "description": "name of the fourth group of auto home axes", - "default": "" - }, - "type": { - "type": "string", - "const": "pmac.autohome", - "default": "pmac.autohome" - } - }, - "required": [ - "Controller", - "PLC", - "P" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "Asyn port name for this object", - "vscode_ibek_plugin_type": "type_id" - }, - "Controller": { - "type": "string", - "description": "the PMAC Controller", - "vscode_ibek_plugin_type": "type_object" - }, - "CS": { - "type": "integer", - "description": "Coordinate system number" - }, - "NAxes": { - "type": "integer", - "description": "number of CS axes", - "default": 9 - }, - "Program": { - "type": "integer", - "description": "PROG number for CS motion", - "default": 10 - }, - "type": { - "type": "string", - "const": "pmac.CS", - "default": "pmac.CS" - } - }, - "required": [ - "name", - "Controller", - "CS" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "name": { - "type": "string", - "description": "A name this IP module", - "vscode_ibek_plugin_type": "type_id" - }, - "carrier": { - "type": "string", - "description": "IPAC carrier name", - "vscode_ibek_plugin_type": "type_object" - }, - "ip_site_number": { - "type": "integer", - "description": "Site on the carrier for this IP Module (0=A, 1=B, 2=C, 3=D)" - }, - "interrupt_vector": { - "type": "string", - "description": "Interrupt Vector reserved with epics.InterruptVectorVME, count=3", - "vscode_ibek_plugin_type": "type_object" - }, - "link": { - "type": "integer", - "description": "Link number on this IP module (0 or 1)", - "default": 0 - }, - "type": { - "type": "string", - "const": "psc.PscIpModule", - "default": "psc.PscIpModule" - } - }, - "required": [ - "name", - "carrier", - "ip_site_number", - "interrupt_vector" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "device": { - "type": "string", - "description": "Device Name, PV Suffix", - "vscode_ibek_plugin_type": "type_id" - }, - "ip_module": { - "type": "string", - "description": "PscIpModule object", - "vscode_ibek_plugin_type": "type_object" - }, - "link": { - "type": "integer", - "description": "Link number on this IP module (0 or 1)" - }, - "i_abserr": { - "type": "number", - "description": "Absolute error limit (TODO what is i_abserr vs abserr ?)", - "default": 0.0005 - }, - "abserr": { - "type": "number", - "description": "Absolute error limit [0..1]", - "default": 0.0005 - }, - "relerr": { - "type": "number", - "description": "Relative error limit [0..1]", - "default": 0.0002 - }, - "controlerr": { - "type": "number", - "description": "Control Error", - "default": 0.0005 - }, - "startsw_evnt": { - "type": "integer", - "description": "Event to start Soft ramps (ignore)", - "default": 53 - }, - "syncsw_evnt": { - "type": "integer", - "description": "Event to synchronise Soft ramps (ignore)", - "default": 54 - }, - "hyscycle_dly": { - "type": "integer", - "description": "Seconds to wait in hysteresis cycle: time of PS between min and max value\n", - "default": 3 - }, - "hyscydir": { - "type": "integer", - "description": "Direction of hysteresis cycle:\napproaching set point from above (-) or below (+) at the end of the cycle\n", - "default": 0 - }, - "hyscmask": { - "type": "integer", - "description": "Defines the number of hysteresis cycles to run (for values >1 (3, 7, ...)\nthe seq delay has to be specified in an extra template)\n", - "default": 3 - }, - "hyslock": { - "type": "integer", - "description": "The value \"locked\" will force the PS to do a full cycle,\nwhenever the value I-SET is changed in the wrong direction (against HYCDIR)\n", - "default": 0 - }, - "hysimin": { - "type": "integer", - "description": "Minimum value for hysteresis cycle", - "default": -3 - }, - "hysimax": { - "type": "integer", - "description": "Maximum value for hysteresis cycle", - "default": 3 - }, - "oninitcycle": { - "type": "boolean", - "description": "Flag to determine if power supply should do a hysteresis cycle\nwhen it is switched ON\n", - "default": false - }, - "vdclink_adel": { - "type": "number", - "description": "UNKNOWN", - "default": 0.3 - }, - "vload_adel": { - "type": "number", - "description": "UNKNOWN", - "default": 0.3 - }, - "icharge_adel": { - "type": "number", - "description": "UNKNOWN", - "default": 0.0005 - }, - "type": { - "type": "string", - "const": "psc.PscTemplate", - "default": "psc.PscTemplate" - } - }, - "required": [ - "device", - "ip_module", - "link" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "entity_enabled": { - "type": "boolean", - "default": true - }, - "card": { - "type": "string", - "description": "8401 card identifier", - "vscode_ibek_plugin_type": "type_object" - }, - "psc_template": { - "type": "string", - "description": "The PSC template instance", - "vscode_ibek_plugin_type": "type_object" - }, - "channel": { - "type": "integer", - "description": "8401 channel number (0-7)" - }, - "name": { - "type": "string", - "description": "Suffix for PV name for this channel" - }, - "cal_m": { - "type": "number", - "description": "Calibrated current multiplier" - }, - "cal_c": { - "type": "number", - "description": "Calibrated current constant" - }, - "adel": { - "type": "number", - "description": "Archive deadband for calibrated current" - }, - "type": { - "type": "string", - "const": "psc.pscHy8401Channel-BS", - "default": "psc.pscHy8401Channel-BS" - } - }, - "required": [ - "card", - "psc_template", - "channel", - "name", - "cal_m", - "cal_c", - "adel" - ], - "additionalProperties": false - } - ] - }, - "description": "List of entities this IOC instantiates" - }, - "generic_ioc_image": { - "type": "string", - "description": "The generic IOC container image registry URL" - } - }, - "required": [ - "ioc_name", - "description", - "entities", - "generic_ioc_image" - ], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" -} \ No newline at end of file diff --git a/_global/global.sh b/_global/global.sh index 4398643..5c1d05c 100644 --- a/_global/global.sh +++ b/_global/global.sh @@ -1,6 +1,12 @@ + #!/bin/bash +# this script is applied to patch all support modules and is always called +# by each support module's install.sh script + +# TODO this needs updating with the new ibek support command set + # For RTEMS builds, avoid also building for the host architecture if [[ $TARGET_ARCHITECTURE == "rtems" ]]; then @@ -8,4 +14,6 @@ if [[ $TARGET_ARCHITECTURE == "rtems" ]]; then echo >> configure/CONFIG_SITE.Common.linux-x86_64 echo "VALID_BUILDS=Host" >> configure/CONFIG_SITE.Common.linux-x86_64 -fi \ No newline at end of file +else + echo No global changes needed for this build ... +fi diff --git a/_global/ibek.defs.schema.json b/_global/ibek.defs.schema.json deleted file mode 100644 index 7a682fc..0000000 --- a/_global/ibek.defs.schema.json +++ /dev/null @@ -1,562 +0,0 @@ -{ - "$defs": { - "BoolArg": { - "additionalProperties": false, - "description": "An argument with an bool value", - "properties": { - "type": { - "const": "bool", - "default": "bool", - "title": "Type" - }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the argument will be used for", - "title": "Description", - "type": "string" - }, - "default": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Default" - } - }, - "required": [ - "name", - "description" - ], - "title": "BoolArg", - "type": "object" - }, - "Comment": { - "additionalProperties": false, - "description": "\n A script snippet that will have '# ' prepended to every line\n for insertion into the startup script\n ", - "properties": { - "type": { - "const": "comment", - "default": "comment", - "title": "Type" - }, - "when": { - "allOf": [ - { - "$ref": "#/$defs/When" - } - ], - "default": "every", - "description": "One of first / every / last" - }, - "value": { - "default": "", - "description": "A comment to add into the startup script", - "title": "Value", - "type": "string" - } - }, - "title": "Comment", - "type": "object" - }, - "Database": { - "additionalProperties": false, - "description": "\n A database file that should be loaded by the startup script and its args\n ", - "properties": { - "file": { - "description": "Filename of the database template in /db", - "title": "File", - "type": "string" - }, - "args": { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "description": "Dictionary of args and values to pass through to database. A value of None is equivalent to ARG: '{{ ARG }}'", - "title": "Args", - "type": "object" - } - }, - "required": [ - "file", - "args" - ], - "title": "Database", - "type": "object" - }, - "Definition": { - "additionalProperties": false, - "description": "\n A single definition of a class of Entity that an IOC instance may instantiate\n ", - "properties": { - "name": { - "description": "Publish Definition as type . for IOC instances", - "title": "Name", - "type": "string" - }, - "description": { - "description": "A description of the Support module defined here", - "title": "Description", - "type": "string" - }, - "args": { - "default": [], - "description": "The arguments IOC instance should supply", - "items": { - "anyOf": [ - { - "$ref": "#/$defs/FloatArg" - }, - { - "$ref": "#/$defs/StrArg" - }, - { - "$ref": "#/$defs/IntArg" - }, - { - "$ref": "#/$defs/BoolArg" - }, - { - "$ref": "#/$defs/ObjectArg" - }, - { - "$ref": "#/$defs/IdArg" - } - ] - }, - "title": "Args", - "type": "array" - }, - "values": { - "default": [], - "description": "The values IOC instance should supply", - "items": { - "$ref": "#/$defs/Value" - }, - "title": "Values", - "type": "array" - }, - "databases": { - "default": [], - "description": "Databases to instantiate", - "items": { - "$ref": "#/$defs/Database" - }, - "title": "Databases", - "type": "array" - }, - "pre_init": { - "default": [], - "description": "Startup script snippets to add before iocInit()", - "items": { - "anyOf": [ - { - "$ref": "#/$defs/Function" - }, - { - "$ref": "#/$defs/Comment" - }, - { - "$ref": "#/$defs/Text" - } - ] - }, - "title": "Pre Init", - "type": "array" - }, - "post_init": { - "default": [], - "description": "Startup script snippets to add post iocInit(), such as dbpf", - "items": { - "anyOf": [ - { - "$ref": "#/$defs/Function" - }, - { - "$ref": "#/$defs/Comment" - }, - { - "$ref": "#/$defs/Text" - } - ] - }, - "title": "Post Init", - "type": "array" - }, - "env_vars": { - "default": [], - "description": "Environment variables to set in the boot script", - "items": { - "$ref": "#/$defs/EnvironmentVariable" - }, - "title": "Env Vars", - "type": "array" - } - }, - "required": [ - "name", - "description" - ], - "title": "Definition", - "type": "object" - }, - "EnvironmentVariable": { - "additionalProperties": false, - "description": "\n An environment variable that should be set in the startup script\n ", - "properties": { - "name": { - "description": "Name of environment variable", - "title": "Name", - "type": "string" - }, - "value": { - "description": "Value to set", - "title": "Value", - "type": "string" - } - }, - "required": [ - "name", - "value" - ], - "title": "EnvironmentVariable", - "type": "object" - }, - "FloatArg": { - "additionalProperties": false, - "description": "An argument with a float value", - "properties": { - "type": { - "const": "float", - "default": "float", - "title": "Type" - }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the argument will be used for", - "title": "Description", - "type": "string" - }, - "default": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Default" - } - }, - "required": [ - "name", - "description" - ], - "title": "FloatArg", - "type": "object" - }, - "Function": { - "additionalProperties": false, - "description": "\n A script snippet that defines a function to call\n ", - "properties": { - "name": { - "description": "Name of the function to call", - "title": "Name", - "type": "string" - }, - "args": { - "description": "The arguments to pass to the function", - "title": "Args", - "type": "object" - }, - "header": { - "default": "", - "description": "commands/comments to appear before the function", - "title": "Header", - "type": "string" - }, - "when": { - "allOf": [ - { - "$ref": "#/$defs/When" - } - ], - "default": "every", - "description": "one of first / every / last" - }, - "type": { - "const": "function", - "default": "function", - "title": "Type" - } - }, - "required": [ - "name", - "args" - ], - "title": "Function", - "type": "object" - }, - "IdArg": { - "additionalProperties": false, - "description": "Explicit ID argument that an object can refer to", - "properties": { - "type": { - "const": "id", - "default": "id", - "title": "Type" - }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the argument will be used for", - "title": "Description", - "type": "string" - }, - "default": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Default" - } - }, - "required": [ - "name", - "description" - ], - "title": "IdArg", - "type": "object" - }, - "IntArg": { - "additionalProperties": false, - "description": "An argument with an int value", - "properties": { - "type": { - "const": "int", - "default": "int", - "title": "Type" - }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the argument will be used for", - "title": "Description", - "type": "string" - }, - "default": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Default" - } - }, - "required": [ - "name", - "description" - ], - "title": "IntArg", - "type": "object" - }, - "ObjectArg": { - "additionalProperties": false, - "description": "A reference to another entity defined in this IOC", - "properties": { - "type": { - "const": "object", - "default": "object", - "title": "Type" - }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the argument will be used for", - "title": "Description", - "type": "string" - }, - "default": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Default" - } - }, - "required": [ - "name", - "description" - ], - "title": "ObjectArg", - "type": "object" - }, - "StrArg": { - "additionalProperties": false, - "description": "An argument with a str value", - "properties": { - "type": { - "const": "str", - "default": "str", - "title": "Type" - }, - "name": { - "description": "Name of the argument that the IOC instance should pass", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the argument will be used for", - "title": "Description", - "type": "string" - }, - "default": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Default" - } - }, - "required": [ - "name", - "description" - ], - "title": "StrArg", - "type": "object" - }, - "Text": { - "additionalProperties": false, - "description": "\n A script snippet to insert into the startup script\n ", - "properties": { - "type": { - "const": "text", - "default": "text", - "title": "Type" - }, - "when": { - "default": "every", - "description": "One of first / every / last", - "title": "When", - "type": "string" - }, - "value": { - "default": "", - "description": "raw text to add to the startup script", - "title": "Value", - "type": "string" - } - }, - "title": "Text", - "type": "object" - }, - "Value": { - "additionalProperties": false, - "description": "A calculated string value for a definition", - "properties": { - "name": { - "description": "Name of the value that the IOC instance will expose", - "title": "Name", - "type": "string" - }, - "description": { - "description": "Description of what the value will be used for", - "title": "Description", - "type": "string" - }, - "value": { - "description": "The contents of the value", - "title": "Value", - "type": "string" - } - }, - "required": [ - "name", - "description", - "value" - ], - "title": "Value", - "type": "object" - }, - "When": { - "enum": [ - "first", - "every", - "last" - ], - "title": "When", - "type": "string" - } - }, - "additionalProperties": false, - "description": "\n Lists the definitions for a support module, this defines what Entities it supports\n\n Provides the deserialize entry point.\n ", - "properties": { - "module": { - "description": "Support module name, normally the repo name", - "title": "Module", - "type": "string" - }, - "defs": { - "description": "The definitions an IOC can create using this module", - "items": { - "$ref": "#/$defs/Definition" - }, - "title": "Defs", - "type": "array" - } - }, - "required": [ - "module", - "defs" - ], - "title": "Support", - "type": "object" -} \ No newline at end of file diff --git a/asyn/asyn.sh b/asyn/asyn.sh deleted file mode 100644 index 18c0385..0000000 --- a/asyn/asyn.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -# patch asyn for compatibility with the container base OS Ubuntu - -if [[ $TARGET_ARCHITECTURE != "rtems" ]]; then - # Enable TIRPC for ASYN - sed -i 's:# TIRPC:TIRPC:g' configure/CONFIG_SITE -else - # don't build the test directories (they don't compile on RTEMS) - sed -i '/DIRS += .*test/d' Makefile -fi - -# remove dependency on IPAC support -sed -i 's:IPAC=:# IPAC=:g' configure/RELEASE \ No newline at end of file diff --git a/asyn/install.sh b/asyn/install.sh new file mode 100755 index 0000000..8286fd6 --- /dev/null +++ b/asyn/install.sh @@ -0,0 +1,40 @@ +#!/bin/bash +########################################################################## +##### install script for Asyn support modules ############################ +########################################################################## + + +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=asyn + +# log output and abort on failure +set -xe + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} +ibek support register ${NAME} + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs asyn +ibek support add-dbds asyn.dbd + +# No need for IPAC unless its already installed +ibek support add-release-macro IPAC --no-replace + +# Patches to the CONFIG_SITE +if [[ $TARGET_ARCHITECTURE == "rtems" ]]; then + # don't build the test directories (they don't compile on RTEMS) + sed -i '/DIRS += ${SUPPORT}/${NAME}.*test/d' Makefile +else + ibek support add-config-macro ${NAME} TIRPC YES +fi + +# compile the support module +ibek support compile ${NAME} + +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} + + diff --git a/autosave/autosave.sh b/autosave/autosave.sh deleted file mode 100755 index 3c82fe9..0000000 --- a/autosave/autosave.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -THIS_DIR=$(dirname $(readlink -f $0)) - -if [[ $TARGET_ARCHITECTURE == "rtems" ]]; then - echo "Patching RTEMS autosave" - patch -p1 < ${THIS_DIR}/rtems-autosave.patch - - echo >> configure/CONFIG_SITE.Common.linux-x86_64 - echo "VALID_BUILDS=Host" >> configure/CONFIG_SITE.Common.linux-x86_64 -else - echo "No autosave patch required for architecture <$TARGET_ARCHITECTURE>" -fi diff --git a/autosave/install.sh b/autosave/install.sh new file mode 100755 index 0000000..cab7785 --- /dev/null +++ b/autosave/install.sh @@ -0,0 +1,42 @@ +#!/bin/bash +########################################################################## +##### install script for autosave module ################################# +########################################################################## + +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=autosave + +# log output and abort on failure +set -xe + +# get the name of this folder, i.e. the name of the support module +NAME=$(basename $(dirname ${0})) + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} +ibek support register ${NAME} + + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs autosave +ibek support add-dbds asSupport.dbd + +# Patches for RTEMS +THIS_DIR=$(dirname ${0}) + +if [[ $TARGET_ARCHITECTURE == "rtems" ]]; then + echo "Patching RTEMS autosave" + patch -p1 < ${THIS_DIR}/rtems-autosave.patch + + echo >> ${SUPPORT}/${NAME}/configure/CONFIG_SITE.Common.linux-x86_64 + echo "VALID_BUILDS=Host" >> configure/CONFIG_SITE.Common.linux-x86_64 +fi + +# compile the support module +ibek support compile ${NAME} +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} + + diff --git a/busy/install.sh b/busy/install.sh new file mode 100755 index 0000000..b6d3dfb --- /dev/null +++ b/busy/install.sh @@ -0,0 +1,28 @@ +#!/bin/bash +########################################################################## +##### install script for busy support module ############################ +########################################################################## + +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=busy + +# log output and abort on failure +set -xe + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} +ibek support register ${NAME} + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs busy +ibek support add-dbds busySupport.dbd + +# compile the support module +ibek support compile ${NAME} +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} + + + diff --git a/busy/place_holder b/busy/place_holder deleted file mode 100644 index e69de29..0000000 diff --git a/ioc/README.md b/ioc/README.md new file mode 100644 index 0000000..550e92d --- /dev/null +++ b/ioc/README.md @@ -0,0 +1,5 @@ +Test IOCs for ibek-support +========================== + +This ioc folder is copied into the test images by Dockerfile.xxx in +the tests folder. \ No newline at end of file diff --git a/ioc/config/st.cmd b/ioc/config/st.cmd new file mode 100755 index 0000000..fddac5f --- /dev/null +++ b/ioc/config/st.cmd @@ -0,0 +1,10 @@ +# Basic test IOC startup script to verify IOC can execute + +cd "$(TOP)" + +dbLoadDatabase "dbd/ioc.dbd" +ioc_registerRecordDeviceDriver(pdbbase) + +# start IOC shell +iocInit + diff --git a/ioc/liveness.sh b/ioc/liveness.sh new file mode 100755 index 0000000..861e5c4 --- /dev/null +++ b/ioc/liveness.sh @@ -0,0 +1,40 @@ +#!/bin/bash +TOP=/repos/epics/ioc +cd ${TOP} +CONFIG_DIR=${TOP}/config + +set -ex + +CONFIG_DIR=/repos/epics/ioc/config +THIS_SCRIPT=$(realpath ${0}) +override=${CONFIG_DIR}/liveness.sh + +if [[ -f ${override} && ${override} != ${THIS_SCRIPT} ]]; then + exec bash ${override} +fi + +if [[ ${K8S_IOC_LIVENESS_ENABLED} != 'true' ]]; then + exit 0 +fi + +# use devIOCStats UPTIME as the default liveness PV +# but allow override from the environment +K8S_IOC_PV=${K8S_IOC_PV:-"${IOC_PREFIX}:UPTIME"} + +# use default CA PORT or override from the environment +K8S_IOC_PORT=${K8S_IOC_PORT:-5064} + +export EPICS_CA_ADDR_LIST=${K8S_IOC_ADDRESS} +export EPICS_CA_SERVER_PORT=${K8S_IOC_PORT} + +# verify that the IOC is running +if caget ${K8S_IOC_PV} ; then + exit 0 +else + # send the error message to the container's main process stdout + echo "Liveness check failed for ${IOC_NAME}" > /proc/1/fd/1 + echo "Failing PV: ${K8S_IOC_PV}" > /proc/1/fd/2 + echo "Address list: ${EPICS_CA_ADDR_LIST}" > /proc/1/fd/2 + echo "CA Port: ${EPICS_CA_SERVER_PORT}" > /proc/1/fd/2 + exit 1 +fi diff --git a/ioc/start.sh b/ioc/start.sh new file mode 100755 index 0000000..6216579 --- /dev/null +++ b/ioc/start.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +# +# The epics-containers IOC startup script. +# +# This script is used to start an EPICS IOC in a Kubernetes pod. Implementers +# of generic IOCs are free to replace this script with their own. But +# this script as is should work for most IOCs. +# +# When a generic IOC runs in a kubernetes pod it is expected to have +# a config folder that defines the IOC instance. +# The helm chart for the generic IOC will mount the config folder +# as a configMap and this turns a generic IOC into aspecific IOC instance. +# +# Here we support the following set of options for the contents of +# the config folder: +# +# 1. start.sh ****************************************************************** +# If the config folder contains a start.sh script it will be executed. +# This allows the instance implementer to provide a conmpletely custom +# startup script. +# +# 2. ioc.yaml ************************************************************* +# If the config folder contains an ioc.yaml file we invoke the ibek tool to +# generate the startup script and database. Then launch with the generated +# startup script. +# +# 3. st.cmd + ioc.subst ********************************************************* +# If the config folder contains a st.cmd script and a ioc.subst file then +# optionally generate ioc.db from the ioc.subst file and use the st.cmd script +# as the IOC startup script. Note that the expanded database file will +# be generated in /tmp/ioc.db +# +# 4. empty config folder ******************************************************* +# If the config folder is empty then this IOC will launch the example in +# ./example folder +# +# RTEMS IOCS - RTEMS IOC startup files can be generated using 2,3,4 above. For +# RTEMS we do not execute the ioc inside of the pod. Instead we: +# - copy the IOC directory to the RTEMS mount point +# - send a reboot command to the RTEMS crate +# - start a telnet session to the RTEMS IOC console +# + +set -x -e + +# environment setup ************************************************************ + +export TOP=$(realpath $(dirname $0)) +cd ${TOP} +CONFIG_DIR=${TOP}/config + +# add module paths to environment for use in ioc startup script +source ${SUPPORT}/configure/RELEASE.shell + +# override startup script +override=${CONFIG_DIR}/start.sh +# source YAML for IOC Builder for EPICS on Kubernetes (ibek) +ibek_src=${CONFIG_DIR}/ioc.yaml +# Startup script for EPICS IOC generated by ibek +ioc_startup=${CONFIG_DIR}/st.cmd +# expanded database file +epics_db=/tmp/ioc.db + + +# 1. start.sh ****************************************************************** + +if [ -f ${override} ]; then + exec ${override} + +# 2. ioc.yaml ****************************************************************** + +elif [ -f ${ibek_src} ]; then + # Database generation script generated by ibek + db_src=/tmp/make_db.sh + final_ioc_startup=/tmp/st.cmd + + # get ibek the support yaml files this ioc's support modules + defs=/ctools/*/*.ibek.support.yaml + ibek build-startup ${ibek_src} ${defs} --out ${final_ioc_startup} --db-out ${db_src} + + # build expanded database using the db_src shell script + if [ -f ${db_src} ]; then + bash ${db_src} > ${epics_db} + fi + +# 3. st.cmd + ioc.substitutions ************************************************ + +elif [ -f ${ioc_startup} ] ; then + if [ -f ${CONFIG_DIR}/ioc.substitutions ]; then + # generate ioc.db from ioc.substitutions, including all templates from SUPPORT + includes=$(for i in ${SUPPORT}/*/db; do echo -n "-I $i "; done) + msi ${includes} -S ${CONFIG_DIR}/ioc.substitutions -o ${epics_db} + fi + final_ioc_startup=${ioc_startup} + +# 4. empty config folder ******************************************************* + +else + final_ioc_startup=${TOP}/example/st.cmd +fi + +# Launch the IOC *************************************************************** + +if [[ ${TARGET_ARCHITECTURE} == "rtems" ]] ; then + echo "RTEMS IOC startup - copying IOC to RTEMS mount point ..." + cp -r ${IOC} ${K8S_IOC_ROOT} + sleep 100 +else + # Execute the IOC binary and pass the startup script as an argument + exec ${IOC}/bin/linux-x86_64/ioc ${final_ioc_startup} +fi diff --git a/ioc/stop.sh b/ioc/stop.sh new file mode 100644 index 0000000..9d92a1e --- /dev/null +++ b/ioc/stop.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +TOP=/repos/epics/ioc +cd ${TOP} +CONFIG_DIR=${TOP}/config + +override=${CONFIG_DIR}/stop.sh + +if [[ -f ${override} ]]; then + exec bash ${override} +elif [[ ${RTEMS_VME_AUTO_REBOOT} == 'true' ]] ; then + # This is a placeholder for a script that is called when the pod is stopped. + # Placing your own stop.sh in the config directory will override this script. +fi + + diff --git a/iocStats/install.sh b/iocStats/install.sh new file mode 100755 index 0000000..d9d0a19 --- /dev/null +++ b/iocStats/install.sh @@ -0,0 +1,27 @@ +#!/bin/bash +########################################################################## +##### install script for iocStats support module ######################### +########################################################################## + +# ARGUMENTS: +# $1 VERSION to install (must match repo tag) +VERSION=${1} +NAME=iocStats + +# log output and abort on failure +set -xe + +# get the source and fix up the configure/RELEASE files +ibek support git-clone ${NAME} ${VERSION} +ibek support register ${NAME} + +# declare the libs and DBDs that are required in ioc/iocApp/src/Makefile +ibek support add-libs devIocStats +ibek support add-dbds devIocStats.dbd + +# compile the support module +ibek support compile ${NAME} + +# prepare *.bob, *.pvi, *.ibek.support.yaml for access outside the container. +ibek support generate-links ${NAME} + diff --git a/_global/devIocStats.ibek.support.yaml b/iocStats/iocStats.ibek.support.yaml similarity index 100% rename from _global/devIocStats.ibek.support.yaml rename to iocStats/iocStats.ibek.support.yaml diff --git a/make_global_schemas.sh b/make_global_schemas.sh index 11f0bba..b95960b 100755 --- a/make_global_schemas.sh +++ b/make_global_schemas.sh @@ -7,7 +7,7 @@ # all.ibek.support.schema.json is a global schema for **ibek.ioc.yaml files # which includes all the support schemas. -THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +THIS_DIR="$(realname "$(dirname "$0")" cd $THIS_DIR diff --git a/tests/Dockerfile.asyn b/tests/Dockerfile.asyn new file mode 100644 index 0000000..6582b71 --- /dev/null +++ b/tests/Dockerfile.asyn @@ -0,0 +1,47 @@ +##### build stage ############################################################## + +ARG BASE +ARG REGISTRY +ARG TARGET_ARCHITECTURE + +FROM ${REGISTRY}/epics-base-${TARGET_ARCHITECTURE}-developer:${BASE} AS developer + +# In a devcontainer this folder is mounted on the host's clone of ioc-adsimdetector +WORKDIR /workspaces/ioc-adsimdetector/ibek-support + +# copy the global ibek files +COPY ibek-support/_global/ _global + +COPY ibek-support/asyn/ asyn/ +RUN asyn/install.sh R4-42 + +# Make the IOC +RUN ibek ioc generate-makefile +RUN ibek ioc compile + +##### runtime preparation stage ################################################ + +FROM developer AS runtime_prep + +# get the products from the build stage and reduce to runtime assets only +WORKDIR /min_files +RUN bash /epics/scripts/minimize.sh ${IOC} $(ls -d ${SUPPORT}/*/) + +##### runtime stage ############################################################ + +FROM ${REGISTRY}/epics-base-${TARGET_ARCHITECTURE}-runtime:${BASE} AS runtime + +# get the virtual environment from the developer stage +COPY --from=developer /venv /venv +# add products from build stage +COPY --from=runtime_prep /min_files / + +# install runtime system dependencies, collected from install.sh scripts +RUN ibek support apt-install --runtime + +# add ioc sample startup scripts +COPY ioc ${IOC} + +ENV TARGET_ARCHITECTURE ${TARGET_ARCHITECTURE} + +ENTRYPOINT ["/bin/bash", "-c", "${IOC}/start.sh"] diff --git a/tests/Dockerfile.busy b/tests/Dockerfile.busy new file mode 100644 index 0000000..4b53d5e --- /dev/null +++ b/tests/Dockerfile.busy @@ -0,0 +1,53 @@ +##### build stage ############################################################## + +ARG BASE +ARG REGISTRY +ARG TARGET_ARCHITECTURE + +FROM ${REGISTRY}/epics-base-${TARGET_ARCHITECTURE}-developer:${BASE} AS developer + +# In a devcontainer this folder is mounted on the host's clone of ioc-adsimdetector +WORKDIR /workspaces/ioc-adsimdetector/ibek-support + +# copy the global ibek files +COPY ibek-support/_global/ _global + +# busy depends on asyn and autosave +COPY ibek-support/asyn/ asyn/ +RUN asyn/install.sh R4-42 +COPY ibek-support/autosave/ autosave/ +RUN autosave/install.sh R5-10-2 + +COPY ibek-support/busy/ busy/ +RUN busy/install.sh R1-7-3 + +# Make the IOC +RUN ibek ioc generate-makefile +RUN ibek ioc compile + +##### runtime preparation stage ################################################ + +FROM developer AS runtime_prep + +# get the products from the build stage and reduce to runtime assets only +WORKDIR /min_files +RUN bash /epics/scripts/minimize.sh ${IOC} $(ls -d ${SUPPORT}/*/) + +##### runtime stage ############################################################ + +FROM ${REGISTRY}/epics-base-${TARGET_ARCHITECTURE}-runtime:${BASE} AS runtime + +# get the virtual environment from the developer stage +COPY --from=developer /venv /venv +# add products from build stage +COPY --from=runtime_prep /min_files / + +# install runtime system dependencies, collected from install.sh scripts +RUN ibek support apt-install --runtime + +# add ioc sample startup scripts +COPY ioc ${IOC} + +ENV TARGET_ARCHITECTURE ${TARGET_ARCHITECTURE} + +ENTRYPOINT ["/bin/bash", "-c", "${IOC}/start.sh"] diff --git a/tests/Verify.asyn.sh b/tests/Verify.asyn.sh new file mode 100644 index 0000000..ce1ae74 --- /dev/null +++ b/tests/Verify.asyn.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "HELLO WORLD" \ No newline at end of file diff --git a/tests/Verify.busy.sh b/tests/Verify.busy.sh new file mode 100644 index 0000000..8ce1569 --- /dev/null +++ b/tests/Verify.busy.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +echo TODO add tests for busy support module diff --git a/tests/_test_support_build.sh b/tests/_test_support_build.sh new file mode 100755 index 0000000..dd45bdb --- /dev/null +++ b/tests/_test_support_build.sh @@ -0,0 +1,123 @@ +#!/bin/bash + +# A script for building EPICS container images. +# +# Note that this is implemented in bash to make it portable between +# CI frameworks. This approach uses the minimum of GitHub Actions. +# Also works locally for testing outside of CI (with podman-docker installed) +# +# INPUTS: +# PUSH: if true, push the container image to the registry +# TAG: the tag to use for the container image +# REGISTRY: the container registry to push to +# REPOSITORY: the container repository to push to +# CACHE: the directory to use for caching +# PLATFORM: the platform to build for (linux/amd64 or linux/arm64) + +set -xe + +THIS_FOLDER=$(dirname ${0}) +# ibek-support is normally a submodule of the Docker Context so we need to +# pass the container context as the folder above the ibek-support folder +CONTEXT=$(realpath ${THIS_FOLDER}/../..) + +BASE_VERSION="23.9.3" + +ARCH=${ARCH:-linux} +PLATFORM=${PLATFORM:-linux/amd64} +TAG=${TAG:-latest} + +if [[ -z "${1}" ]]; then + DOCKERFILES=$(ls ${THIS_FOLDER}/Dockerfile.*) +else + DOCKERFILES=${THIS_FOLDER}/Dockerfile.${1} +fi + +# decide on container build tool +if which docker > /dev/null ; then + docker=docker +else + echo using podman + docker=podman +fi + +NEWCACHE=${CACHE}-new + +# check for podman - it might be aliased to docker so -v gets the real name +if $docker -v | grep podman ; then + # podman command line parameters (just use local cache) + cachefrom="" + cacheto="" +else + # setup a buildx driver for multi-arch / remote cached builds + docker buildx create --driver docker-container --use + # docker command line parameters + cachefrom=--cache-from=type=local,src=${CACHE} + cacheto=--cache-to=type=local,dest=${NEWCACHE},mode=max +fi + +do_build() { + TARGET_ARCHITECTURE=$1 + TARGET=$2 + DOCKERFILE=$3 + shift 3 + + args=" + --build-arg TARGET_ARCHITECTURE=${TARGET_ARCHITECTURE} + --build-arg BASE=${BASE_VERSION} + --build-arg REGISTRY=ghcr.io/epics-containers + --target ${TARGET} + --load + -t test_image_only + -f ${DOCKERFILE} + " + if [[ ${TARGET_ARCHITECTURE} == "linux" ]] ; then + args="${args} --platform=${PLATFORM}" + fi + + echo "CONTAINER BUILD FOR ${image_name} with ARCHITECTURE=${TARGET_ARCHITECTURE} ..." + + ( + set -x + $docker buildx build ${args} ${*} ${CONTEXT} + ) +} + + +# build the container images for each Dockerfile in tests folder + +for dockerfile in ${DOCKERFILES}; do + # make two targets from each Dockerfile + do_build ${ARCH} developer ${dockerfile} + do_build ${ARCH} runtime ${dockerfile} + + # launch the runtime IOC container + $docker run --name test_me --rm -dit test_image_only + + # verify that the IOC is running - but give it time to start + for retry in {1..10}; do + sleep 1 + if $docker exec test_me ps aux | grep /epics/ioc/bin/linux-x86_64/ioc ; then + echo "IOC is running" + break + fi + done + + # The above check is sufficient to show that the generic IOC will load and + # run and that all the necessary runtime libraries are in place. + # + # for more detailed testing add a Verify.xxx.sh script where xxx is the + # the same as the suffix on the Dockerfile. See Verify.asyn for an example. + VERIFY=Verify."${dockerfile#*.}" + if [[ -f ${THIS_FOLDER}/${VERIFY} ]] ; then + $THIS_FOLDER/${VERIFY} test_me + fi + + $docker stop -t0 test_me + + if [[ $retry == 10 ]] ; then + echo "ERROR: IOC for ${dockerfile} did not start" + exit 1 + fi +done +