CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cgroupspy

Python library for managing Linux control groups (cgroups) with pythonic interface to filesystem operations

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

node-operations.mddocs/

Node Operations

Node classes for representing cgroup filesystem objects with creation, deletion, and traversal capabilities. Provides hierarchical representation of cgroups with controller integration and specialized functionality for different node types.

Capabilities

Basic Node Management

Core node class representing individual cgroup directories with filesystem operations and controller integration.

class Node:
    """Basic cgroup tree node with filesystem operations."""
    
    # Node type constants
    NODE_ROOT: bytes
    NODE_CONTROLLER_ROOT: bytes  
    NODE_SLICE: bytes
    NODE_SCOPE: bytes
    NODE_CGROUP: bytes
    
    # Controller mapping
    CONTROLLERS: dict  # Maps controller names to controller classes
    
    def __init__(self, name, parent=None):
        """
        Create a node representing a cgroup directory.
        
        Parameters:
        - name: str or bytes, node name/directory name
        - parent: Node, parent node (None for root)
        """
    
    @property
    def full_path(self) -> bytes:
        """Absolute system path to the node directory."""
    
    @property 
    def path(self) -> bytes:
        """Node's relative path from the root node."""
    
    @property
    def node_type(self) -> bytes:
        """Type of node (root, controller_root, slice, scope, cgroup)."""
    
    @property
    def controller_type(self) -> bytes:
        """Controller type for this node (cpu, memory, etc.)."""
    
    @property
    def controller(self):
        """Controller instance for managing this node's properties."""
    
    def create_cgroup(self, name):
        """
        Create a cgroup directory and attach it as child node.
        
        Parameters:
        - name: str or bytes, cgroup name
        
        Returns:
        Node object for the created cgroup
        
        Raises:
        RuntimeError if cgroup already exists
        OSError if filesystem operation fails
        """
    
    def delete_cgroup(self, name):
        """
        Delete a cgroup directory and detach from children.
        
        Parameters:
        - name: str or bytes, cgroup name
        
        Raises:
        OSError if cgroup is not empty or operation fails
        """
    
    def delete_empty_children(self):
        """
        Recursively delete all empty child cgroups.
        
        Walks through children and removes any empty directories.
        Continues recursively until no more empty children found.
        """
    
    def walk(self):
        """
        Walk through this node and its children - pre-order depth-first.
        
        Yields:
        Node objects in traversal order
        """
    
    def walk_up(self):
        """
        Walk through this node and its children - post-order depth-first.
        
        Yields:  
        Node objects in reverse traversal order
        """

Usage example:

from cgroupspy.trees import Tree

# Create tree and get cpuset controller
t = Tree()
cpuset = t.get_node_by_path('/cpuset/')

# Create new cgroup
test_cgroup = cpuset.create_cgroup('test')
print(test_cgroup.full_path)  # b'/sys/fs/cgroup/cpuset/test'
print(test_cgroup.path)       # b'/cpuset/test'

# Configure the cgroup
test_cgroup.controller.cpus = {0, 1}
test_cgroup.controller.mems = {0}

# Create nested cgroup
nested = test_cgroup.create_cgroup('nested')

# Clean up empty cgroups
cpuset.delete_empty_children()

# Delete specific cgroup
cpuset.delete_cgroup('test')

Grouped Control Nodes

Node class for grouping multiple nodes by hierarchy position, enabling unified access to same-named cgroups across different controllers.

class NodeControlGroup:
    """Groups multiple nodes by their position in cgroup hierarchy."""
    
    def __init__(self, name, parent=None):
        """
        Create a control group node.
        
        Parameters:
        - name: str or bytes, group name
        - parent: NodeControlGroup, parent group (None for root)
        """
    
    @property
    def name(self) -> bytes:
        """Control group name."""
    
    @property
    def path(self) -> bytes:
        """Control group path with extension handling."""
    
    @property
    def children(self) -> list:
        """List of child control groups."""
    
    @property
    def controllers(self) -> dict:
        """Dictionary of controllers by type."""
    
    @property
    def nodes(self) -> list:
        """List of underlying Node objects."""
    
    @property
    def group_tasks(self) -> set:
        """All process IDs in the hierarchy affected by this group."""
    
    @property
    def tasks(self) -> set:
        """Process IDs in this exact group only."""
    
    def add_node(self, node):
        """
        Add a Node object to the control group.
        
        Parameters:
        - node: Node, node to add (one per controller type)
        
        Raises:
        RuntimeError if controller type already assigned
        """

Usage example:

from cgroupspy.trees import GroupedTree

# Create grouped tree
gt = GroupedTree()

# Find a control group
machine = gt.get_node_by_name('machine')

# Access controllers through the group
print(machine.cpu.shares)        # CPU controller
print(machine.memory.limit_in_bytes)  # Memory controller

# View all tasks in the group hierarchy
print(machine.group_tasks)       # All PIDs in hierarchy
print(machine.tasks)             # PIDs in this exact group

# Access child groups
for child in machine.children:
    print(f"Child: {child.name}")

Virtual Machine Nodes

Specialized control group node for QEMU virtual machine management with VM-specific properties and component access.

class NodeVM(NodeControlGroup):
    """Specialized control group for QEMU virtual machine nodes."""
    
    @property
    def verbose_name(self) -> str:
        """Human-readable VM name or 'AnonymousVM' if unavailable."""
    
    @property
    def emulator(self):
        """NodeControlGroup for the emulator process or None."""
    
    @property  
    def vcpus(self) -> list:
        """List of NodeControlGroup objects for individual VCPUs."""

Usage example:

from cgroupspy.trees import VMTree

# Create VM tree
vmt = VMTree()

# Get VM node
vm = vmt.get_vm_node("test-vm-uuid")

# VM information
print(vm.verbose_name)           # VM display name
print(vm.path)                   # VM cgroup path

# VM resource limits
print(vm.cpu.shares)             # CPU shares
print(vm.memory.limit_in_bytes)  # Memory limit
print(vm.cpuset.cpus)            # CPU pinning

# VM components
emulator = vm.emulator
if emulator:
    print(emulator.cpu.shares)   # Emulator CPU shares

# VCPU management
vcpus = vm.vcpus
for i, vcpu in enumerate(vcpus):
    print(f"VCPU {i} CPUs: {vcpu.cpuset.cpus}")
    
    # Pin VCPU to specific cores
    vcpu.cpuset.cpus = {i % 4}   # Pin to core based on VCPU index

# Task management
print(vm.tasks)                  # PIDs directly in VM cgroup
print(vm.group_tasks)            # All PIDs in VM hierarchy

Install with Tessl CLI

npx tessl i tessl/pypi-cgroupspy

docs

index.md

node-operations.md

resource-controllers.md

tree-management.md

utilities.md

tile.json