Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/markitobonito/cloud_repositorio/llms.txt

Use this file to discover all available pages before exploring further.

OrchestratorAPI is the primary entry point for managing slices programmatically. It coordinates the Database, DeploymentAPI, VMLauncher, and VLANManager to provide a high-level interface for the full VM lifecycle — from slice creation and topology design through deployment and teardown.

Constructor

__init__(db, deployment_api)

db
Database
required
A Database instance used for all persistence operations (slices, users, ID counters).
deployment_api
DeploymentAPI
required
A DeploymentAPI instance. Its .executor attribute is used internally to construct VMLauncher and VLANManager.
The constructor also reads workers_list from the database to initialise the round-robin worker selector. If workers_list is absent the default list ["10.0.10.1", "10.0.10.2", "10.0.10.3"] is used.
from database import Database
from remote_executor import RemoteExecutor
from deployment_api import DeploymentAPI
from orchestrator_api import OrchestratorAPI

db = Database()
executor = RemoteExecutor()
deployment = DeploymentAPI(executor)
orchestrator = OrchestratorAPI(db, deployment)

Methods

create_slice(username, slice_name, topology_type="custom")(bool, dict | str)

Creates a new slice record in the database and registers it on the given user.
username
string
required
Must match an existing user in the database. Returns (False, "User not found") otherwise.
slice_name
string
required
Human-readable label returned in the success payload. Not persisted in the database — the slice is identified by its numeric slice_id.
topology_type
string
default:"custom"
Topology descriptor stored on the Slice object (e.g. "custom", "linear", "star").
Returns
  • (True, {"slice_id": int, "name": str}) — slice created successfully.
  • (False, error_str) — user not found or unexpected exception.
The VLAN pool is computed automatically from slice_id at creation time (see Slice).
success, result = orchestrator.create_slice("admin", "my-slice")
# success → True
# result  → {"slice_id": 1000, "name": "my-slice"}

add_vm_to_slice(username, slice_id, vm_name, flavor_name, data_interfaces_count, internet_enabled=False)(bool, dict | str)

Creates a VM object (with QCOW2 backing image) and appends it to the named slice.
username
string
required
Must own the slice. Returns (False, "Not authorized") otherwise.
slice_id
integer
required
Numeric slice identifier returned by create_slice.
vm_name
string
required
Human-readable VM name, used as the QCOW2 filename prefix ({vm_name}_img.qcow2).
flavor_name
string
required
Must be "cirros" or "ubuntu". Any other value returns (False, "Invalid flavor").
data_interfaces_count
integer
required
Number of data interfaces to create (eth1, eth2, …). These are created without a VLAN assignment and become available for linking.
internet_enabled
boolean
default:"false"
When True, eth0 is assigned to VLAN 400 and given an IP in the 10.60.7.0/24 management range. When False, eth0 is created with no VLAN.
Returns
  • (True, vm_dict)vm_dict is the full serialized VM object including vm_id, vnc_port, worker_ip, interfaces, and qcow_image.
  • (False, error_str) — user/slice not found, quota exceeded, invalid flavor, QCOW creation failure, or unexpected exception.
The user’s used_vms counter is incremented by 1 on success.
success, vm = orchestrator.add_vm_to_slice(
    "admin",
    slice_id=1000,
    vm_name="vm1",
    flavor_name="cirros",
    data_interfaces_count=1,
    internet_enabled=True,
)
# vm["vm_id"]    → 1001
# vm["vnc_port"] → 5901
# vm["interfaces"][0]["name"]    → "eth0"
# vm["interfaces"][0]["vlan_id"] → 400
# vm["interfaces"][1]["name"]    → "eth1"
# vm["interfaces"][1]["vlan_id"] → None  (not yet linked)

