Skip to content

Commit

Permalink
Add container runtime and developer environment
Browse files Browse the repository at this point in the history
Publish runtime container
Update devcontainer to build and run C++ applictions
Create full local eiger deployment
Add development quickstart guide to README
  • Loading branch information
GDYendell committed Aug 2, 2024
1 parent d81208f commit 76a5dd9
Show file tree
Hide file tree
Showing 32 changed files with 1,104 additions and 55 deletions.
51 changes: 30 additions & 21 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
// For format details, see https://containers.dev/implementors/json_reference/
{
"name": "Python 3 Developer Container",
"name": "eiger-detector devcontainer",
"build": {
"dockerfile": "../Dockerfile",
"context": "..",
"target": "developer"
},
"remoteEnv": {
// Allow X11 apps to run inside the container
"DISPLAY": "${localEnv:DISPLAY}"
"features": {
// add quality of life features for developers including git config integration
// note this is slow for the odin-data container - leaving out for now
"ghcr.io/devcontainers/features/common-utils:2": {
// don't upgrade to make this similar to the runtime container
"upgradePackages": false
}
},
// IMPORTANT for this devcontainer to work with docker VSCODE_REMOTE_USER must be
// set to vscode. You will run as vscode 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.
"remoteUser": "${localEnv:VSCODE_REMOTE_USER}",
"customizations": {
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"python.defaultInterpreterPath": "/venv/bin/python"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"github.vscode-github-actions",
"ms-python.vscode-pylance",
"tamasfe.even-better-toml",
"redhat.vscode-yaml",
"ryanluker.vscode-coverage-gutters",
"epicsdeb.vscode-epics",
"charliermarsh.ruff",
"ms-azuretools.vscode-docker"
"ms-vscode.cmake-tools",
"ms-vscode.cpptools"
]
}
},
"features": {
// Some default things like git config
"ghcr.io/devcontainers/features/common-utils:2": {
"upgradePackages": false
}
},
// 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": [
// Allow the container to access the host X11 display and EPICS CA
"--net=host",
// Make sure SELinux does not disable with access to host filesystems like tmp
// Make sure SELinux does not disable write access to host filesystems like tmp
"--security-opt=label=disable"
],
// Mount the parent as /workspaces so we can pip install peers as editable
// Mount the parent of the project folder so we can access peer projects
"workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind",
// After the container is created, install the python project in editable form
"postCreateCommand": "pip install $([ -f dev-requirements.txt ] && echo '-c dev-requirements.txt') -e './python[dev]' && pre-commit install"
// mount in other useful files from the host
"mounts": [
// add extra mounts below
// "source=${localWorkspaceFolder},target=/odin-data,type=bind"
"source=/dev/shm,target=/dev/shm,type=bind"
]
}
6 changes: 6 additions & 0 deletions .devcontainer/initializeCommand
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

# custom initialization goes here - runs outside of the dev container
# just before the container is launched but after the container is created

echo "devcontainerID ${1}"
28 changes: 28 additions & 0 deletions .devcontainer/postCreateCommand
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

# Custom initialization goes here if needed.
# Runs inside the dev container after the container is created

################################################################################
# When using docker we will not be root inside the container
# You may wish to change ownership of files you want the user to modify
################################################################################

# if [[ $USER != "root" ]] ; then
# # make sure the non-root user can build iocs and (mounted in) support modules
# # sudo chown -R ${USER}:${USER} add_folders_here_if needed
# fi

################################################################################
# Shell customizations for Generic IOC devcontainers
################################################################################

# pick a zsh theme that does not cause completion corruption in zsh vscode terminals
sed -i $HOME/.zshrc -e 's/ZSH_THEME="devcontainers"/ZSH_THEME="dst"/'

# allow personalization of all devcontainers in this subdirectory
# by placing a .devcontainer_rc file in the workspace root
if [[ -f /workspaces/.devcontainer_rc ]] ; then
source /workspaces/.devcontainer_rc
fi

10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.dockerignore

external
*build*
*prefix*
*.pyc
venv*
*.egg-info

docs/build/
92 changes: 92 additions & 0 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Container CI

on:
push:
pull_request:

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0 # All history

- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Log in to GitHub Docker Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1

- name: Build image
uses: docker/build-push-action@v4
with:
context: .
file: Dockerfile
target: runtime
push: false
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

