杰瑞科技汇

python cobbler api

Of course! The Cobbler API is a powerful way to automate infrastructure provisioning using Python. Here’s a comprehensive guide covering what it is, how to use it, and practical examples.

python cobbler api-图1
(图片来源网络,侵删)

What is the Cobbler API?

Cobbler is a Linux installation server that allows for rapid setup of network installation environments. It can PXE boot, provision, and manage the lifecycle of servers.

The Cobbler API is a Python-based, XML-RPC interface that allows you to programmatically control every aspect of a Cobbler server. This means you can write Python scripts to:

  • Add, edit, and delete distributions (OS install trees).
  • Manage profiles (templates for systems).
  • Create and manage system entries (individual hosts to be provisioned).
  • Sync configuration files to the TFTP and web servers.
  • Kick off installations.

The API is the backbone of the Cobbler web interface (cobbler-web) and is designed for automation.

How to Access the API

The API is exposed as an XML-RPC service. You don't need to know the details of XML-RPC to use it. The cobbler Python module provides a convenient wrapper.

python cobbler api-图2
(图片来源网络,侵删)

Prerequisites

You need the cobbler Python module installed on the machine where your script will run. This is typically installed on the Cobbler server itself.

# On RHEL/CentOS/Fedora
sudo dnf install cobbler
# On Debian/Ubuntu
sudo apt-get install cobbler

Connecting to the API

Your first step in any script is to create a connection to the Cobbler API server.

import cobbler.api as capi
try:
    # Connect to the Cobbler API
    # The API is typically on the local Cobbler server.
    # The second argument is the username, and the third is the password.
    # Default credentials are usually "cobbler" / "cobbler".
    api = capi.CobblerAPI("http://127.0.0.1", "cobbler", "cobbler")
    # You can test the connection
    if api is not None:
        print("Successfully connected to Cobbler API!")
        print(f"Cobbler Version: {api.get_version()}")
except Exception as e:
    print(f"Error connecting to Cobbler API: {e}")
    exit(1)

Common API Operations

Once connected, the api object gives you access to all of Cobbler's functionality. The methods are organized into logical groups.

A. Getting Information (Read-Only)

You can query all objects in Cobbler.

# --- Get all distributions ---
distributions = api.get_distributions()
print(f"\nFound {len(distributions)} distributions:")
for dist in distributions:
    print(f"  - {dist.name} (Kernel: {dist.kernel})")
# --- Get all profiles ---
profiles = api.get_profiles()
print(f"\nFound {len(profiles)} profiles:")
for profile in profiles:
    print(f"  - {profile.name} (Distro: {profile.get_distro()})")
# --- Get all systems ---
systems = api.get_systems()
print(f"\nFound {len(systems)} systems:")
for system in systems:
    print(f"  - {system.name} (Profile: {system.get_profile()})")

B. Creating and Modifying Objects (CRUD)

This is where the real power lies. The general pattern is:

  1. Get a new object from the API (e.g., api.new_distro()).
  2. Set its attributes.
  3. Call the appropriate add_...() or add_..._autoinstall() method.
  4. Call api.sync() to apply the changes to the filesystem.

Important: After adding, editing, or deleting objects, you must call api.sync() for the changes to take effect. This generates the PXE files, DHCP configurations, etc.

Example 1: Adding a New Distribution

Let's say you have a custom OS install tree available via HTTP.

# Create a new distribution object
new_distro = api.new_distro()
# Set the attributes for the distribution
new_distro.name = "custom-rocky9-x86_64"
new_distro.kernel = "/var/www/cobbler/distro_images/custom-rocky9-x86_64/images/pxeboot/vmlinuz"
new_distro.initrd = "/var/www/cobbler/distro_images/custom-rocky9-x86_64/images/pxeboot/initrd.img"
new_distro.breed = "redhat"
new_distro.os_version = "rhel9"
new_distro.arch = "x86_64"
new_distro.boot_files = {
    "/images/pxeboot/kernel": "/var/www/cobbler/distro_images/custom-rocky9-x86_64/images/pxeboot/kernel",
    "/images/pxeboot/initrd.img": "/var/www/cobbler/distro_images/custom-rocky9-x86_64/images/pxeboot/initrd.img"
}
# Add the distribution to Cobbler
api.add_distro(new_distro, save=True) # save=True is equivalent to calling api.sync() after
print(f"\nSuccessfully added distribution: {new_distro.name}")

