diff --git a/.copier-answers.yml b/.copier-answers.yml index 2558940..19f867c 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,9 +1,9 @@ # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: 4.0.1 +_commit: 4.1.0 _src_path: gh:epics-containers/ioc-template description: A Generic IOC for the terminal server git_platform: github.com -github_org: maxherbs +github_org: epics-containers name: ioc-terminalserver -repo_uri: git@github.com:maxherbs/ioc-terminalserver.git +repo_uri: git@github.com:epics-containers/ioc-terminalserver.git rtems: false diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c369aa0..ad36638 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,18 +15,17 @@ "remoteEnv": { // provides a name for epics-containers to use in bash prompt etc. "EC_PROJECT": "${localWorkspaceFolderBasename}", - "EPICS_CA_AUTO_ADDR_LIST": "NO", - "EPICS_CA_ADDR_LIST": "127.0.0.1" + "IOC_NAME": "DEV_TEST_IOC" }, "features": { - // add quality of life features for developers including git config integration - "ghcr.io/devcontainers/features/common-utils:2": { - // don't upgrade to make this similar to the runtime container - "upgradePackages": false - } + // add in eternal history and other bash features + "ghcr.io/diamondlightsource/devcontainer-features/bash-config:1.0.0": {} }, - // IMPORTANT for this devcontainer to work with docker EC_REMOTE_USER must be - // set to your user name. You will run with full sudo rights. + // outside of the container setup + "initializeCommand": "bash .devcontainer/initializeCommand ${devcontainerId}", + // IMPORTANT for this devcontainer to work with docker rootful + // EC_REMOTE_USER must be set to your user name. You will run with full + // sudo rights. // For podman it should be left blank. You will run as root but host mounts // will be owned by your user id. "remoteUser": "${localEnv:EC_REMOTE_USER}", @@ -35,22 +34,15 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-python.vscode-pylance", - "tamasfe.even-better-toml", "redhat.vscode-yaml", - "ryanluker.vscode-coverage-gutters", "epicsdeb.vscode-epics", "charliermarsh.ruff" ] } }, - // You can place any outside of the container before-launch commands here - "initializeCommand": "bash .devcontainer/initializeCommand ${devcontainerId}", // One time global setup commands inside the container "postCreateCommand": "bash .devcontainer/postCreateCommand ${devcontainerId}", "runArgs": [ - // IMPORTANT: this network must exist before the container is created - // source compose/environment.sh to create it before first use - "--network=channel_access_devcontainer", // Make sure SELinux does not disable write access to host filesystems like tmp "--security-opt=label=disable" ], diff --git a/.devcontainer/initializeCommand b/.devcontainer/initializeCommand index 5cd42cd..36799f0 100644 --- a/.devcontainer/initializeCommand +++ b/.devcontainer/initializeCommand @@ -3,11 +3,14 @@ # custom initialization goes here - runs outside of the dev container # just before the container is launched but after the container is created -FOLDER=$(dirname $(readlink -f $0)) +echo "initializeCommand for devcontainerID ${1}" +set -xe -echo "devcontainerID ${1}" +# make the config folder for the shared bash-config feature +mkdir -p ${HOME}/.config/bash-config +# make a folder for auto-generated opi screens +mkdir -p ./opi/auto-generated + +# ensure local container users can access X11 server +xhost +SI:localuser:$(id -un) -# make sure the shared network is created -# TODO this would be better done with compose but compose and podman -# in devcontainers is not currently stable. -source $FOLDER/../compose/environment.sh diff --git a/.devcontainer/postCreateCommand b/.devcontainer/postCreateCommand index ac30849..9347e45 100644 --- a/.devcontainer/postCreateCommand +++ b/.devcontainer/postCreateCommand @@ -23,7 +23,7 @@ echo 'source <(ibek --show-completion bash)' >> $HOME/.bashrc echo 'source <(ibek --show-completion zsh)' >> $HOME/.zshrc # pick theme and RPS1 with no unicode chars to avoid completion corruption in zsh -sed -i $HOME/.zshrc -e 's/ZSH_THEME="devcontainers"/ZSH_THEME="dst"/' -e '/^RPS1=/d' +sed -i $HOME/.zshrc -e 's/^ZSH_THEME.*$/ZSH_THEME="dst"/' -e '/^RPS1=/d' # override the response PS - this shows the last exit code in red only # echo "RPS1=$'%(?..%{\C-[[01;31m%}%? %{\C-[[00m%})'" >> $HOME/.zshrc diff --git a/.gitignore b/.gitignore index 188285c..ce44137 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,7 @@ ibek # config folder is a container mount at /epics/ioc/config ioc/config # the opi folder is also mounted into the container at /epics/ioc/opi -opi/auto-generated/* -!opi/auto-generated/.placeholder +opi/auto-generated # podman may leave this around in aborted builds .build.swp diff --git a/Dockerfile b/Dockerfile index 4be33e9..79bec11 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,7 +34,7 @@ RUN iocStats/install.sh 3.2.0 ##### CUSTOM MODULES COPY ibek-support/calc/ calc -RUN calc/install.sh R3-7 +RUN calc/install.sh R3-7-5 COPY ibek-support/autosave/ autosave RUN autosave/install.sh R5-11 diff --git a/README.md b/README.md index 030ced5..df0120d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Generic IOC Template Repository ioc-terminalserver +# Generic IOC ioc-terminalserver ## Description A Generic IOC for the terminal server @@ -21,14 +21,11 @@ copier update -a --trust . This repository includes a developer container configuration for Visual Studio Code. This allows you to run the Generic IOC locally and debug it. See https://epics-containers.github.io/main/tutorials/dev_container.html. -### IMPORTANT: First Time Preparation +## Channel Access -The devcontainer uses a docker network that it can share with a ca-gateway in order that your PVs are accessible from your host machine. We arrange to create this network once and as long as you don't delete it or reset docker it will be available for all your devcontainers going forward. - -To create the network run the following commands: +The vscode developer container auto forwards the channel access ports on the loopback interface. If you have channel access clients running on the host machine, you can connect to the IOC by setting the `EPICS_CA_NAME_SERVERS` environment variable as follows: ```bash -cd ioc-adsimdetector -source ./compose/environment.sh +export EPICS_CA_NAME_SERVERS=127.0.0.1:5064 +caget IOCNAME:PVNAME ``` - diff --git a/build b/build index 95ab316..f02a6a7 100755 --- a/build +++ b/build @@ -20,16 +20,21 @@ fi cd $(dirname ${0}) -# use docker if available else use podman -if ! docker version &>/dev/null; then docker=podman; else docker=docker; fi -if $docker buildx version &>/dev/null; then buildx=buildx; load=--load ; fi -if [[ $DOCKER_BUILDKIT == "0" ]]; then buildx=; load=; fi +# make sure the ioc binaries and config symlink are cleaned up +git clean -fdx ioc + +# prefer docker but use podman if USE_PODMAN is set +if docker version &> /dev/null && [[ -z $USE_PODMAN ]] + then docker=docker + else docker=podman +fi # make sure new repos get their submodule ibek-support if [ ! -d ibek-support/_global ] ; then git submodule update --init ; fi -# build and developer images +# build runtime or developer image set -x -$docker $buildx build -t ${TAG} "${@}" $load \ - --build-arg IMAGE_EXT=$IMAGE_EXT \ - $runtime --target $TARGET . +$docker build -t ${TAG} "${@}" --build-arg IMAGE_EXT=$IMAGE_EXT \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + --build-arg EPICS_TARGET_ARCH=$T_A \ + --load --target $TARGET . diff --git a/compose/compose.yaml b/compose/compose.yaml deleted file mode 100644 index 2aacfd1..0000000 --- a/compose/compose.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# This docker compose definition stands up a ca-gateway and phoebus instance. -# This enables interactive testing to the IOC developer container -# -# To lauch these services:- -# source ./environment.sh -# docker compose up -d -# - -include: - - services/gateway/compose.yml - - services/phoebus/compose.yml diff --git a/compose/environment.sh b/compose/environment.sh deleted file mode 100644 index 5b9e9a4..0000000 --- a/compose/environment.sh +++ /dev/null @@ -1,55 +0,0 @@ -#! /bin/bash - -# Setup environment variables required to launch the services described in this -# repo. A standard install of docker compose and permission to run docker -# are the only other requirements (membership of the docker group). -# -# docker compose may be backed by podman or docker container engines, see -# https://epics-containers.github.io/main/tutorials/setup_workstation.html. - - -# This script must be sourced -if [ "$0" = "$BASH_SOURCE" ]; then - echo "ERROR: Please source this script (source ./environment.sh)" - exit 1 -fi - -# if there is a docker-compose module then load it -if [[ $(module avail docker-compose 2>/dev/null) != "" ]] ; then - module load docker-compose -fi - -function check_docker { - # return 0 if docker is detected, or 1 otherwise, - # cope with the possibility that podman is aliased to docker - if [[ $(docker version) =~ "Docker" ]]&> /dev/null; then - return 0 - fi - return 1 -} - -if check_docker; then - USER_ID=$(id -u); USER_GID=$(id -g) -else - USER_ID=0; USER_GID=0 - alias docker=podman -fi - -# make sure we have a network to share beteen the devcontainer and gateway container -if ! docker network inspect channel_access_devcontainer &>/dev/null ; then - docker network create --subnet="170.21.0.0/16" channel_access_devcontainer -fi - -# ensure local container users can access X11 server -xhost +SI:localuser:$(id -un) - -# Set up the environment for compose ########################################### - -# set user id for the phoebus container for easy X11 forwarding. -export UIDGID=$USER_ID:$USER_GID -# choose test profile for docker compose -export COMPOSE_PROFILES=test -# for test profile our ca-gateway publishes PVS on the loopback interface -export EPICS_CA_ADDR_LIST=127.0.0.1 -# make a short alias for docker-compose for convenience -alias ec='docker compose' diff --git a/compose/services/gateway/compose.yml b/compose/services/gateway/compose.yml deleted file mode 100644 index dcd2f3e..0000000 --- a/compose/services/gateway/compose.yml +++ /dev/null @@ -1,54 +0,0 @@ -# ca gateway for exposing container network PVs to the host's loopback interface - -services: - - # ca-gateway for test / dev ################################################## - - ca-gateway: &ca-gateway - - container_name: ca-gateway - - image: ghcr.io/epics-containers/docker-ca-gateway:2.1.3ec1 - - expose: - - 5064-5065/udp - - 5064-5065 - - ports: - # bind to localhost to isolate channel access to this host only - - 127.0.0.1:5064:5064/udp - - 127.0.0.1:5064-5065:5064-5065 - - restart: unless-stopped - - networks: - channel_access_devcontainer: - - configs: - - source: ca-gateway_config - target: /config - - command: -cip 170.21.255.255 -pvlist /config/pvlist -access /config/access -log /dev/stdout -debug 1 - - profiles: - - test - - dev - - # debugging version of gateway container ##################################### - ca-gateway-debug: - - <<: *ca-gateway - - # this image is not distroless and has network tools installed - image: ghcr.io/epics-containers/docker-ca-gateway-debug:2.1.3ec1 - - profiles: - - debug - -configs: - ca-gateway_config: - file: ./config - -networks: - channel_access_devcontainer: - external: true \ No newline at end of file diff --git a/compose/services/gateway/config/access b/compose/services/gateway/config/access deleted file mode 100644 index f69d0e8..0000000 --- a/compose/services/gateway/config/access +++ /dev/null @@ -1,6 +0,0 @@ -# See /EPICS/extensions/src/gateway/GATEWAY.access for more detailed example - -ASG(DEFAULT) { - RULE(1,READ) - RULE(1,WRITE) -} diff --git a/compose/services/gateway/config/pvlist b/compose/services/gateway/config/pvlist deleted file mode 100644 index 209c98b..0000000 --- a/compose/services/gateway/config/pvlist +++ /dev/null @@ -1,7 +0,0 @@ -# See /EPICS/extensions/src/gateway/GATEWAY.pvlist for more detailed example - -EVALUATION ORDER ALLOW, DENY - -[0-9].* ALLOW -[a-z].* ALLOW -[A-Z].* ALLOW diff --git a/compose/services/phoebus/compose.yml b/compose/services/phoebus/compose.yml deleted file mode 100644 index 0f759d7..0000000 --- a/compose/services/phoebus/compose.yml +++ /dev/null @@ -1,34 +0,0 @@ -# for development and testing it is useful to bring up phoebus instanced to -# interact with the local IOCs PVs. - -services: - phoebus: - container_name: phoebus - image: ghcr.io/epics-containers/ec-phoebus:4.7.3ec2 - environment: - DISPLAY: $DISPLAY - tty: true - # pick a server port for phoebus so it does not reconnect to existing phoebus - command: phoebus-product/phoebus.sh -settings /config/settings.ini -resource /opi/auto-generated/index.bob -server 7010 - volumes: - - /tmp/.X11-unix:/tmp/.X11-unix - - ~/.Xauthority:/root/.Xauthority - - ../../../opi:/opi - - ../../../..:/workspaces - - # for X11 to work we need to run as the same UID as the host - # IMPORTANT: set UIDGID to your host user:group e.g. 1000:1000 - # BUT: always to 0:0 if you are using podman - user: ${UIDGID} - - # network host with a gateway for CA is the most reliable way to - # get X11 forwarding to work - even with ssh->container. - network_mode: host - - configs: - - source: phoebus_config - target: /config - -configs: - phoebus_config: - file: ./config diff --git a/compose/services/phoebus/config/settings.ini b/compose/services/phoebus/config/settings.ini deleted file mode 100644 index c4d462b..0000000 --- a/compose/services/phoebus/config/settings.ini +++ /dev/null @@ -1,4 +0,0 @@ -# using localhost for channel access to isolate it to the host for development - -# TODO restore this once we have PVA gateway and IOCS running in the CNI -org.phoebus.pv.ca/addr_list=127.0.0.1 diff --git a/ibek-support b/ibek-support index 870e326..c51c413 160000 --- a/ibek-support +++ b/ibek-support @@ -1 +1 @@ -Subproject commit 870e3260ab2c98a7c72751726fd14ed23f47b1c9 +Subproject commit c51c413fa1b35dea28cca2c412a1336bbe1d5a7b diff --git a/opi/auto-generated/.placeholder b/opi/auto-generated/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/opi/phoebus-launch.sh b/opi/phoebus-launch.sh new file mode 100755 index 0000000..3341945 --- /dev/null +++ b/opi/phoebus-launch.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# A launcher for the phoebus to view the generated OPIs + +thisdir=$(realpath $(dirname $0)) +workspace=$(realpath ${thisdir}/..) + +# update settings.ini with CA and PVA ports +cat ${workspace}/opi/settings.ini | + sed -r \ + -e "s|5064|${EPICS_CA_SERVER_PORT:-5064}|" \ + -e "s|5075|${EPICS_PVA_SERVER_PORT:-5075}|" \ + -e "s|5065|${EPICS_CA_REPEATER_PORT:-5065}|" > /tmp/settings.ini + +settings=" +-resource ${workspace}/opi/auto-generated/index.bob +-settings /tmp/settings.ini +" + +if which phoebus.sh &>/dev/null ; then + echo "Using phoebus.sh from PATH" + set -x + phoebus.sh ${settings} "${@}" + +elif module load phoebus 2>/dev/null; then + echo "Using phoebus module" + set -x + phoebus.sh ${settings} "${@}" + +else + echo "No local phoebus install found, using a container" + + # prefer podman but use docker if USE_DOCKER is set + if podman version &> /dev/null && [[ -z $USE_DOCKER ]] + then docker=podman; UIDGID=0:0 + else docker=docker; UIDGID=$(id -u):$(id -g) + fi + echo "Using $docker as container runtime" + + # ensure local container users can access X11 server + xhost +SI:localuser:$(id -un) + + # settings for container launch + x11="-e DISPLAY --net host" + args="--rm -it --security-opt=label=none --user ${UIDGID}" + mounts="-v=/tmp:/tmp -v=${workspace}:/workspace -v=${workspace}/..:/workspaces" + image="ghcr.io/epics-containers/ec-phoebus:latest" + + settings=" + -resource /workspace/opi/auto-generated/index.bob + -settings /tmp/settings.ini + " + + set -x + $docker run ${mounts} ${args} ${x11} ${image} ${settings} "${@}" + +fi diff --git a/opi/settings.ini b/opi/settings.ini new file mode 100644 index 0000000..b180c26 --- /dev/null +++ b/opi/settings.ini @@ -0,0 +1,12 @@ +# NOTE: port numbers are defaults only +# this script to be processed with sed to replace port numbers +# see phoebus-launch.sh + +# point at local host for channel access +org.phoebus.pv.ca/addr_list=127.0.0.1 +org.phoebus.pv.ca/server_port=5064 +org.phoebus.pv.ca/repeater_port=5065 +org.phoebus.pv.ca/name_servers=127.0.0.1:5064 +# point at local host for pvAccess name server +org.phoebus.pv.pva/epics_pva_name_servers=127.0.0.1:5075 +org.phoebus.pv.pva/server_port=5075 \ No newline at end of file diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 3aad907..7be4f65 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -13,8 +13,11 @@ CONF=/epics/ioc/config # log commands and stop on errorsr set -ex -# use docker if available else use podman -if docker version &>/dev/null; then docker=docker; else docker=podman; fi +# prefer docker but use podman if USE_PODMAN is set +if docker version &> /dev/null && [[ -z $USE_PODMAN ]] + then docker=docker + else docker=podman +fi cd ${ROOT} @@ -23,7 +26,8 @@ export TAG=${TAG:-ec_test} if [[ ${TAG} == "ec_test" ]] ; then TARGET=runtime ./build; fi # try out a test ibek config IOC instance with the generic IOC -result=$($docker run --rm -v ${THIS}/config:${CONF} ${TAG} /epics/ioc/start.sh 2>&1) +opts="--rm --security-opt=label=disable -v ${THIS}/config:${CONF}" +result=$($docker run ${opts} ${TAG} /epics/ioc/start.sh 2>&1) # check that the IOC output expected results if echo "${result}" | grep -i error; then @@ -36,5 +40,3 @@ fi echo "Tests passed!" - -