fabric-generic-cluster
A comprehensive, type-safe Python framework for managing FABRIC testbed slices with support for complex network topologies, DPU interfaces, multi-OS configurations, and various hardware components.
🌟 Features
Core Capabilities
- ✅ Type-Safe Data Models - Pydantic-based topology definitions with automatic validation
- ✅ DPU Interface Support - Full support for DPU network interfaces alongside traditional NICs
- ✅ Multi-OS Support - Automatic detection and configuration for Rocky Linux, Ubuntu, and Debian
- ✅ Hardware Components - Full support for GPUs, FPGAs, DPUs, NVMe, and custom NICs
- ✅ Network Management - L2/L3 network configuration with IPv4/IPv6 support
- ✅ SSH Automation - Passwordless SSH setup across all nodes
- ✅ Visualization - Multiple output formats (text, ASCII, graphs, tables)
- ✅ Easy Installation - Available on PyPI via
pip install - ✅ Modular Design - Separated concerns for better maintainability
Hardware Support
- GPUs - NVIDIA RTX series, Tesla T4, A30, A40
- FPGAs - Xilinx Alveo U280, U50, U250
- DPUs - ConnectX-7 100G/400G Data Processing Units with network interfaces
- NVMe - Intel P4510, P4610 NVMe storage
- NICs - Basic, ConnectX-5, ConnectX-6, SharedNICs, SmartNICs
- Persistent Storage - Volume management
📋 Table of Contents
- Installation
- Quick Start
- Package Structure
- Usage Examples
- API Reference
- Command-Line Tools
- Development
- Documentation
- Contributing
🚀 Installation
From PyPI (Recommended)
pip install fabric-generic-cluster
From Source
git clone https://github.com/mcevik0/fabric-generic-cluster.git
cd fabric-generic-cluster
pip install -e .
Prerequisites
- Python 3.9 or higher
- Access to FABRIC testbed
fabrictestbed-extensions>=1.9.0(installed automatically)
Verify Installation
import fabric_generic_cluster
print(fabric_generic_cluster.__version__)
🎯 Quick Start
Option 1: Python Script
from fabric_generic_cluster import (
load_topology_from_yaml_file,
deploy_topology_to_fabric,
configure_l3_networks,
configure_node_interfaces,
setup_passwordless_ssh,
)
# Load topology
topology = load_topology_from_yaml_file("topology.yaml")
# Deploy to FABRIC
slice = deploy_topology_to_fabric(topology, "my-cluster")
# Configure networks (if using L3 networks)
configure_l3_networks(slice, topology)
# Configure interfaces
configure_node_interfaces(slice, topology)
# Setup SSH
setup_passwordless_ssh(slice)
print("✅ Cluster deployed and configured!")
Option 2: Using the Example Script
# Clone the repository for examples
git clone https://github.com/mcevik0/fabric-generic-cluster.git
cd fabric-generic-cluster
# Run the complete deployment example
python examples/complete-deployment-example.py \
--yaml path/to/topology.yaml \
--slice-name my-test-slice
Option 3: Jupyter Notebooks
For interactive workflows, check out the fabric-generic-cluster-notebooks repository:
git clone https://github.com/mcevik0/fabric-generic-cluster-notebooks.git
cd fabric-generic-cluster-notebooks
jupyter notebook
📦 Package Structure
fabric-generic-cluster/
├── fabric_generic_cluster/ # Main package
│ ├── __init__.py # Package exports
│ ├── models.py # Pydantic models for topology
│ ├── deployment.py # Slice deployment functions
│ ├── network_config.py # Network configuration
│ ├── ssh_setup.py # SSH management
│ ├── topology_viewer.py # Visualization tools
│ ├── builder_compat.py # Backward compatibility
│ └── tools/ # Command-line tools
│ ├── __init__.py
│ └── topology_summary.py # Topology summary generator
│
├── examples/ # Usage examples
│ └── complete-deployment-example.py
│
├── tests/ # Test suite
│ ├── test-dpu-support.py
│ └── test-fpga-support.py
│
├── pyproject.toml # Package metadata
├── setup.py # Setup configuration
├── MANIFEST.in # Package data
├── LICENSE # MIT License
└── README.md # This file
📚 Usage Examples
Example 1: Load and Explore Topology
from fabric_generic_cluster import (
load_topology_from_yaml_file,
print_topology_summary,
draw_topology_graph,
)
# Load topology
topology = load_topology_from_yaml_file("topology.yaml")
# Print summary
print_topology_summary(topology)
# Create visualization
draw_topology_graph(topology, show_ip=True, save_path="topology.png")
Example 2: Deploy Multi-Site Cluster
from fabric_generic_cluster import (
load_topology_from_yaml_file,
deploy_topology_to_fabric,
configure_node_interfaces,
verify_node_interfaces,
)
# Load topology with nodes at multiple sites
topology = load_topology_from_yaml_file("multi-site-topology.yaml")
# Deploy
slice = deploy_topology_to_fabric(topology, "multi-site-cluster")
# Configure all nodes
configure_node_interfaces(slice, topology)
# Verify configuration
verify_node_interfaces(slice, topology)
Example 3: Access Type-Safe Data
from fabric_generic_cluster import load_topology_from_yaml_file
topology = load_topology_from_yaml_file("topology.yaml")
# Get specific node
node = topology.get_node_by_hostname("node-1")
print(f"Node: {node.hostname}")
print(f"Site: {node.site}")
print(f"CPU: {node.capacity.cpu} cores")
print(f"RAM: {node.capacity.ram} GB")
# Check hardware components
if node.pci.dpu:
print(f"DPUs: {len(node.pci.dpu)}")
for dpu_name, dpu in node.pci.dpu.items():
print(f" - {dpu_name}: {dpu.model}")
print(f" Interfaces: {len(dpu.interfaces)}")
if node.pci.fpga:
print(f"FPGAs: {len(node.pci.fpga)}")
for fpga_name, fpga in node.pci.fpga.items():
print(f" - {fpga_name}: {fpga.model}")
# Get all interfaces (NIC + DPU)
all_interfaces = node.get_all_interfaces()
print(f"\nTotal interfaces: {len(all_interfaces)}")
for device_name, iface_name, iface in all_interfaces:
device_type = "DPU" if device_name.startswith("dpu") else "NIC"
print(f"{device_type} {device_name}.{iface_name}: {iface.binding}")
Example 4: Test Network Connectivity
from fabric_generic_cluster import (
get_slice,
load_topology_from_yaml_file,
ping_network_from_node,
verify_ssh_access,
)
# Get existing slice
slice = get_slice("my-cluster")
topology = load_topology_from_yaml_file("topology.yaml")
# Test ping connectivity
ping_results = ping_network_from_node(
slice,
topology,
source_hostname="node-1",
network_name="network1",
count=3
)
if all(ping_results.values()):
print("✅ All ping tests passed!")
# Test SSH access
ssh_results = verify_ssh_access(
slice,
topology,
source_hostname="node-1",
network_name="network1"
)
if all(ssh_results.values()):
print("✅ All SSH connections successful!")
Example 5: Using Module-Style Imports
For compatibility with existing code:
from fabric_generic_cluster import deployment as sd
from fabric_generic_cluster import network_config as snc
from fabric_generic_cluster import ssh_setup as ssh
from fabric_generic_cluster import load_topology_from_yaml_file
# Load topology
topology = load_topology_from_yaml_file("topology.yaml")
# Deploy
slice = sd.deploy_topology_to_fabric(topology, "my-slice")
# Configure
snc.configure_node_interfaces(slice, topology)
ssh.setup_passwordless_ssh(slice)
🔧 API Reference
Models and Loaders
from fabric_generic_cluster import (
SiteTopology, # Main topology model
Node, # Node model
Network, # Network model
load_topology_from_yaml_file, # Load from YAML file
load_topology_from_dict, # Load from dictionary
)
Deployment Functions
from fabric_generic_cluster import (
deploy_topology_to_fabric, # Deploy slice to FABRIC
configure_l3_networks, # Configure L3 networks
get_slice, # Get existing slice
delete_slice, # Delete slice
check_slices, # List all slices
)
# Usage
slice = deploy_topology_to_fabric(topology, "slice-name")
configure_l3_networks(slice, topology)
Network Configuration
from fabric_generic_cluster import (
configure_node_interfaces, # Configure all interfaces
verify_node_interfaces, # Verify configuration
ping_network_from_node, # Test connectivity
update_hosts_file_on_nodes, # Update /etc/hosts
)
# Usage
configure_node_interfaces(slice, topology)
verify_node_interfaces(slice, topology)
SSH Setup
from fabric_generic_cluster import (
setup_passwordless_ssh, # Complete SSH setup
verify_ssh_access, # Verify SSH connectivity
)
# Usage
setup_passwordless_ssh(slice)
results = verify_ssh_access(slice, topology, "node-1", "network1")
Visualization
from fabric_generic_cluster import (
print_topology_summary, # Detailed summary
print_compact_summary, # Brief summary
draw_topology_graph, # Visual graph
)
# Usage
print_topology_summary(topology)
draw_topology_graph(topology, show_ip=True, save_path="topology.png")
🛠️ Command-Line Tools
Topology Summary Generator
The package includes a command-line tool for generating topology summaries:
# Generate summary for a YAML file
fabric-topology-summary input.yaml --output output.yaml
# Just print summary without modifying file
fabric-topology-summary input.yaml --dry-run
# Include ASCII diagram
fabric-topology-summary input.yaml --ascii --output output.yaml
This tool is automatically installed when you install the package.
💻 Development
Setting Up Development Environment
# Clone repository
git clone https://github.com/mcevik0/fabric-generic-cluster.git
cd fabric-generic-cluster
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
Running Tests
# Run test suite
pytest tests/
# Run specific test
python tests/test-dpu-support.py
python tests/test-fpga-support.py
Package Version
The [project].version field in pyproject.toml is the version source of truth.
fabric_generic_cluster.__version__ reads the installed distribution metadata
and falls back to "0+unknown" in an uninstalled source checkout when metadata
is unavailable. After changing the project version for a release, editable
installs may need their metadata refreshed by reinstalling with
pip install -e ".[dev]".
Building the Package
# Install build tools
pip install build twine
# Build distribution
python -m build
# Check package
twine check dist/*
# Test upload to TestPyPI
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*
Code Style
# Format code
black fabric_generic_cluster/
# Check style
flake8 fabric_generic_cluster/
📖 Documentation
Comprehensive Guides
- Getting Started: See Quick Start above
- Jupyter Notebooks: fabric-generic-cluster-notebooks
- YAML Format: Detailed topology format documentation in notebooks repository
- API Reference: See API Reference above
Example Topologies
Example YAML topology files are available in the notebooks repository:
- Basic 2-node cluster
- Multi-site deployment
- Storage cluster with NVMe
- DPU/SmartNIC configurations
- FPGA-enabled topologies
- OpenStack deployment variants
YAML Topology Format
site_topology:
nodes:
node-1:
hostname: node-1
site: SITE1
capacity:
cpu: 8
ram: 32
disk: 100
os: default_rocky_9
nics:
nic1:
interfaces:
iface1:
binding: network1
ipv4_address: 10.0.1.1
ipv4_netmask: 255.255.255.0
pci:
dpu:
dpu1:
model: NIC_ConnectX_7_100
interfaces:
iface1:
binding: network1
ipv4_address: 10.0.1.10
networks:
network1:
name: network1
type: L2Bridge
subnet: 10.0.1.0/24
🤝 Contributing
Contributions are welcome! Here's how you can help:
- Report bugs: Open an issue on GitHub
- Suggest features: Open an issue with your idea
- Submit PRs: Fork, make changes, and submit a pull request
Contribution Guidelines
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Workflow
- Update code in
fabric_generic_cluster/ - Add tests in
tests/ - Update documentation
- Run tests:
pytest tests/ - Build package:
python -m build - Test locally:
pip install dist/*.whl
📊 Performance
- Validation Speed: ~10ms for typical topology (3-10 nodes)
- Deployment Time: Depends on FABRIC (typically 5-10 minutes)
- Network Config: ~30 seconds per node
- SSH Setup: ~1-2 minutes for 3-node cluster
🗺️ Roadmap
- Type-safe Pydantic models
- DPU interface support
- Multi-distro support (Rocky/Ubuntu/Debian)
- L2/L3 network configuration
- Automated SSH setup
- PyPI package distribution
- Web-based topology editor
- Ansible playbook integration
- Monitoring and metrics collection
- REST API endpoint
🐛 Troubleshooting
Import Issues
Problem: ModuleNotFoundError: No module named 'fabric_generic_cluster'
Solution:
pip install fabric-generic-cluster
YAML File Not Found
Problem: FileNotFoundError when loading topology
Solution: Use absolute paths or ensure YAML file is in current directory:
from pathlib import Path
yaml_file = Path("path/to/topology.yaml")
topology = load_topology_from_yaml_file(str(yaml_file))
DPU Interfaces Not Detected
Problem: DPU interfaces not showing up
Solution: Verify DPU configuration in YAML:
node = topology.get_node_by_hostname("node-1")
print(f"DPUs: {node.pci.dpu}")
# Check all interfaces
all_ifaces = node.get_all_interfaces()
print(f"Total interfaces: {len(all_ifaces)}")
Network Configuration Fails
Problem: Interface configuration errors
Solution:
- Check L3 networks are configured first:
configure_l3_networks(slice, topology) - Ensure nodes are active:
slice.wait() - Verify OS detection: Check logs for supported distro
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built for the FABRIC Testbed
- Uses Pydantic for data validation
- Network visualization with NetworkX and Matplotlib
📞 Support
- 📧 Issues: GitHub Issues
- 📚 Documentation: fabric-generic-cluster-notebooks
- 💬 FABRIC Slack: FABRIC Workspace
- 🌐 FABRIC Help: FABRIC Learn
📦 Related Repositories
- Jupyter Notebooks: fabric-generic-cluster-notebooks - Example notebooks and topology files
- PyPI Package: fabric-generic-cluster - Install via pip
🔗 Links
- GitHub: https://github.com/mcevik0/fabric-generic-cluster
- PyPI: https://pypi.org/project/fabric-generic-cluster/
- Documentation: https://github.com/mcevik0/fabric-generic-cluster-notebooks
- FABRIC Testbed: https://fabric-testbed.net/
Made with ❤️ for the FABRIC Community
Author: Mert Cevik (@mcevik0)
Metadata
Release files for fabric-generic-cluster 1.0.20
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fabric_generic_cluster-1.0.20.tar.gz | 68.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fabric_generic_cluster-1.0.20-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 136.9 kB
Release files / fabric_generic_cluster-1.0.20.tar.gz
| Download URL | fabric_generic_cluster-1.0.20.tar.gz |
|---|---|
| Size | 68.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a5e8686b54ddd36f850536b6322db8d0c7e2e80358a3a5dc4fcf136bc715f365
|
|
BLAKE2b-256 checksum How to use checksums |
2407f27a51319a1d3561f1172f2d5ba801fce85900142f15fa41acdfb17a929e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / fabric_generic_cluster-1.0.20-py3-none-any.whl
| Download URL | fabric_generic_cluster-1.0.20-py3-none-any.whl |
|---|---|
| Size | 68.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
269615c36245de5051643647dc70f4b2612d9724164102f612fbd9b9ab5337cf
|
|
BLAKE2b-256 checksum How to use checksums |
0cf9906efc669421a1c25a6c5e086e5429b61c020d68928e1efa95e4a83fd0b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|