Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---

name: Deploy Documentation
permissions:
contents: read
pages: write
id-token: write

on:
push:
branches: [main]
workflow_dispatch:

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
name: Build Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143
with:
pixi-version: v0.68.0
cache: false
frozen: true

- name: Generate Docs Table
run: pixi run docs-table

- name: Build Documentation
run: pixi run docs-build

- name: Upload Pages Artifact
uses: actions/upload-pages-artifact@v3
with:
path: site/

deploy:
name: Deploy to GitHub Pages
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion .github/workflows/superlinter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143 # yamllint disable-line rule:line-length
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-deploy-ioc-role.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand All @@ -63,7 +63,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-device-roles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/validate_module_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143 # yamllint disable-line rule:line-length
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand All @@ -46,7 +46,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143 # yamllint disable-line rule:line-length
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand All @@ -69,7 +69,7 @@ jobs:
- name: Setup Pixi
uses: prefix-dev/setup-pixi@8ca4608ef7f4daeb54f5205b20d0b7cb42f11143 # yamllint disable-line rule:line-length
with:
pixi-version: v0.55.0
pixi-version: v0.68.0
cache: false
frozen: true

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ __pycache__/
.ansible/
.pixi/
ansible_collections/
site/
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ repos:
ansible-lint --offline
--exclude roles/install_module/vars/*
--exclude scripts/deploy_ioc.yml
--exclude docs/*
--exclude site/*
--exclude roles/device_roles/adpilatus/*
description: Perform ansible linting
types: [yaml]
Comment on lines 18 to 26

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ module:

report:
pixi run report

docs-table:
pixi run docs-table
98 changes: 98 additions & 0 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Installation

## Prerequisites

- **pixi** (≥ v0.55.0) — Task runner and environment manager
- **Docker** or **Podman** — For local testing with EPICS containers
- **Git** — For cloning and version management

## Installing pixi

```bash
curl -fsSL https://pixi.sh/install.sh | bash
```

## Cloning the Repository

```bash
git clone https://github.com/NSLS2/nsls2.ioc_deploy.git
cd nsls2.ioc_deploy
```

## Installing Dependencies

All Python and Ansible dependencies are managed by pixi. Simply run any pixi task and the environment will be set up automatically:

```bash
pixi run tests
```

Or explicitly install the environment:

```bash
pixi install
```

### Key Dependencies

The pixi environment includes:

| Package | Purpose |
|---------|---------|
| `ansible` | Automation engine for running playbooks |
| `ansible-lint` | Linting for Ansible files |
| `pytest` | Test framework |
| `yamale` | YAML schema validation |
| `questionary` | Interactive prompts for collection management |
| `tabulate` | Report generation |
| `ruff` | Python linting |
| `pre-commit` | Git hook management |

## Setting Up for Local Testing

Local testing deploys IOC roles into Docker/Podman containers running AlmaLinux with EPICS pre-installed.

### Pull the EPICS Container Images

```bash
docker login ghcr.io
docker pull ghcr.io/nsls2/epics-alma8:latest
docker pull ghcr.io/nsls2/epics-alma9:latest
```

### Verify Your Setup

```bash
# Run the test suite (no container needed)
pixi run tests

# Test a specific role against a container
pixi run deployment -t adsimdetector --container -m 8
```

## Installing as an Ansible Collection

If you want to use this collection in your own playbooks:

```bash
ansible-galaxy collection install nsls2.ioc_deploy
```

Or add it to your `requirements.yml`:

```yaml
collections:
- name: nsls2.ioc_deploy
source: https://github.com/NSLS2/nsls2.ioc_deploy
type: git
```

## NSLS-II Network Utilities (Optional)

For deployments to real NSLS-II infrastructure, install the network utility package:

```bash
pixi run install-nsls2network
```

This provides access to beamline network configuration and host lookup utilities.
142 changes: 142 additions & 0 deletions docs/getting-started/usage-patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Usage Patterns

## Intended Workflow

The `nsls2.ioc_deploy` collection is designed to be used in a **three-repository architecture**:

```
┌─────────────────────────┐ ┌─────────────────────────────┐
│ nsls2.ioc_deploy │ │ Playbook Repository │
│ (this collection) │ │ (calls roles with params) │
│ │ │ │
│ • Core deployment logic│◄────│ • Defines what to deploy │
│ • Device roles │ │ • Sets host_config │
│ • Module configs │ │ • Specifies targets │
└─────────────────────────┘ └──────────────┬──────────────┘
┌─────────────────────────────┐
│ IOC Config Repository │
│ (per-beamline configs) │
│ │
│ • IOC instance definitions │
│ • Environment variables │
│ • Substitution files │
└─────────────────────────────┘
```

1. **This collection** (`nsls2.ioc_deploy`) — Contains the reusable Ansible roles and device-specific logic
2. **A playbook repository** — Calls these roles with appropriate parameters for a given deployment
3. **An IOC configuration repository** — Stores per-beamline, per-IOC instance configurations

## IOC Configuration Format

Each IOC instance is defined as a YAML dictionary entry. The key is the IOC name, and the value contains its configuration:

```yaml
my-ioc-01:
type: adaravis # Must match a device role name
environment: # Required environment variables
ENGINEER: "J. Smith"
PREFIX: "XF:28ID1-ES{Cam:1}"
CAMERA_NAME: "Allied Vision-Manta G-040B-50-0503548886"
ENABLE_CACHING: 1
```

The `type` field determines which device role is applied. Each device role defines a schema that validates the configuration structure.

## Deployment Flow

When a deployment is triggered, the following sequence occurs:

1. **Host configuration** is loaded (network interface, user/group, base paths)
2. **System packages** are installed (e.g., `procServ`)
3. **Network setup** file is deployed for EPICS Channel Access
4. For each IOC instance:
1. The IOC `type` field selects the appropriate **device role vars** from `roles/deploy_ioc/vars/<type>.yml`
2. The `install_module` role builds any required EPICS modules (with full dependency resolution)
3. The **core `deploy_ioc` tasks** create directory structure, startup scripts, and environment files
4. The **device-specific tasks** from `roles/device_roles/<type>/tasks/main.yml` run to customize the deployment
5. Optionally, the IOC service is installed, enabled, and/or started

## Variable Precedence

Variables are resolved in the following order (highest priority first):

1. **IOC instance configuration** (from the config repository)
2. **Device role vars** (`roles/deploy_ioc/vars/<type>.yml`)
3. **Device role defaults** (`roles/device_roles/<type>/defaults/main.yml`)
4. **deploy_ioc defaults** (`roles/deploy_ioc/defaults/main.yml`)

## Standard vs. Custom Startup Scripts

Most IOCs use the **standard startup script** format (`deploy_ioc_standard_st_cmd: true`), which produces:

```
<ioc-dir>/
├── st.cmd # Top-level wrapper script
├── iocBoot/
│ ├── st.cmd # Main startup script (loads all .cmd files, runs iocInit)
│ ├── epicsEnv.cmd # Environment variable definitions
│ ├── base.cmd # Device-specific initialization (from device role template)
│ ├── common.cmd # Common module loading (iocStats, autosave, etc.)
│ └── postInit.cmd # Post-initialization commands (dbpf, etc.)
├── db/
│ └── *.substitutions # Database substitution files
└── as/
├── req/ # Autosave request files
└── save/ # Autosave save files
```

For IOCs that need completely custom startup (e.g., Python-based caproto IOCs), set `deploy_ioc_standard_st_cmd: false`.

## Python-Based IOCs

Some IOC types (e.g., `pandabox`) are Python-based and use `pixi` for environment management instead of compiled EPICS binaries. These roles:

- Set `deploy_ioc_standard_st_cmd: false`
- Manage their own startup scripts
- Use `deploy_ioc_pixi_executable_path` for the pixi binary location

## Post-Deployment Actions

The `deploy_ioc_post_deploy_step` variable controls what happens after files are deployed:

| Value | Behavior |
|-------|----------|
| `"None"` | Deploy files only, don't touch services |
| `"Install"` | Install the systemd service file |
| `"Install and Enable"` | Install and enable (auto-start on boot) |
| `"Install and Start"` | Install and start immediately |
| `"Install and Enable and Start"` | Install, enable, and start |
| `"Restart"` | Restart an existing service |

## Substitutions Format

Database substitutions are defined in the IOC configuration and processed into EPICS `.substitutions` files:

```yaml
my-ioc-01:
type: tetramm
environment:
PREFIX: "XF:28ID1-ES{EM:1}"
substitutions:
tetramm:
- filepath: "$(TETRAMM)/db/TetrAMM.template"
pattern: ["P", "R", "PORT"]
instances:
- ["$(PREFIX)", "Ch1:", "TetrAMM"]
- ["$(PREFIX)", "Ch2:", "TetrAMM"]
```

This generates a standard EPICS substitutions file that gets loaded via `dbLoadTemplate` during IOC startup.

## EL Version Matrix

Deployments can target multiple Enterprise Linux versions. By default, roles support EL 8 and EL 9:

```yaml
deploy_ioc_supported_el_versions: [8, 9]
```

Roles that don't support a specific EL version can override this to skip deployment on unsupported targets.
Loading
Loading