diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 92d81d5..fab021b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -13,8 +13,6 @@ } }, "remoteEnv": { - // allows X11 apps to run inside the container - "DISPLAY": "${localEnv:DISPLAY}", // provides a name for epics-containers to use in bash prompt etc. "EC_PROJECT": "${localWorkspaceFolderBasename}" }, @@ -26,9 +24,9 @@ } }, // IMPORTANT for this devcontainer to work with docker EC_REMOTE_USER must be - // set to vscode. You will run as vscode with full sudo rights. + // set to your user name. You will run full sudo rights. // For podman it should be left blank. You will run as root but host mounts - // will be owned by your user. + // will be owned by your user id. "remoteUser": "${localEnv:EC_REMOTE_USER}", "customizations": { "vscode": { @@ -48,8 +46,9 @@ // One time global setup commands inside the container "postCreateCommand": "bash .devcontainer/postCreateCommand ${devcontainerId}", "runArgs": [ - // Allow the container to access the host X11 display and EPICS CA - "--net=host", + // IMPORTANT: this network must exist before the container is created + // source compose/environment.sh to create it before first use + "--network=channel_access", // Make sure SELinux does not disable write access to host filesystems like tmp "--security-opt=label=disable" ], @@ -62,6 +61,6 @@ // in this way the devcontainer and runtime look very similar "source=${localWorkspaceFolder},target=/epics/generic-source,type=bind", // Mount the opi folder so we can use phoebus from outside the container - "source=${localWorkspaceFolder}/opi,target=/epics/opi,type=bind" + "source=${localWorkspaceFolder}/opi/ioc,target=/epics/opi,type=bind" ] } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7143991..10ff20f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,8 @@ 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/* -!opi/.placeholder +opi/ioc/* +!opi/ioc/.placeholder # podman may leave this around in aborted builds .build.swp diff --git a/compose/compose.yaml b/compose/compose.yaml new file mode 100644 index 0000000..2aacfd1 --- /dev/null +++ b/compose/compose.yaml @@ -0,0 +1,11 @@ +# 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 new file mode 100644 index 0000000..502e297 --- /dev/null +++ b/compose/environment.sh @@ -0,0 +1,54 @@ +#! /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 exists channel_access ; then + docker network create --subnet="170.20.0.0/16" channel_access +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 new file mode 100644 index 0000000..4b50776 --- /dev/null +++ b/compose/services/gateway/compose.yml @@ -0,0 +1,54 @@ +# 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: + + configs: + - source: ca-gateway_config + target: /config + + command: -cip 170.20.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: + external: true \ No newline at end of file diff --git a/compose/services/gateway/config/access b/compose/services/gateway/config/access new file mode 100644 index 0000000..f69d0e8 --- /dev/null +++ b/compose/services/gateway/config/access @@ -0,0 +1,6 @@ +# 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 new file mode 100644 index 0000000..209c98b --- /dev/null +++ b/compose/services/gateway/config/pvlist @@ -0,0 +1,7 @@ +# 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 new file mode 100644 index 0000000..cdc32b8 --- /dev/null +++ b/compose/services/phoebus/compose.yml @@ -0,0 +1,32 @@ +# 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/ioc/index.bob -server 7010 + volumes: + - /tmp/.X11-unix:/tmp/.X11-unix + - ~/.Xauthority:/root/.Xauthority + - ../../../opi:/opi + # 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 new file mode 100644 index 0000000..c4d462b --- /dev/null +++ b/compose/services/phoebus/config/settings.ini @@ -0,0 +1,4 @@ +# 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/opi/.placeholder b/opi/ioc/.placeholder similarity index 100% rename from opi/.placeholder rename to opi/ioc/.placeholder