diff --git a/.copier-answers.yml b/.copier-answers.yml index d361def..213cd3f 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: 3.6.1-7-gb5b6581 +_commit: 4.1.0b1 _src_path: gh:epics-containers/ioc-template description: Generic IOC for the Delta Tau turbo pmac and power pmac motion controllers git_platform: github.com diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c369aa0..cb296a4 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,25 +34,28 @@ // 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" ], + "appPort": [ + // Expose Channel Access on the hosts loopback interface + // NOTE: change the first port number to run more than one devcontainer + // on the same host. + // + // To access two devcontainers from the host for example: + // EPICS_CA_ADDR_LIST="127.0.0.1:5064 127.0.0.1:6064" + "127.0.0.1:5064:5064/udp", + "127.0.0.1:5064-5065:5064-5065" + ], // Mount the parent of the project folder so we can access peer projects "workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind", // mount in other useful files from the host 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 ed6e374..f69488d 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/README.md b/README.md index 0ec4293..8fd9349 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Generic IOC Template Repository ioc-pmac +# Generic IOC ioc-pmac ## Description Generic IOC for the Delta Tau turbo pmac and power pmac motion controllers @@ -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 developer container exposes 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_ADDR_LIST` environment variable as follows: ```bash -cd ioc-adsimdetector -source ./compose/environment.sh +export EPICS_CA_ADDR_LIST=127.0.0.1 +caget IOCNAME:PVNAME ``` - diff --git a/build b/build index 95ab316..0e6b1c8 100755 --- a/build +++ b/build @@ -20,8 +20,14 @@ fi cd $(dirname ${0}) -# use docker if available else use podman -if ! docker version &>/dev/null; then docker=podman; else docker=docker; fi +# make sure the ioc binaries and config symlink are cleaned up +git clean -fdx ioc + +if podman version &> /dev/null && [[ -z $USE_DOCKER ]] + 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 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 d437e6d..0000000 --- a/compose/environment.sh +++ /dev/null @@ -1,54 +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) =~ "Podman" ]]&> /dev/null; then - return 1 - fi -} - -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 c17d609..897ff57 160000 --- a/ibek-support +++ b/ibek-support @@ -1 +1 @@ -Subproject commit c17d609756cc7e487245afac6018ef311ab9a5b1 +Subproject commit 897ff57ae59f62c0f51e7fd8887bd47aa084d974 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..98a7cf9 --- /dev/null +++ b/opi/phoebus-launch.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# A launcher for the phoebus to view the generated OPIs + +thisdir=$(realpath $(dirname $0)) +workspace=$(realpath ${thisdir}/..) + +settings=" +-resource ${workspace}/opi/auto-generated/index.bob +-settings ${workspace}/opi/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" + + if podman version &> /dev/null && [[ -z $USE_DOCKER ]] ; + then docker=podman + else docker=docker + 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" + mounts="-v=/tmp:/tmp -v=${workspace}:/workspace" + image="ghcr.io/epics-containers/ec-phoebus:latest" + + settings=" + -settings /workspace/opi/settings.ini + -resource /workspace/opi/auto-generated/index.bob + " + + 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..a8fb091 --- /dev/null +++ b/opi/settings.ini @@ -0,0 +1,2 @@ +# point at local host for channel access +org.phoebus.pv.ca/addr_list=127.0.0.1 diff --git a/requirements.txt b/requirements.txt index 671ef4c..e573dc0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -ibek==3.0.1 +ibek==3.1.0 # to install direct from github during development in a branch # git+https://github.com/epics-containers/ibek.git@fix-extract-assets diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 3aad907..b7a7b69 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -13,8 +13,10 @@ 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 +if podman version &> /dev/null && [[ -z $USE_DOCKER ]] + then docker=podman + else docker=docker +fi cd ${ROOT} @@ -23,7 +25,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