### Install envtest Binaries Source: https://github.com/cozystack/blockstor/blob/main/tests/integration/README.md Installs the necessary `envtest` binaries for running integration tests. This is a one-time setup step. ```bash go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest export KUBEBUILDER_ASSETS="$(setup-envtest use --print path 1.34.x)" ``` -------------------------------- ### Setup and Cluster Shape Example Source: https://github.com/cozystack/blockstor/blob/main/tests/e2e/cli-matrix/README.md This snippet illustrates the initial steps within a test cell: sourcing lib.sh, setting up the linstor CLI, and defining a cluster shape using kubectl or linstor commands. ```shell #!/bin/bash # Source the common library . lib.sh # Setup linstor CLI and build LCTL array linstor_cli_setup # Lay down a cluster shape (e.g., 2 nodes, 2 replicas) # Example: kubectl apply -f cluster-shape.yaml # Or chaining linstor commands: # linstor rd c --name node-1 --role Controller # linstor vd c --name vol-1 --size 10GiB --pool-name pool-1 # linstor r c --name vol-1 --node node-1 --pool-name pool-1 --role Controller ``` -------------------------------- ### Kernel Probe Example Source: https://github.com/cozystack/blockstor/blob/main/tests/e2e/cli-matrix/README.md This example demonstrates how to check the kernel-side state of a DRBD resource on a specific node using drbdsetup. ```shell # Check kernel-side DRBD status on_node node-1 drbdsetup status my-resource ``` -------------------------------- ### Install Linstor CLI Source: https://github.com/cozystack/blockstor/blob/main/tests/integration/README.md Installs the upstream `linstor` CLI and its Python dependencies, required for interacting with the storage system during integration tests. This is a one-time setup step. ```bash apt-get install -y linstor-client python3-linstor # Debian/Ubuntu ``` -------------------------------- ### Resource Status Check Example Source: https://github.com/cozystack/blockstor/blob/main/tests/e2e/cli-matrix/README.md This example shows how to retrieve the observer-stamped status of a resource on a specific node using kubectl. ```shell # Get resource status kubectl get resource my-resource.node-1 -o json ``` -------------------------------- ### Setup and Run Controller Integration Tests Source: https://github.com/cozystack/blockstor/blob/main/tests/scenarios/README.md Set up the environment for controller integration tests and then run them. This involves setting up envtest. ```bash make setup-envtest && go test ./internal/controller/... ``` -------------------------------- ### LINSTOR Resource Configuration Example Source: https://github.com/cozystack/blockstor/blob/main/docs/design-res-rendering-linstor-parity.md This is an example of a resource configuration file generated by LINSTOR. It includes settings for options, network, volumes, and connections. ```plaintext resource "pvc-..." { options { on-no-data-accessible suspend-io; on-no-quorum suspend-io; on-suspended-primary-outdated force-secondary; quorum majority; } net { cram-hmac-alg sha1; shared-secret "lFvd6mblDkeOmjc2YxEG"; connect-int 15; ping-int 15; ping-timeout 20; protocol C; rr-conflict retry-connect; timeout 100; verify-alg "crc32c"; } on "node1" { volume 0 { disk /dev/zvol/data/pvc-..._00000; disk { discard-zeroes-if-aligned yes; rs-discard-granularity 16384; } meta-disk internal; device minor 1040; } node-id 0; } on "node0" { volume 0 { disk none; # diskless replica disk { discard-zeroes-if-aligned yes; rs-discard-granularity 16384; } meta-disk internal; device minor 1040; } node-id 2; } on "node2" { volume 0 { disk /dev/drbd/this/is/not/used; # tiebreaker placeholder ... } node-id 1; } connection { net { connect-int 15; ping-int 15; ... } host "node1" address ipv4 10.4.100.12:7035; host "node0" address ipv4 10.4.100.11:7035; } connection { net { ... } host "node1" address ipv4 10.4.100.12:7035; host "node2" address ipv4 10.4.100.13:7035; } } ``` -------------------------------- ### ZFS Create Command for Thin Provisioning Source: https://github.com/cozystack/blockstor/blob/main/docs/zfs-thick-validation-2026-05-14.md Example of the ZFS `create` command used for thin provisioning, which includes the `-s` (sparse) flag. ```bash zfs create -V N -s ``` -------------------------------- ### ZFS Create Command for Thick Provisioning Source: https://github.com/cozystack/blockstor/blob/main/docs/zfs-thick-validation-2026-05-14.md Example of the ZFS `create` command used for thick provisioning, which does not use the `-s` (sparse) flag. ```bash zfs create -V N ``` -------------------------------- ### Example of Test-Only LUKS Layer CLI Cells Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This refers to command-line interface cells used specifically for testing the LUKS (Linux Unified Key Setup) layer. These are not intended for production use. ```bash LUKS layer operator-CLI cells ``` -------------------------------- ### Example CLI Command for Listing Resources Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This command lists resources. It was used in an audit to check the post-state of resources, but did not fully capture the behavior of resource creation with specific flags. ```bash linstor r l ``` -------------------------------- ### Example CLI Command for Creating a Resource Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This command creates a resource. It was identified that omitting the `--diskless` flag could lead to incorrect resource states due to skipped pool resolution. ```bash linstor r c ``` -------------------------------- ### DRBD Net Block Configuration for Verify Algorithm Source: https://github.com/cozystack/blockstor/blob/main/docs/design-res-rendering-linstor-parity.md Example of how the verify-alg option is rendered within a DRBD net block for integrity checking. ```text net { ... verify-alg "crc32c"; } ``` -------------------------------- ### Example CLI Command for Volume Creation Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This command creates volumes for a resource. A bug occurred when late volume creation after the resource reached 'UpToDate' state resulted in new volumes being diskless. ```bash vd c ``` -------------------------------- ### Deploy and Run End-to-End Tests Source: https://github.com/cozystack/blockstor/blob/main/tests/scenarios/README.md Deploy the Blockstor stack and run end-to-end tests for a specific scenario. This involves multiple make targets for setup. ```bash # E2E (full stand): make up NAME=e2e7 && make piraeus NAME=e2e7 && make blockstor NAME=e2e7 && make pools NAME=e2e7 make e2e NAME=e2e7 SCENARIO= ``` -------------------------------- ### Example CLI Command for Diskless Resource Update Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This command updates a resource to be diskless. A bug caused it to return success even when the DRBD kernel did not detach the disk. ```bash r td --diskless ``` -------------------------------- ### Example CLI Command for Multi-Place Autoplace Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This command attempts to autoplace multiple diskful volumes with a storage-only constraint. A bug resulted in the creation of unrelated volumes and a TieBreaker, indicating a meaningless placement. ```bash r c --auto-place=2 -l STORAGE ``` -------------------------------- ### Blockstor Development Stand Quick Start Source: https://github.com/cozystack/blockstor/blob/main/AGENTS.md Commands to bring up, configure, and manage a Blockstor development cluster using the 'make up' command. Includes options for real-disk pools and multiple parallel clusters. ```sh # Single cluster (default name "blockstor") make up make piraeus make blockstor # install the controller + satellite DaemonSet make smoke-blockstor make down # Real-disk pools (ZFS + LVM-thin) on extra disks make pools STORPOOL=zfs-thin make smoke-blockstor # Multiple parallel clusters — each gets its own 10..0.0/24 CIDR make up NAME=alice make up NAME=bob ``` -------------------------------- ### Example CLI Command for Autoplace with Multiple Pools Source: https://github.com/cozystack/blockstor/blob/main/docs/cli-parity-audit-2026-05-19-refresh.md This command attempts to autoplace a resource across multiple storage pools. A bug was found where it only selected one pool due to pre-filtering of the candidate set. ```bash linstor autoplace --storage-pool=A,B ``` -------------------------------- ### Create, List, and Inspect Snapshots Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Demonstrates creating a snapshot, listing snapshots for a specific resource, and listing all cluster-wide snapshots. ```bash linstor snapshot create test snap1 linstor snapshot list -r test linstor snapshot list # cluster-wide ``` -------------------------------- ### Simulate Disk I/O Failures with dmsetup Source: https://github.com/cozystack/blockstor/blob/main/tests/advanced-config-scenarios.md This example shows how to use dmsetup to create a failing device mapper target, simulating per-sector I/O errors on a block device. This is useful for testing fault tolerance and event handling in storage systems. ```bash # Wrap the backing LV with a failing dm device: size=$(blockdev --getsz /dev/blockstor-lvm/some-lv) # Build a table with a corrupt 1MB region at offset 100MB: cat < /tmp/fail.table 0 204800 linear /dev/blockstor-lvm/some-lv 0 204800 2048 error 206848 $((size-206848)) linear /dev/blockstor-lvm/some-lv 206848 EOF dmsetup create faildev < /tmp/fail.table # Reroute the satellite to use the faildev (would require pointing # blockstor's StoragePool at /dev/mapper/faildev instead of the # raw LV — design TBD) # Force a read of the bad region: dd if=/dev/drbd bs=4096 skip=25000 count=1 of=/dev/null # Expected: I/O error, DRBD events2 emits `change device disk:Failed`, # observer auto-detaches per the on-io-error=detach policy linstor r l -r # Expected: this node's replica shows State=Failed or Diskless # (after auto-detach) ``` -------------------------------- ### Tier 2 Integration Test CI Requirements Source: https://github.com/cozystack/blockstor/blob/main/docs/test-strategy.md Specifies the necessary setup for Continuous Integration to run Tier 2 integration tests. This includes caching dependencies and installing required packages. ```bash #setup-envtest action caches `kube-apiserver` + `etcd` #apt install -y linstor-client python3-linstor in the job # Build constraint `//go:build integration` so `go test ./...` does not pull integration tests by default ``` -------------------------------- ### Get Peer Node ID using Kubernetes-native fields Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Future Kubernetes-native equivalent to get the peer's DRBD node ID. This method reads a denormalized field on the local Resource CRD, simplifying access. ```bash # Same answer, but as a denormalised field on the local Resource, # so tests don't need to know the peer's CRD name: kubectl get resource "${rd}.${node}" -o json \ | jq -r --arg p "${peer}" '.status.connections[]? | select(.peerNodeName==$p) | .peerDrbdNodeId' ``` -------------------------------- ### Get Node Source: https://github.com/cozystack/blockstor/blob/main/docs/csi-api-surface.md Retrieves details of a specific node. ```APIDOC ## GET /v1/nodes/{node} ### Description Retrieves details of a specific node. ### Method GET ### Endpoint /v1/nodes/{node} ### Parameters #### Path Parameters - **node** (string) - Required - The identifier of the node. ``` -------------------------------- ### Mid-level Provisioning with Auto-Placement Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Use `linstor create --auto-place` after manually creating resource and volume definitions to perform only the placement step, allowing the autoplacer to land replicas according to specified counts. This splits the creation process. ```bash linstor resource-definition create test-auto --resource-group default linstor volume-definition create test-auto 10G linstor resource list -r test-auto # expect empty linstor create test-auto --auto-place 2 linstor resource list -r test-auto # expect 3 rows ``` -------------------------------- ### Get Peer Disk State using Kubernetes-native fields Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Future Kubernetes-native equivalent to get the peer's disk state. This method reads a denormalized field on the local Resource CRD, providing the local kernel's view of the peer's disk state. ```bash kubectl get resource "${rd}.${node}" -o json \ | jq -r --arg p "${peer}" --argjson v "${vol}" \ '.status.connections[]? \ | select(.peerNodeName==$p) \ | .peerVolumes[]? | select(.volumeNumber==$v) | .peerDiskState' ``` -------------------------------- ### Get Resource Definition Source: https://github.com/cozystack/blockstor/blob/main/docs/csi-api-surface.md Retrieves details of a specific resource definition. ```APIDOC ## GET /v1/resource-definitions/{rd} ### Description Retrieves details of a specific resource definition. ### Method GET ### Endpoint /v1/resource-definitions/{rd} ### Parameters #### Path Parameters - **rd** (string) - Required - The identifier of the resource definition. ``` -------------------------------- ### Configure Resource Group Placement Constraints Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-ug9-feature-scenarios.md Example of configuring resource group placement with constraints on replica location. Use `--replicas-on-same` to ensure replicas are on the same site, or `--replicas-on-different` for disaster recovery scenarios. ```bash --replicas-on-same site --place-count 2 ``` ```bash --x-replicas-on-different site 2 --place-count 3 ``` -------------------------------- ### Get Clone Status Source: https://github.com/cozystack/blockstor/blob/main/docs/csi-api-surface.md Retrieves the status of a resource definition cloning operation. ```APIDOC ## GET /v1/resource-definitions/{rd}/clone/{target} ### Description Retrieves the status of a resource definition cloning operation. ### Method GET ### Endpoint /v1/resource-definitions/{rd}/clone/{target} ### Parameters #### Path Parameters - **rd** (string) - Required - The identifier of the resource definition. - **target** (string) - Required - The identifier of the target for the clone operation. ``` -------------------------------- ### Manual Provisioning with Explicit Storage Pool Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Use `linstor resource create -s ` for low-level provisioning, allowing explicit node and storage pool selection. This is useful for debugging autoplacer behavior or specific placement needs. ```bash linstor resource-definition create test-manual --resource-group default linstor volume-definition create test-manual 10G linstor resource create test-manual -s lvm-thin linstor resource create test-manual -s lvm-thin linstor resource list -r test-manual ``` -------------------------------- ### Get Resource Definition Sync Status Source: https://github.com/cozystack/blockstor/blob/main/docs/csi-api-surface.md Retrieves the synchronization status of a resource definition. ```APIDOC ## GET /v1/resource-definitions/{rd}/sync-status ### Description Retrieves the synchronization status of a resource definition. ### Method GET ### Endpoint /v1/resource-definitions/{rd}/sync-status ### Parameters #### Path Parameters - **rd** (string) - Required - The identifier of the resource definition. ``` -------------------------------- ### Create Storage Pool Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Demonstrates adding a new storage pool on a specific node using LVM_THIN driver. ```bash linstor sp create new-pool LVM_THIN \ --pool-name=blockstor-lvm/thin linstor sp list ``` -------------------------------- ### Get Node Storage Pool Source: https://github.com/cozystack/blockstor/blob/main/docs/csi-api-surface.md Retrieves details of a specific storage pool on a node. ```APIDOC ## GET /v1/nodes/{node}/storage-pools/{pool} ### Description Retrieves details of a specific storage pool on a node. ### Method GET ### Endpoint /v1/nodes/{node}/storage-pools/{pool} ### Parameters #### Path Parameters - **node** (string) - Required - The identifier of the node. - **pool** (string) - Required - The identifier of the storage pool. ``` -------------------------------- ### Configure Topology-Aware Replica Placement Source: https://github.com/cozystack/blockstor/blob/main/tests/advanced-config-scenarios.md Sets up Kubernetes node labels for zones and creates a StorageClass with the 'replicasOnDifferent' parameter to ensure replicas are spread across different failure domains. Verifies the placement of replicas. ```bash kubectl label node worker-1 worker-2 topology.kubernetes.io/zone=a kubectl label node worker-3 worker-4 topology.kubernetes.io/zone=b kubectl label node worker-5 worker-6 topology.kubernetes.io/zone=c ``` ```bash # Verify the operator picked up labels into Aux/topology: linstor node list-properties worker-1 # Expected: Aux/topology/topology.kubernetes.io/zone=a # StorageClass that spreads: cat < ``` -------------------------------- ### Get Node Network Interface Source: https://github.com/cozystack/blockstor/blob/main/docs/csi-api-surface.md Retrieves details of a specific network interface on a node. ```APIDOC ## GET /v1/nodes/{node}/net-interfaces/{nif} ### Description Retrieves details of a specific network interface on a node. ### Method GET ### Endpoint /v1/nodes/{node}/net-interfaces/{nif} ### Parameters #### Path Parameters - **node** (string) - Required - The identifier of the node. - **nif** (string) - Required - The identifier of the network interface. ``` -------------------------------- ### Get LINSTOR-NODE Pod Source: https://github.com/cozystack/blockstor/blob/main/tests/observability-cheat-sheet-scenarios.md Retrieves pods labeled with app=linstor-node. Used for upstream LINSTOR node identification. ```bash kubectl get pod -l app=linstor-node -o wide ``` -------------------------------- ### DRBD Resource File Header Comment Source: https://github.com/cozystack/blockstor/blob/main/docs/design-res-rendering-linstor-parity.md Example of a header comment block that should be rendered at the top of every .res file. ```text Header comment block at the top of every .res: ``` -------------------------------- ### Mount and Check Resource Usage Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Demonstrates mounting a DRBD device and checking its usage status via `linstor resource list`. This is used to verify auto-promotion to Primary. ```bash # On worker-1: mkfs.ext4 /dev/drbd && mount /dev/drbd /mnt/test # From admin shell: linstor resource list -r test ``` -------------------------------- ### Get Blockstor Satellite Pod Source: https://github.com/cozystack/blockstor/blob/main/tests/observability-cheat-sheet-scenarios.md Retrieves pods labeled with app=blockstor-satellite in the blockstor-system namespace. Used for blockstor satellite identification. ```bash kubectl get pod -n blockstor-system -l app=blockstor-satellite -o wide ``` -------------------------------- ### Test Harness Skeleton for E2E Scenarios Source: https://github.com/cozystack/blockstor/blob/main/tests/scenarios/01-api-contract.md This script sets up the environment for end-to-end tests, including port-forwarding the Blockstor controller and defining the LINSTOR client command. It ensures the test is independently re-runnable and includes cleanup mechanisms. ```bash # tests/e2e/linstor-cli-.sh set -euo pipefail WORK_DIR=${1:?work_dir required} export KUBECONFIG "$WORK_DIR/kubeconfig" source "$(dirname "$0")/lib.sh" kubectl port-forward -n blockstor-system svc/blockstor-controller \ 3370:3370 >/tmp/pf-blockstor.log 2>&1 & PF_PID=$! trap 'kill $PF_PID 2>/dev/null || true; cleanup' EXIT sleep 2 LINSTOR="linstor --controllers=127.0.0.1:3370" # ... per-scenario commands + asserts ... ``` -------------------------------- ### Get the role of a resource Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Retrieves the current role of a Blockstor resource on a specific node. Returns an empty string if the field is not set. ```bash # $1=rd, $2=node — Status.Role landed in a077afcf2 (Phase 11.5.b P0) status_role() { kubectl get resource "${1}.${2}" -o jsonpath='{.status.role}' 2>/dev/null } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/cozystack/blockstor/blob/main/tests/scenarios/README.md Execute unit tests for the pkg and internal directories. These tests typically mock dependencies. ```bash # Unit tests: go test ./pkg/... ./internal/... ``` -------------------------------- ### List Resources for a Resource Definition Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Shows per-node replicas for a given resource definition, including port, usage, connections, state, and creation timestamp. Verifies the correct number of replicas and their states (UpToDate, TieBreaker). ```bash linstor resource list -r test1 ``` -------------------------------- ### DRBD Option Override Regression Example Source: https://github.com/cozystack/blockstor/blob/main/docs/architecture.md Illustrates a potential regression where `if *src.X { out.X = src.X }` could silently drop explicit-false overrides. ```go A regression that did `if *src.X { out.X = src.X }` would silently drop explicit-`false` overrides, e.g. an RD that intentionally sets `AllowTwoPrimaries=false` would inherit a parent RG's `true`. ``` -------------------------------- ### Clone Resource Definition Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Illustrates cloning an existing resource definition to create a derived one with its own volumes and replicas. ```bash linstor rd clone test test-clone linstor rd l ``` -------------------------------- ### Create Resource and Verify PrefNic Usage Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-ug9-feature-scenarios.md This sequence of commands creates a new LINSTOR resource and verifies that the resource's configuration file (.res) correctly points to the preferred network interface (PrefNic) for communication. ```bash linstor rd c prefnic-test linstor vd c prefnic-test 1G linstor r c worker-{1,2,3} prefnic-test --storage-pool zfs-thin sleep 5 ssh worker-1 'cat /var/lib/linstor.d/prefnic-test.res | grep address' ``` -------------------------------- ### Get DRBD port for a resource Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Retrieves the DRBD port number for a given resource and node. Returns an empty string if the field is not set. ```bash # $1=rd, $2=node — int / empty if not yet allocated status_drbd_port() { kubectl get resource "${1}.${2}" -o jsonpath='{.status.drbdPort}' 2>/dev/null } ``` -------------------------------- ### Create and Spawn DRBD Resource with Performance Tuning Source: https://github.com/cozystack/blockstor/blob/main/tests/advanced-config-scenarios.md Commands to create a new DRBD resource (RD) and associated volume (VD) after tuning controller properties. This step is crucial to test if the new resource honors the performance settings. ```bash # Spawn a new RD, check .res honours the props: linstor rd c perf-test linstor vd c perf-test 1G linstor rd ap perf-test --place-count 2 ``` -------------------------------- ### Get DRBD Replication State (Bypass) Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Checks if the DRBD replication state is 'Established' on a specific node. Useful for verifying successful replication. ```bash on_node "$node" drbdsetup status "$RD" --verbose 2>/dev/null \ | grep -E 'replication:Established' | head -1 ``` -------------------------------- ### Cross-Node Snapshot Shipping (LVM-THIN) Source: https://github.com/cozystack/blockstor/blob/main/tests/scenarios/06-storage-backends.md This command sequence demonstrates shipping an LVM-THIN snapshot between nodes using the `thin-send-recv` utility. ```bash thin-send-recv ``` -------------------------------- ### Test Harness Skeleton Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Provides a basic bash script structure for end-to-end Linstor CLI tests, including setup, port-forwarding, and cleanup. ```bash #!/usr/bin/env bash # tests/e2e/linstor-cli-.sh set -euo pipefail WORK_DIR=${1:?work_dir required} export KUBECONFIG "$WORK_DIR/kubeconfig" source "$(dirname "$0")/lib.sh" # Port-forward blockstor-controller in the background, kill on exit. kubectl port-forward -n blockstor-system svc/blockstor-controller \ 3370:3370 >/tmp/pf-blockstor.log 2>&1 & PF_PID=$! trap 'kill $PF_PID 2>/dev/null || true; cleanup' EXIT sleep 2 # linstor CLI talks to the forwarded port via default config. LINSTOR="linstor --controllers=127.0.0.1:3370" # … per-scenario commands + asserts … ``` -------------------------------- ### Get DRBD node ID for a resource Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Retrieves the DRBD node ID for a given resource and node. Returns an empty string if the field is not set. ```bash status_drbd_node_id() { kubectl get resource "${1}.${2}" -o jsonpath='{.status.drbdNodeId}' 2>/dev/null } ``` -------------------------------- ### Run All Replay Workflows Source: https://github.com/cozystack/blockstor/blob/main/CLAUDE.md Executes all replay workflows defined in the operator-harness. Requires setting the BS_URL environment variable and will exit on the first failure. ```bash # All replay workflows (CI): for f in tests/operator-harness/replay/*.yaml; do BS_URL=http://127.0.0.1:3370 \ tests/operator-harness/replay-runner.sh dev-kvaps "$f" || exit 1 done ``` -------------------------------- ### Get DRBD minor number for a resource Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Retrieves the DRBD minor number for a given resource and node. Returns an empty string if the field is not set. ```bash status_drbd_minor() { kubectl get resource "${1}.${2}" -o jsonpath='{.status.drbdMinor}' 2>/dev/null } ``` -------------------------------- ### Create Replicated Volume Step-by-Step Source: https://github.com/cozystack/blockstor/blob/main/docs/usage.md Manually creates a replicated volume by defining resources and volumes explicitly. This method is useful when not using resource groups. ```sh linstor resource-definition create myvolume linstor volume-definition create myvolume 10G linstor resource create myvolume --auto-place 3 --storage-pool data ``` -------------------------------- ### Run Single Scenario Source: https://github.com/cozystack/blockstor/blob/main/tests/linstor-cli-scenarios.md Command to execute a specific end-to-end test scenario using the 'make e2e' target. ```bash make e2e NAME=e2e6 SCENARIO=linstor-cli-spawn ``` -------------------------------- ### Get DRBD Role (k8s-native) Source: https://github.com/cozystack/blockstor/blob/main/docs/test-status-cheatsheet.md Retrieves the role of a DRBD resource replica using `kubectl`. This field is stamped by an observer parsing `drbdsetup events2`. ```bash kubectl get resource "${rd}.${node}" -o jsonpath='{.status.role}' # → "Primary" ```