Example 2: Adding a Profile and a System

Profiles are templates for systems. Let's create a profile based on the distribution we just added, and then a system that uses that profile.

# --- Create a Profile ---
new_profile = api.new_profile()
new_profile.name = "web-server-profile"
new_profile.distro = "custom-rocky9-x86_64" # Use the name of the distro
new_profile.kickstart = "/var/lib/cobbler/kickstarts/rocky9-ks.cfg"
new_profile.kernel_options = {
    "lang": "en_US",
    "text": "", # Install in text mode
    "ksdevice": "eth0"
}
api.add_profile(new_profile, save=True)
print(f"\nSuccessfully added profile: {new_profile.name}")
# --- Create a System ---
new_system = api.new_system()
new_system.name = "web-server-01"
new_system.profile = "web-server-profile"
new_system.hostname = "web-01.example.com"
new_system.interfaces = {
    "eth0": {
        "macaddress": "52:54:00:12:34:56",
        "ipaddress": "192.168.1.101",
        "netmask": "255.255.255.0",
        "dhcp_tag": "default",
        "static": True
    }
}
api.add_system(new_system, save=True)
print(f"\nSuccessfully added system: {new_system.name}")
# --- Final Sync ---
# It's good practice to sync one last time to ensure everything is clean.
# The individual save=True calls should handle this, but a final sync is robust.
api.sync()
print("\nFinal sync complete.")

C. Deleting Objects

Deleting is straightforward. You just need the name of the object.

# --- Delete a System ---
system_to_delete = "web-server-01"
if api.find_system(name=system_to_delete):
    api.remove_system(system_to_delete, save=True)
    print(f"\nSuccessfully deleted system: {system_to_delete}")
else:
    print(f"\nSystem not found: {system_to_delete}")
# --- Delete a Profile ---
profile_to_delete = "web-server-profile"
if api.find_profile(name=profile_to_delete):
    api.remove_profile(profile_to_delete, save=True)
    print(f"Successfully deleted profile: {profile_to_delete}")
else:
    print(f"Profile not found: {profile_to_delete}")
# --- Delete a Distribution ---
distro_to_delete = "custom-rocky9-x86_64"
if api.find_distro(name=distro_to_delete):
    api.remove_distro(distro_to_delete, save=True)
    print(f"Successfully deleted distribution: {distro_to_delete}")
else:
    print(f"Distribution not found: {distro_to_delete}")

Putting It All Together: A Complete Script

Here is a full, runnable script that demonstrates adding a distribution, profile, and system, and then cleaning them up.