Creates a Layer-2 link between two VM interfaces by assigning the next available VLAN from the slice pool and recording it on both interfaces.
username
string
required
Must own the slice.
slice_id
integer
required
Slice that contains both VMs.
vm1_id
integer
required
ID of the first VM.
vm1_interface
string
required
Interface name on the first VM, e.g. "eth1".
vm2_id
integer
required
ID of the second VM.
vm2_interface
string
required
Interface name on the second VM, e.g. "eth1".
Returns
  • (True, link_dict) — includes link_id, vlan_id, vm1_id, vm1_interface, vm2_id, vm2_interface.
  • (False, "VLAN pool exhausted") — all 20 VLANs in the slice pool are in use.
  • (False, error_str) — slice not found, not authorized, or unexpected exception.
Both matched interfaces in the slice’s VM list have their vlan_id and link_id fields updated in the database before returning.
success, link = orchestrator.create_link(
    "admin",
    slice_id=1000,
    vm1_id=1001, vm1_interface="eth1",
    vm2_id=1002, vm2_interface="eth1",
)
# link → {"link_id": 1, "vlan_id": 100, "vm1_id": 1001,
#          "vm1_interface": "eth1", "vm2_id": 1002, "vm2_interface": "eth1"}

deploy_slice(username, slice_id)(bool, str)

Deploys a slice by configuring VLANs on the network node and launching all VMs on their assigned workers.
username
string
required
Must own the slice.
slice_id
integer
required
Slice to deploy. Must be in "design" status; returns an error if already "running".
Execution order
1

Internet VLAN

If any VM interface has vlan_id == 400, calls VLANManager.create_vlan_with_gateway(400, "10.60.7.0/24", "10.60.7.1") followed by enable_internet_for_vlan(400, "10.60.7.0/24").
2

Per-link VLANs

For each link in the slice, derives cidr = "192.168.{vlan_id % 256}.0/24" and calls create_vlan_with_gateway(vlan_id, cidr, gateway_ip, dhcp_enabled=True). Fails fast on the first VLAN configuration error.
3

VM launch

Calls VMLauncher.launch_vm(worker_ip, vm_dict) for each VM. On success, sets vm_dict["status"] = "running" and stores the PID. Fails fast on the first launch error.
Returns
  • (True, "Slice deployed successfully") — all VLANs configured and all VMs running.
  • (False, error_str) — first failure encountered during any step.
The slice status is set to "running" in the database only if all steps succeed.
success, msg = orchestrator.deploy_slice("admin", 1000)
# success → True
# msg     → "Slice deployed successfully"

delete_slice(username, slice_id)(bool, str)

Tears down a slice and frees all associated resources.
username
string
required
Must own the slice.
slice_id
integer
required
Slice to delete.
Teardown order
  • If running: stops each VM via VMLauncher.stop_vm() (kills QEMU, removes TAP devices from OVS), then deletes each link VLAN via VLANManager.delete_vlan().
  • Always: deletes QCOW2 images via DeploymentAPI.delete_vm_dict() for each VM.
  • Always: removes the slice record from the database, removes slice_id from user["slices"], and decrements user["used_vms"] by the VM count (floored at 0).
Returns
  • (True, "Slice deleted")
  • (False, error_str) — slice not found, not authorized, or unexpected exception.
success, msg = orchestrator.delete_slice("admin", 1000)
# success → True
# msg     → "Slice deleted"

get_next_worker()str

Returns the IP address of the next worker node using a round-robin strategy. The internal round_robin_idx counter is incremented on each call.
This is an internal method called automatically by add_vm_to_slice. The worker list is populated from database.yaml under the key workers_list. Update that list to change which nodes receive new VMs.
# With workers ["10.0.10.1", "10.0.10.2", "10.0.10.3"]
orchestrator.get_next_worker()  # "10.0.10.1"
orchestrator.get_next_worker()  # "10.0.10.2"
orchestrator.get_next_worker()  # "10.0.10.3"
orchestrator.get_next_worker()  # "10.0.10.1"  (wraps around)

Build docs developers (and LLMs) love