- name: Create tags for developer image
id: meta-developer
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}-developer
tags: |
type=ref,event=tag
type=raw,value=latest
- name: Push developer image
if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }}
uses: docker/build-push-action@v4
with:
context: .
file: Dockerfile
target: developer
tags: ${{ steps.meta-developer.outputs.tags }}
labels: ${{ steps.meta-developer.outputs.labels }}
push: ${{ github.event_name != 'pull_request' }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

- name: Create tags for runtime image
id: meta-runtime
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}-runtime
tags: |
type=ref,event=tag
type=raw,value=latest
- name: Push runtime image
if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }}
uses: docker/build-push-action@v4
with:
context: .
file: Dockerfile
target: runtime
tags: ${{ steps.meta-runtime.outputs.tags }}
labels: ${{ steps.meta-runtime.outputs.labels }}
push: ${{ github.event_name != 'pull_request' }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
20 changes: 20 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"cmake.generator": "Unix Makefiles",
"cmake.sourceDirectory": "${workspaceFolder}/cpp",
"cmake.buildDirectory": "${workspaceFolder}/vscode_build",
"cmake.installPrefix": "/odin",
"cmake.configureArgs": [
"-DODINDATA_ROOT_DIR=/odin"
],
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"editor.formatOnSave": true,
"[python]": {
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.rulers": [
88
]
},
}
58 changes: 31 additions & 27 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
# The devcontainer should use the developer target and run as root with podman
# or docker with user namespaces.
ARG PYTHON_VERSION=3.11
FROM python:${PYTHON_VERSION} as developer

# Add any system dependencies for the developer/build environment here
RUN apt-get update && apt-get install -y --no-install-recommends \
graphviz \
&& rm -rf /var/lib/apt/lists/*

# Set up a virtual environment and put it in PATH
RUN python -m venv /venv
ENV PATH=/venv/bin:$PATH

# The build stage installs the context into the venv
FROM developer as build
COPY . /context
WORKDIR /context
RUN pip install ./python

# The runtime stage copies the built venv into a slim runtime container
FROM python:${PYTHON_VERSION}-slim as runtime
# Add apt-get system dependecies for runtime here if needed
COPY --from=build /venv/ /venv/
ENV PATH=/venv/bin:$PATH

ENTRYPOINT ["bash"]
FROM ghcr.io/odin-detector/odin-data-build:latest AS developer

FROM developer AS build

# Root of eiger-detector
COPY . /odin/eiger-detector

# C++
WORKDIR /odin/eiger-detector
RUN mkdir -p build && cd build && \
cmake -DCMAKE_INSTALL_PREFIX=/odin -DODINDATA_ROOT_DIR=/odin ../cpp && \
make -j8 VERBOSE=1 && \
make install

# Python
WORKDIR /odin/eiger-detector/python
RUN python -m pip install .[sim]

FROM ghcr.io/odin-detector/odin-data-runtime:latest AS runtime

COPY --from=build /odin /odin
COPY --from=build /venv /venv
COPY deploy /odin/eiger-deploy

RUN rm -rf /odin/eiger-detector

ENV PATH=/odin/bin:/odin/venv/bin:$PATH

WORKDIR /odin

CMD ["sh", "-c", "cd /odin/eiger-deploy && zellij --layout ./layout.kdl"]
44 changes: 37 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
eiger-detector
=========
# eiger-detector

Data Acquisition from the Eiger detector.
Data acquisition framework for the Eiger detector consisting of:

eigerfan: a fan-out of the Eiger zeromq push/pull stream.
- eigerfan: a fan-out of the Eiger zeromq push/pull stream
- EigerMetaWriter: A plugin for the odin-data meta_writer application
- EigerProcessPlugin: A plugin for the odin-data FrameProcessor
- EigerFrameDecoder: A plugin for the odin-data FrameReceiver

metalistener: A python application that listens for odin-data meta messages and writes data to a meta file
# Development

EigerProcessPlugin: Plugin for the odin-data FrameProcessor
A devcontainer is provided for simpler local development. To get started:

EigerFrameDecoder: Plugin for the odin-data FrameReceiver
1. Open the project in VSCode and re-open in devcontainer when prompted, or
open manually with `Dev Containers: Reopen in Container`
2. Add odin-data to with `Workspaces: Add Folder to Workspace...`
3. Build eiger-detector

i. `> CMake: Delete Cache and Reconfigure`

ii. `> CMake: Install`

4. Install the python dev dependencies and tickit simulator

ii. `$ pip install -e ./eiger-detector/python[dev,sim]`

5. Run the dev deployment from the `deploy` directory with `$ zellij -l startAll.kdl`

It is then possible to edit the python applications and restart, or edit the C++
applications, rebuild and restart.

To run the tickit simulation, add tickit-devices to the workspace, pip install, and then
run the `Eiger` launch config.

To run the IOC, add eiger-fastcs to the workspace, pip install and run the `Eiger IOC`
launch config, which talks to the tickit sim by default. The generated output.bob can
then be opened in Phoebus for GUI control.

Currently in development is odin-fastcs, which creates an EPICS IOC to control the odin
processes. To run this, add odin-fastcs to the workspace, pip install, and then run the
`Odin IOC` launch config, which by default talks to a control server at 127.0.0.1:8888.
At the time of writing, this will not produce any PVs, but at the time of following this
guide it may be functional.
3 changes: 3 additions & 0 deletions deploy/eiger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- type: tickit_devices.eiger.Eiger
inputs: {}
name: eiger
Loading

0 comments on commit 76a5dd9

Please sign in to comment.