#!/usr/bin/env python3
import cobbler.api as capi
import time
# --- Configuration ---
COBBLER_URL = "http://127.0.0.1"
COBBLER_USER = "cobbler"
COBBLER_PASS = "cobbler"
# Object names to be created and managed
TEST_DISTRO_NAME = "my-test-distro"
TEST_PROFILE_NAME = "my-test-profile"
TEST_SYSTEM_NAME = "my-test-system"
def main():
    """Main function to demonstrate the Cobbler API."""
    try:
        # 1. Connect to the Cobbler API
        print("Connecting to Cobbler API...")
        api = capi.CobblerAPI(COBBLER_URL, COBBLER_USER, COBBLER_PASS)
        print(f"Connected! Cobbler version: {api.get_version()}")
        # 2. Create and Add a Distribution
        # NOTE: For this to work, the kernel/initrd files must exist at the specified paths.
        # We will create a "dummy" distro for demonstration.
        print(f"\n--- Creating Distribution: {TEST_DISTRO_NAME} ---")
        if not api.find_distro(name=TEST_DISTRO_NAME):
            distro = api.new_distro()
            distro.name = TEST_DISTRO_NAME
            distro.kernel = "/path/to/your/kernel" # IMPORTANT: Replace with a real path
            distro.initrd = "/path/to/your/initrd.img" # IMPORTANT: Replace with a real path
            distro.breed = "redhat"
            distro.os_version = "rhel9"
            distro.arch = "x86_64"
            api.add_distro(distro, save=True)
            print(f"Distribution '{TEST_DISTRO_NAME}' added successfully.")
        else:
            print(f"Distribution '{TEST_DISTRO_NAME}' already exists. Skipping creation.")
        # 3. Create and Add a Profile
        print(f"\n--- Creating Profile: {TEST_PROFILE_NAME} ---")
        if not api.find_profile(name=TEST_PROFILE_NAME):
            profile = api.new_profile()
            profile.name = TEST_PROFILE_NAME
            profile.distro = TEST_DISTRO_NAME
            profile.kickstart = "/var/lib/cobbler/kickstarts/sample.ks" # Use a real kickstart
            profile.kernel_options = {"lang": "en_US", "kssendmac": ""}
            api.add_profile(profile, save=True)
            print(f"Profile '{TEST_PROFILE_NAME}' added successfully.")
        else:
            print(f"Profile '{TEST_PROFILE_NAME}' already exists. Skipping creation.")
        # 4. Create and Add a System
        print(f"\n--- Creating System: {TEST_SYSTEM_NAME} ---")
        if not api.find_system(name=TEST_SYSTEM_NAME):
            system = api.new_system()
            system.name = TEST_SYSTEM_NAME
            system.profile = TEST_PROFILE_NAME
            system.hostname = TEST_SYSTEM_NAME + ".localdomain"
            system.interfaces = {
                "eth0": {
                    "macaddress": "AA:BB:CC:DD:EE:FF",
                    "ipaddress": "192.168.1.150",
                    "netmask": "255.255.255.0",
                    "static": True
                }
            }
            api.add_system(system, save=True)
            print(f"System '{TEST_SYSTEM_NAME}' added successfully.")
        else:
            print(f"System '{TEST_SYSTEM_NAME}' already exists. Skipping creation.")
        # 5. Final Sync
        print("\nPerforming a final sync to apply all changes...")
        api.sync()
        print("Sync complete.")
        # Optional: Pause to see the objects in the web UI
        print("\nScript finished. You can check the Cobbler web UI.")
        # time.sleep(30) # Uncomment to pause for 30 seconds
    except capi.CobblerAPIError as e:
        print(f"\nA Cobbler API error occurred: {e}")
    except Exception as e:
        print(f"\nAn unexpected error occurred: {e}")
    finally:
        # 6. Cleanup (Optional)
        # Uncomment the block below to automatically clean up the created objects.
        print("\n--- Cleaning up created objects ---")
        try:
            if api.find_system(name=TEST_SYSTEM_NAME):
                api.remove_system(TEST_SYSTEM_NAME, save=True)
                print(f"Removed system: {TEST_SYSTEM_NAME}")
            if api.find_profile(name=TEST_PROFILE_NAME):
                api.remove_profile(TEST_PROFILE_NAME, save=True)
                print(f"Removed profile: {TEST_PROFILE_NAME}")
            if api.find_distro(name=TEST_DISTRO_NAME):
                api.remove_distro(TEST_DISTRO_NAME, save=True)
                print(f"Removed distribution: {TEST_DISTRO_NAME}")
            api.sync()
            print("Cleanup sync complete.")
        except Exception as e:
            print(f"Error during cleanup: {e}")
if __name__ == "__main__":
    main()

Important Considerations

  • Authentication: The default credentials are weak. For production, you should configure Cobbler to use a more secure authentication method, like Kerberos or by integrating with a central user directory.
  • api.sync(): This is the most important command. It's what makes your changes "live". Forgetting it is a common mistake. It can be resource-intensive on large setups.
  • Error Handling: Always wrap your API calls in try...except blocks. The cobbler.api.CobblerAPIError exception is specific to the API and will give you details about what went wrong (e.g., a missing kickstart file, a name conflict).
  • Idempotency: Good scripts check if an object already exists before trying to create it (as shown in the full example). This makes your scripts safe to run multiple times.
  • Permissions: The user running the script needs the correct permissions to connect to and modify the Cobbler API. This is usually handled by the cobbler user on the server.
分享:
扫描分享到社交APP
上一篇
下一篇