From c19bf497b8848c8b170379b61f2427e414a84f86 Mon Sep 17 00:00:00 2001 From: alessio94 Date: Wed, 11 Feb 2026 15:17:46 +0100 Subject: [PATCH 1/5] Add tutorial for configuring Rucio with Docker Compose This tutorial provides a comprehensive guide for setting up a Rucio test environment using Docker Compose, detailing prerequisites, environment management, configuration, and data management scripts for effective data replication and multi-hop transfers. --- docs/operator/setting_up_demo.md | 204 +++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/docs/operator/setting_up_demo.md b/docs/operator/setting_up_demo.md index 3934261940c..dbe978a666e 100644 --- a/docs/operator/setting_up_demo.md +++ b/docs/operator/setting_up_demo.md @@ -423,3 +423,207 @@ $ rucio list-file-replicas test:mynewdataset | test | file4 | 10.486 MB | 65786e49 | XRD3: root://xrd3:1096//rucio/... | +-------+-------+-----------+----------+-----------------------------------+ ``` + +# Configuring S3 Storage and Multi-Hop Transfers in Rucio + + + +This tutorial walks you through setting up a complete Rucio test environment using Docker Compose. The playground includes 17 containers with XRootD servers, MinIO S3 storage, FTS (File Transfer Service), and a full Rucio stack for testing data replication and multi-hop transfers. + +The original scripts and a Jupyter notebook version of the tutorial are available on [rucio-playground](/_resources/rucio-playground). + + +## Prerequisites + +Before starting, ensure you have the following installed: + +- **Docker** (with Docker Compose support) +- **Python 3** (for Rucio clients) +- **Basic understanding** of Rucio concepts (RSEs, replication rules, datasets) + +## Tutorial Scripts Overview + +This tutorial uses a series of numbered scripts that progressively set up and configure your Rucio playground environment. Each script builds on the previous one to create a fully functional test infrastructure. + +### Environment Management Scripts + +#### qt-999-down.sh - Clean Up Environment + +Stops and removes all Docker containers, volumes, and resources from the Rucio playground. Use this to start fresh or clean up after testing. + +```bash +./qt-999-down.sh +``` + +**What it does:** +- Stops all running containers +- Removes containers and networks +- Prunes orphaned containers +- Attempts to clean up unused volumes + +:::warning[Volume Persistence Issue] +The `docker volume prune -f` command only removes **unused** volumes, not the ones that might still be referenced. **PostgreSQL database volumes persist** between runs, keeping old schema objects. + +To completely clean up, you may need to manually remove specific volumes: + +```bash +docker volume rm dev_vol-ruciodb-data1 2>/dev/null +docker volume rm dev_vol-ftsdb-mysql1 2>/dev/null +``` +::: + +#### qt-000-up.sh - Start the Environment + +Launches the complete Docker Compose stack with all storage services and the Rucio infrastructure. + +```bash +./qt-000-up.sh +``` + +**What it does:** +- Generates MinIO SSL certificates +- Starts 17 containers including: + - XRootD servers (XRD1, XRD2, XRD3) + - MinIO instances (MINIO1, MINIO2) + - File Transfer Service (FTS) + - Rucio server and daemons + - PostgreSQL database + + +### Configuration Scripts + +#### qt-001-initialize.sh - Initialize Rucio + +Runs the Rucio initialization script that sets up the basic Rucio infrastructure. + +```bash +./qt-001-initialize.sh +``` + +**What it does:** +- Creates test scopes +- Creates initial datasets +- Registers XRootD RSEs (XRD1, XRD2, XRD3) +- Sets up basic RSE attributes + +#### qt-002-xrd3-http-protocol.sh - Add HTTPS Protocol + +Adds HTTPS protocol support to the XRD3 RSE, enabling it to communicate with S3 backends for multi-hop transfers. + +```bash +./qt-002-xrd3-http-protocol.sh +``` + +**What it does:** +- Configures HTTPS protocol on XRD3 +- Enables S3 compatibility for multi-hop routing +- Sets protocol priorities for WAN and LAN operations + +#### qt-003-minio-buckets.sh - Create MinIO Buckets + +Creates the necessary storage buckets on MinIO instances. + +```bash +./qt-003-minio-buckets.sh +``` + +**What it does:** +- Creates the `rucio` bucket on MinIO instances +- Sets appropriate bucket policies +- Verifies bucket creation + +#### qt-004-minio-rses.sh - Configure MinIO RSEs + +Registers MinIO instances as Rucio Storage Elements with S3 protocol configuration. + +```bash +./qt-004-minio-rses.sh +``` + +**What it does:** +- Registers MINIO1 and MINIO2 as Rucio RSEs +- Configures S3 protocol endpoints +- Sets up storage credentials +- Configures FTS endpoints for each MinIO RSE +- Establishes network distances between MinIO RSEs and XRD3 for multi-hop routing + +:::tip[Understanding RSE Distance] +RSE distance determines routing for data transfers. A distance of 1 means direct transfer is possible. Setting distances between MINIO RSEs and XRD3 enables multi-hop transfers through XRD3. +::: + +#### qt-005-minio-fts-creds.sh - Configure FTS Credentials + +Registers S3 storage credentials in the File Transfer Service (FTS). + +```bash +./qt-005-minio-fts-creds.sh +``` + +**What it does:** +- Registers S3 storage credentials for both MinIO instances in FTS +- Allows FTS to authenticate and perform third-party copy operations +- Configures GFAL2 S3 settings for proper S3 protocol handling + +:::info[What is FTS?] +FTS (File Transfer Service) is responsible for executing actual data transfers between storage endpoints. It handles authentication, retries, checksums, and provides monitoring for transfers. +::: + +### Data Management Scripts + +#### qt-006-simple-upload.sh - Upload Test Data + +Creates and uploads initial test files to MinIO instances. + +```bash +./qt-006-simple-upload.sh +``` + +**What it does:** +- Generates two random test files +- Uploads one file to MINIO1 +- Uploads one file to MINIO2 +- Adds files to test datasets for replication testing + +#### qt-007-replication-rules.sh - Create Replication Rules + +Creates replication rules to trigger data transfers between storage endpoints. + +```bash +./qt-007-replication-rules.sh +``` + +**What it does:** +- Creates a replication rule to copy dataset to XRD1 +- Creates a replication rule to copy dataset to MINIO2 +- Triggers the Rucio rule evaluation workflow + + +#### qt-008-replicate-loop.sh - Execute Replication Cycle + +Runs a single iteration of the Rucio replication cycle to process pending transfers. + +```bash +./qt-008-replicate-loop.sh +``` + +**What it does:** +- Executes `rucio-judge-evaluator --run-once` +- Evaluates pending replication rules +- Submits transfer requests to FTS +- Updates rule states based on transfer results + +:::info[Running Continuously] +In a production environment, these daemons run continuously. This script executes a single cycle for testing purposes. You may need to run it multiple times or check daemon logs to see transfers complete. +::: + + +### Multi-Hop Transfer Flow + +The playground demonstrates multi-hop transfers where data flows from MinIO through XRD3 to other destinations: + +1. User creates replication rule +2. Judge Evaluator processes rule +3. Conveyor submits transfer to FTS +4. FTS orchestrates multi-hop transfer: + - MINIO1/2 → XRD3 (S3 to HTTPS) + - XRD3 → XRD1/2 (XRootD protocol) From aea3543357f9a68cab76c22495f135d5267c6527 Mon Sep 17 00:00:00 2001 From: alessio94 Date: Wed, 11 Feb 2026 15:27:07 +0100 Subject: [PATCH 2/5] Add script to start Rucio playground environment --- docs/operator/_resources/rucio-playground/qt-000-up.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/operator/_resources/rucio-playground/qt-000-up.txt diff --git a/docs/operator/_resources/rucio-playground/qt-000-up.txt b/docs/operator/_resources/rucio-playground/qt-000-up.txt new file mode 100644 index 00000000000..9523b7e1e6b --- /dev/null +++ b/docs/operator/_resources/rucio-playground/qt-000-up.txt @@ -0,0 +1,7 @@ +#!/bin/bash + +cd `dirname $0` + +etc/certs/generate_minio12.sh + +docker compose --file etc/docker/dev/docker-compose-qt.yml --profile storage up -d From 93afe4630b6bd65a8d9fc677015133e4f56d88ce Mon Sep 17 00:00:00 2001 From: alessio94 Date: Wed, 11 Feb 2026 15:37:25 +0100 Subject: [PATCH 3/5] More files for rucio playground --- .../rucio-playground/qt-001-initialize.txt | 11 ++++ .../qt-002-xrd3-http-protocol.txt | 9 +++ .../rucio-playground/qt-003-minio-buckets.txt | 17 ++++++ .../rucio-playground/qt-004-minio-rses.txt | 57 ++++++++++++++++++ .../qt-005-minio-fts-creds.txt | 60 +++++++++++++++++++ .../rucio-playground/qt-006-simple-upload.txt | 16 +++++ .../qt-007-replication-rules.txt | 6 ++ .../rucio-playground/qt-008-replicte-loop.txt | 15 +++++ .../rucio-playground/qt-999-down.txt | 7 +++ .../_resources/rucio-playground/qt-enter.txt | 13 ++++ .../_resources/rucio-playground/qt-replay.txt | 4 ++ 11 files changed, 215 insertions(+) create mode 100644 docs/operator/_resources/rucio-playground/qt-001-initialize.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-002-xrd3-http-protocol.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-003-minio-buckets.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-004-minio-rses.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-005-minio-fts-creds.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-006-simple-upload.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-007-replication-rules.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-008-replicte-loop.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-999-down.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-enter.txt create mode 100644 docs/operator/_resources/rucio-playground/qt-replay.txt diff --git a/docs/operator/_resources/rucio-playground/qt-001-initialize.txt b/docs/operator/_resources/rucio-playground/qt-001-initialize.txt new file mode 100644 index 00000000000..e9ee4d67b85 --- /dev/null +++ b/docs/operator/_resources/rucio-playground/qt-001-initialize.txt @@ -0,0 +1,11 @@ +#!/bin/bash + +# rucio list-file-replicas test:dataset1 +# rucio list-file-replicas test:dataset2 +# rucio list-file-replicas test:dataset3 +# rucio list-file-replicas test:container + +# Step zero, get a compliant proxy. The key must NOT be group/other readable +# (KEY=$(mktemp); cat /opt/rucio/etc/userkey.pem > "$KEY"; voms-proxy-init -valid 9999:00 -cert /opt/rucio/etc/usercert.pem -key "$KEY"; rm -f "$KEY") + +docker exec -i dev-rucio-1 /bin/bash tools/run_tests.sh -ir diff --git a/docs/operator/_resources/rucio-playground/qt-002-xrd3-http-protocol.txt b/docs/operator/_resources/rucio-playground/qt-002-xrd3-http-protocol.txt new file mode 100644 index 00000000000..60054a91094 --- /dev/null +++ b/docs/operator/_resources/rucio-playground/qt-002-xrd3-http-protocol.txt @@ -0,0 +1,9 @@ +#!/bin/bash + +# XRD3 is enabled for multihop transfers +# so add HTTP protocol to be able to talk to S3 + +docker exec -i dev-rucio-1 /bin/bash </opt/rucio/etc/rse-accounts.cfg </etc/gfal2.d/s3.conf < "$KEY"; voms-proxy-init -valid 9999:00 -cert /opt/rucio/etc/usercert.pem -key "$KEY"; rm -f "$KEY") + + +docker exec -it dev-rucio-1 /bin/bash diff --git a/docs/operator/_resources/rucio-playground/qt-replay.txt b/docs/operator/_resources/rucio-playground/qt-replay.txt new file mode 100644 index 00000000000..141f7da842a --- /dev/null +++ b/docs/operator/_resources/rucio-playground/qt-replay.txt @@ -0,0 +1,4 @@ +#!/bin/bash + +cd `dirname $0` +for i in {0..8} ; do ./qt-00${i}-* ; done From 6440726089eada345ee587f73a1673e18e28205f Mon Sep 17 00:00:00 2001 From: alessio94 Date: Wed, 11 Feb 2026 15:39:04 +0100 Subject: [PATCH 4/5] Added Jupyter notebook file --- .../rucio-playground-tutorial.ipynb | 410 ++++++++++++++++++ 1 file changed, 410 insertions(+) create mode 100644 docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb diff --git a/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb b/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb new file mode 100644 index 00000000000..9a2859a4937 --- /dev/null +++ b/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb @@ -0,0 +1,410 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": "# Rucio Playground Tutorial\n\nThis notebook walks you through setting up a complete **Rucio** test environment using Docker Compose. The playground includes 17 containers with XRootD servers, MinIO S3 storage, FTS (File Transfer Service), and a full Rucio stack for testing data replication and multi-hop transfers.\n\nRucio is a scientific data management framework used to organize, manage, and access large volumes of scientific data across distributed storage systems. It was originally developed for the ATLAS experiment at CERN and is now used across many scientific communities.\n\n## What you will learn\n\n1. **Environment setup** — generate certificates, start 17 Docker containers\n2. **Storage registration** — configure XRootD and MinIO S3 as Rucio Storage Elements (RSEs)\n3. **Credential management** — wire up S3 credentials for Rucio, FTS, and GFAL2\n4. **Data upload** — create files, upload to RSEs, organize into datasets\n5. **Replication policies** — declare where data should live using Rucio rules\n6. **Automated transfers** — run the judge/conveyor pipeline to execute multi-hop transfers\n\n## Prerequisites\n\n- **Docker** (with Docker Compose support) installed locally\n- The **Rucio dev environment** cloned (provides `etc/docker/dev/docker-compose-qt.yml`)\n- This notebook should be run **from the root of the repository** so that relative paths resolve correctly\n\n> **Note:** All Rucio CLI commands run inside Docker containers — no local Rucio or Python installation is required.\n\n## References\n\n- [Rucio Documentation](https://rucio.cern.ch/documentation)\n- [S3 RSE Configuration](https://rucio.github.io/documentation/operator/s3_rse_config/)\n- [FTS3 S3 Support](https://fts3-docs.web.cern.ch/fts3-docs/docs/s3_support.html)\n- [EGI Data Transfer Tutorial](https://docs.egi.eu/users/tutorials/adhoc/data-transfer-object-storage/)\n- [Rucio K8s Tutorial](https://github.com/rucio/k8s-tutorial)\n- [Rucio Docker Dev Environment](https://github.com/rucio/rucio/tree/master/etc/docker/dev)" + }, + { + "cell_type": "markdown", + "source": "---\n## Environment Overview\n\nThe Docker Compose stack spins up 17 containers. The key ones you will interact with:\n\n| Container | Service | Role |\n|-----------|---------|------|\n| `dev-rucio-1` | Rucio server | CLI commands, daemons, uploads |\n| `dev-minio-1` | MinIO (port 9001) | S3 storage instance 1 |\n| `dev-minio-2` | MinIO (port 9002) | S3 storage instance 2 |\n| `dev-fts-1` | FTS3 | File transfer service |\n| XRD1, XRD2, XRD3 | XRootD servers | Grid storage (XRD3 is the multihop intermediary) |\n\n**Credentials** used throughout (demo only): `admin` / `password`", + "metadata": {} + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Step 0 — Start the Environment\n", + "\n", + "Generate TLS certificates for the MinIO instances and start the full Docker Compose stack (Rucio server, MinIO storage nodes, FTS3 transfer service, XRootD servers)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "etc/certs/generate_minio12.sh" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker compose --file etc/docker/dev/docker-compose-qt.yml --profile storage up -d" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Step 1 — Initialize Rucio\n", + "\n", + "Run Rucio's built-in initialization and test suite inside the main container. This bootstraps the database schema, creates the default account (`root`), and registers the initial set of RSEs (Replica Storage Elements) and scopes.\n", + "\n", + "> **Note:** This may take a few minutes as it runs the full init + test harness (`tools/run_tests.sh -ir`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker exec -i dev-rucio-1 /bin/bash tools/run_tests.sh -ir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Step 2 — Add HTTPS Protocol to XRD3 RSE\n", + "\n", + "XRD3 is an XRootD storage element that is enabled for **multihop transfers**. We add an HTTPS protocol endpoint so it can act as an intermediary when transferring data to/from S3 storage (which speaks HTTPS, not XRootD native).\n", + "\n", + "The `gfal.Default` implementation is used, with both LAN and WAN domains configured for read, write, delete, and third-party-copy operations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker exec -i dev-rucio-1 /bin/bash < **Understanding RSE Distance:** RSE distance determines routing for data transfers. A distance of 1 means direct transfer is possible. Setting distances between MINIO RSEs and XRD3 enables multi-hop transfers through XRD3.\n\nFinally, the RSE S3 credentials (access key / secret key) are written to `/opt/rucio/etc/rse-accounts.cfg` keyed by RSE ID.\n\n> **Ref:** [S3 RSE Configuration Guide](https://rucio.github.io/documentation/operator/s3_rse_config/)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "# Register RSEs, set attributes, define distances\n", + "docker exec -i dev-rucio-1 /bin/bash </opt/rucio/etc/rse-accounts.cfg < **What is FTS?** FTS (File Transfer Service) is the middleware responsible for executing actual data transfers between storage endpoints. It handles authentication, retries, checksums, and provides monitoring. Rucio delegates the physical movement of data to FTS.\n\nWe also write a `gfal2` S3 configuration file so the transfer agent knows how to authenticate.\n\n> **Ref:** [FTS3 S3 Support](https://fts3-docs.web.cern.ch/fts3-docs/docs/s3_support.html) · [EGI Data Transfer Tutorial](https://docs.egi.eu/users/tutorials/adhoc/data-transfer-object-storage/)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker exec -i dev-fts-1 /bin/bash <<'END'\n", + "# Register cloud storage endpoints in FTS3\n", + "curl \\\n", + " --cert /etc/grid-security/hostcert.pem \\\n", + " --key /etc/grid-security/hostkey.pem \\\n", + " --capath /etc/grid-security/certificates \\\n", + " https://fts:8446/config/cloud_storage \\\n", + " -H \"Content-Type: application/json\" \\\n", + " -X POST \\\n", + " -d '{\"storage_name\":\"S3:minio1\"}'\n", + "\n", + "curl \\\n", + " --cert /etc/grid-security/hostcert.pem \\\n", + " --key /etc/grid-security/hostkey.pem \\\n", + " --capath /etc/grid-security/certificates \\\n", + " https://fts:8446/config/cloud_storage \\\n", + " -H \"Content-Type: application/json\" \\\n", + " -X POST \\\n", + " -d '{\"user_dn\":\"/CN=Rucio User\",\"storage_name\":\"S3:minio1\",\"access_token\":\"admin\",\"access_token_secret\":\"password\"}'\n", + "\n", + "\n", + "curl \\\n", + " --cert /etc/grid-security/hostcert.pem \\\n", + " --key /etc/grid-security/hostkey.pem \\\n", + " --capath /etc/grid-security/certificates \\\n", + " https://fts:8446/config/cloud_storage \\\n", + " -H \"Content-Type: application/json\" \\\n", + " -X POST \\\n", + " -d '{\"storage_name\":\"S3:minio2\"}'\n", + "\n", + "curl \\\n", + " --cert /etc/grid-security/hostcert.pem \\\n", + " --key /etc/grid-security/hostkey.pem \\\n", + " --capath /etc/grid-security/certificates \\\n", + " https://fts:8446/config/cloud_storage \\\n", + " -H \"Content-Type: application/json\" \\\n", + " -X POST \\\n", + " -d '{\"user_dn\":\"/CN=Rucio User\",\"storage_name\":\"S3:minio2\",\"access_token\":\"admin\",\"access_token_secret\":\"password\"}'\n", + "\n", + "# Write gfal2 S3 configuration\n", + "cat >/etc/gfal2.d/s3.conf < **Ref:** [K8s Tutorial — Create transfer testing data](https://github.com/rucio/k8s-tutorial#create-initial-transfer-testing-data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker exec -i dev-rucio-1 /bin/bash < **Tip:** You may need to **run this cell multiple times**. Transfers take time and the poller/finisher need to catch up with FTS3. Re-run until you see all rule states change to `OK`." + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker exec -i dev-rucio-1 /bin/bash < **Warning:** This destroys all state. You will need to re-run from Step 0 to start again.\n>\n> **Volume Persistence:** `docker volume prune -f` only removes *unused* volumes. PostgreSQL database volumes may persist between runs. To fully clean up:\n> ```\n> docker volume rm dev_vol-ruciodb-data1 2>/dev/null\n> docker volume rm dev_vol-ftsdb-mysql1 2>/dev/null\n> ```", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "docker compose --file etc/docker/dev/docker-compose-qt.yml --profile storage down\n", + "docker container prune -f\n", + "docker volume prune -f" + ] + }, + { + "cell_type": "markdown", + "source": "---\n## Appendix: Multi-Hop Transfer Flow\n\nThe playground demonstrates multi-hop transfers where data flows from MinIO S3 through XRD3 to XRootD destinations:\n\n```\nUser creates replication rule\n │\n ▼\nJudge Evaluator processes rule\n │\n ▼\nConveyor submits transfer to FTS\n │\n ▼\nFTS orchestrates multi-hop transfer:\n MINIO1/2 ──(S3→HTTPS)──▶ XRD3 ──(XRootD)──▶ XRD1/2\n```\n\nXRD3 acts as the **multihop intermediary** because it speaks both HTTPS (needed for S3) and native XRootD protocol. Without the HTTPS protocol added in Step 2, Rucio would have no path between the S3 and XRootD worlds.", + "metadata": {} + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.10.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file From 30fce702ed08a99f02deecb3a8bb9b72518b47e3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:56:34 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../_resources/rucio-playground/rucio-playground-tutorial.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb b/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb index 9a2859a4937..ba354509b63 100644 --- a/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb +++ b/docs/operator/_resources/rucio-playground/rucio-playground-tutorial.ipynb @@ -407,4 +407,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +}