一键导入
fabric-recipes
Deploy common applications on FABRIC including web servers, LLMs, scientific workflows, DHCP, BGP peering, and network monitoring
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Deploy common applications on FABRIC including web servers, LLMs, scientific workflows, DHCP, BGP peering, and network monitoring
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | fabric-recipes |
| description | Deploy common applications on FABRIC including web servers, LLMs, scientific workflows, DHCP, BGP peering, and network monitoring |
| allowed-tools | ["Read","Grep","Glob","Write","Edit","Bash"] |
When invoked, generate code for deploying common applications and services on FABRIC. Available recipes:
Help the user choose the right recipe and generate complete code.
from fabrictestbed_extensions.fablib.fablib import FablibManager
from ipaddress import IPv4Network
fablib = FablibManager()
site = fablib.get_random_site()
slice = fablib.new_slice(name="apache-web-server")
subnet = IPv4Network("192.168.1.0/24")
net = slice.add_l2network(name="net1", subnet=subnet)
server = slice.add_node(name="server", site=site, image="default_ubuntu_20")
server_iface = server.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
server_iface.set_mode("auto")
net.add_interface(server_iface)
client = slice.add_node(name="client", site=site, image="default_ubuntu_20")
client_iface = client.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
client_iface.set_mode("auto")
net.add_interface(client_iface)
slice.submit()
server = slice.get_node(name="server")
# Install Apache
server.execute("sudo apt-get update && sudo apt-get install -y apache2")
# Configure firewall
server.execute("sudo ufw allow 'Apache' && sudo ufw allow ssh && echo 'y' | sudo ufw enable")
# Custom document root
apache_root = "/home/ubuntu/apache_contents"
server.execute(f"mkdir -p {apache_root}")
server.execute(
f"sudo sed -i 's,/var/www/html,{apache_root},g' "
"/etc/apache2/sites-available/000-default.conf"
)
server.execute("sudo service apache2 restart")
# Upload content
server.execute(f"echo '<h1>Hello FABRIC</h1>' > {apache_root}/index.html")
# Test from client
server_addr = server.get_interface(network_name="net1").get_ip_addr()
client = slice.get_node(name="client")
stdout, _ = client.execute(f"curl http://{server_addr}")
print(stdout)
# Find a site with GPUs
site = fablib.get_random_site(
filter_function=lambda x: x['rtx6000_available'] > 0
)
slice = fablib.new_slice(name="ollama-llm")
node = slice.add_node(
name="llm-node",
site=site,
cores=16,
ram=64,
disk=200,
image="default_ubuntu_22",
)
node.add_component(model="GPU_RTX6000", name="gpu1")
node.add_fabnet()
slice.submit()
node = slice.get_node(name="llm-node")
# Install NVIDIA drivers (see fabric-gpu skill for full install)
# ... driver installation steps ...
# Install Ollama
node.execute("curl -fsSL https://ollama.com/install.sh | sh")
# Configure for remote access via FABNet
override_config = """[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
"""
node.execute("sudo mkdir -p /etc/systemd/system/ollama.service.d")
node.execute(
f"echo '{override_config}' | "
"sudo tee /etc/systemd/system/ollama.service.d/override.conf"
)
node.execute("sudo systemctl daemon-reload && sudo systemctl restart ollama")
# Pull and test a model
node.execute("ollama pull deepseek-r1:7b")
stdout, _ = node.execute('ollama run deepseek-r1:7b "Tell me a joke"')
print(stdout)
# Access via FABNet IP from other nodes
ollama_ip = node.get_interface(
network_name=f"FABNET_IPv4_{node.get_site()}"
).get_ip_addr()
print(f"Ollama API: http://{ollama_ip}:11434")
sites = fablib.get_random_sites(count=2)
slice = fablib.new_slice(name="pegasus-experiment")
# Submit node (Pegasus planner + HTCondor central manager)
submit = slice.add_node(
name="pegasus-submit",
site=sites[0],
cores=16,
ram=32,
disk=500,
)
submit.add_fabnet()
# Worker nodes at each site
for i, site in enumerate(sites):
worker = slice.add_node(
name=f"worker-{i}",
site=site,
cores=24,
ram=48,
disk=500,
)
worker.add_fabnet()
slice.submit()
nodes = slice.get_nodes()
# Build /etc/hosts from FABNet IPs
host_to_ip = {}
for n in nodes:
for iface in n.get_interfaces():
ip = iface.get_ip_addr()
if ip:
host_to_ip[n.get_name()] = str(ip)
break
hosts_block = "\n".join(f"{ip} {host}" for host, ip in host_to_ip.items())
for n in nodes:
n.execute(f"sudo sh -c 'echo \"{hosts_block}\" >> /etc/hosts'")
# Distribute SSH keys for passwordless access
for n in nodes:
n.execute('ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa', quiet=True)
n.execute('sudo ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa', quiet=True)
# Collect and distribute public keys (see fabric-containers skill for full pattern)
from ipaddress import IPv4Network, IPv4Address
subnet = IPv4Network("192.168.1.0/24")
slice = fablib.new_slice(name="dhcp-experiment")
site = fablib.get_random_site()
net = slice.add_l2network(name="dhcp-net", subnet=subnet)
# DHCP server
server = slice.add_node(name="dhcp-server", site=site)
server_iface = server.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
server_iface.set_mode("config")
net.add_interface(server_iface)
# DHCP clients
for i in range(3):
client = slice.add_node(name=f"client-{i}", site=site)
iface = client.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface.set_mode("manual")
net.add_interface(iface)
slice.submit()
# Configure DHCP server
server = slice.get_node(name="dhcp-server")
server_iface = server.get_interface(network_name="dhcp-net")
available_ips = list(subnet.hosts())
server_iface.ip_addr_add(addr=available_ips[0], subnet=subnet)
server.execute(f"sudo ifconfig {server_iface.get_os_interface()} up")
# Install and configure DHCP
server.execute("sudo apt-get update && sudo apt-get install -y isc-dhcp-server")
dhcpd_config = """
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option subnet-mask 255.255.255.0;
}
"""
server.execute(f"sudo bash -c 'echo \"{dhcpd_config}\" >> /etc/dhcp/dhcpd.conf'")
server.execute("sudo systemctl restart isc-dhcp-server")
# Request DHCP lease on clients
for i in range(3):
client = slice.get_node(name=f"client-{i}")
os_iface = client.get_interface(network_name="dhcp-net").get_os_interface()
client.execute(f"sudo dhclient {os_iface}")
stdout, _ = client.execute(f"ip addr show {os_iface}")
print(f"client-{i}: {stdout}")
site = fablib.get_random_site()
slice = fablib.new_slice(name="peering-client")
node = slice.add_node(name="peering-node", site=site, cores=4, ram=16, disk=50)
# FABNet IPv6 for peering
fab6 = slice.add_l3network(name="fab6", type="IPv6")
iface = node.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface.set_mode("auto")
fab6.add_interface(iface)
slice.submit()
node = slice.get_node(name="peering-node")
# Configure FABNet IPv6 route
fab6net = slice.get_network(name="fab6")
fab6iface = node.get_interface(network_name="fab6")
node.execute(f"sudo ip link set dev {fab6iface.get_os_interface()} up")
node.ip_route_add(subnet=fablib.FABNETV6_SUBNET, gateway=fab6net.get_gateway())
# Install PEERING client
node.execute(
"git clone --branch fabric https://github.com/PEERINGTestbed/client.git"
)
# Upload PEERING credentials
node.upload_file("client.crt", "/home/ubuntu/client/certs/client.crt")
node.upload_file("prefixes.txt", "/home/ubuntu/client/prefixes.txt")
# Start OpenVPN tunnel and BGP daemon
# node.execute("cd client && ./peering openvpn up fabwash")
# node.execute("cd client && ./peering bgp start")
from ipaddress import IPv6Address, IPv6Network
site = fablib.get_random_site()
slice = fablib.new_slice(name="pmacctd-experiment")
net = slice.add_l2network(name="monitor-net")
node1 = slice.add_node(name="sender", site=site)
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
net.add_interface(iface1)
node2 = slice.add_node(name="collector", site=site)
iface2 = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
net.add_interface(iface2)
slice.submit()
# Configure IPv6 addresses
node1 = slice.get_node(name="sender")
iface1 = node1.get_interface(network_name="monitor-net")
iface1.ip_addr_add(addr=IPv6Address("fd3f:f209:c712::1"), subnet=IPv6Network("fd3f:f209:c712::/48"))
node1.execute(f"sudo ifconfig {iface1.get_os_interface()} up")
# Install pmacctd
node1.execute(
"sudo apt-get update && "
"sudo apt-get install -y libpcap-dev pkg-config libtool autoconf automake libjansson-dev"
)
node1.execute(
"wget https://github.com/pmacct/pmacct/archive/refs/tags/v1.7.8.tar.gz && "
"tar xzf v1.7.8.tar.gz && cd pmacct-1.7.8 && "
"./autogen.sh && ./configure --enable-jansson && make && sudo make install"
)
# Create config and run
pmacctd_config = """
daemonize: false
pcap_interface: {iface_name}
aggregate: src_host, dst_host, src_port, dst_port, proto
plugins: print[csv]
print_output[csv]: csv
""".format(iface_name=iface1.get_os_interface())
node1.execute(f"echo '{pmacctd_config}' > pcap_csv.conf")
node1.execute("sudo pmacctd -f pcap_csv.conf &")
site = fablib.get_random_site(
filter_function=lambda x: x['nic_connectx_6_available'] > 0
)
slice = fablib.new_slice(name="vlan-experiment")
# Two L3 networks on different VLANs
net1 = slice.add_l3network(name="vlan100", type="IPv4")
net2 = slice.add_l3network(name="vlan200", type="IPv4")
# Node with dedicated NIC and sub-interfaces
node = slice.add_node(name="multi-vlan", site=site, cores=4, ram=16, disk=50)
nic = node.add_component(model="NIC_ConnectX_6", name="nic1").get_interfaces()[0]
# Create VLAN sub-interfaces
sub1 = nic.add_sub_interface("child1", vlan="100")
sub1.set_mode("auto")
net1.add_interface(sub1)
sub2 = nic.add_sub_interface("child2", vlan="200")
sub2.set_mode("auto")
net2.add_interface(sub2)
# Add route for FABNet cross-site connectivity
node.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net1.get_gateway())
slice.submit()
# Verify sub-interfaces
node = slice.get_node(name="multi-vlan")
stdout, _ = node.execute("ip addr show")
print(stdout)
# Check IPs on each VLAN
for net_name in ["vlan100", "vlan200"]:
iface = node.get_interface(network_name=net_name)
print(f"{net_name}: {iface.get_ip_addr()}")
ufw for firewall; change document root via sites-available configOLLAMA_HOST=0.0.0.0 for remote access/etc/hosts across all nodes'config' mode; clients use 'manual' modeRun iPerf3 network performance benchmarks with optional CPU pinning and SmartNIC optimization
Generate FABRIC testbed environment setup, configuration validation, and SSH key management code
Deploy Docker containers and Kubernetes clusters on FABRIC nodes
Connect FABRIC to external testbeds via facility ports and set up port mirroring
Provision and flash Xilinx U280 FPGAs on FABRIC nodes
Provision GPU nodes on FABRIC with driver installation and CUDA setup