fuel-main/nailgun/provision/driver/cobbler.py
2012-09-20 09:59:09 +00:00

273 lines
10 KiB
Python

# -*- coding: utf-8 -*-
import logging
import xmlrpclib
from itertools import repeat
from provision import ProvisionException
from provision import ProvisionAlreadyExists, ProvisionDoesNotExist
from provision import Provision
class Cobbler(Provision):
def __init__(self, config):
self.logger = logging.getLogger('provision.cobbler')
try:
self.url = config.url
self.user = config.user
self.password = config.password
except AttributeError as e:
self.logger.error(
'Provision configuration error.'
' Not all necessary attributes are set properly.'
)
raise e
self.logger.debug(
'Cobbler config: url="%s", user="%s", password="%s"',
self.url,
self.user,
self.password
)
try:
self.server = xmlrpclib.Server(self.url)
self.token = self.server.login(self.user, self.password)
except ProvisionException as e:
self.logger.error(
'Error occured while connecting to provision server.'
)
raise e
def _get_any_profile(self):
profiles = self.server.get_profiles(self.token)
if profiles:
return profiles[0]
raise ProvisionException("There is no available profiles")
def system_by_name(self, name):
systems = self.server.find_system({'name': name}, self.token)
if systems:
if len(systems) > 1:
err = "There are more than one system"
" found by pattern: %s" % name
self.logger.error(err)
raise ProvisionException(err)
return systems[0]
return None
def update_system(self, name, mac, power, profile, kopts="", create=False):
if create:
if self.system_by_name(name):
err = "System with name %s already exists."
" Try to edit it." % name
self.logger.error(err)
raise ProvisionAlreadyExists(err)
system_id = self.server.new_system(self.token)
else:
if not self.system_by_name(name):
err = "Trying to edit system"
" that does not exist: %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
system_id = self.server.get_system_handle(name, self.token)
fields = {
"name": name,
"profile": profile.name,
"kopts": kopts,
"modify_interface": {
"macaddress-eth0": mac,
},
}
for key, value in fields.iteritems():
self.server.modify_system(
system_id, key, value, self.token
)
if_fields = {
"power_type": power.power_type,
"power_user": power.power_user,
"power_pass": power.power_pass,
"power_id": power.power_id,
"power_address": power.power_address
}
for key, value in if_fields.iteritems():
if value:
self.server.modify_system(
system_id, key, value, self.token
)
self.server.save_system(system_id, self.token)
return self.system_by_name(name)
def power_system(self, name, power):
if not self.system_by_name(name):
err = "Trying to power system"
" that does not exist: %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
if power not in ('on', 'off', 'reboot', 'status'):
raise ValueError("Power has invalid value")
system_id = self.server.get_system_handle(name, self.token)
self.server.power_system(system_id, power, self.token)
return self.system_by_name(name)
def handle_system(self, name, mac, power, profile, kopts=""):
try:
self.update_system(name, mac, power, profile, kopts)
self.logger.info("Edited system: %s" % name)
except ProvisionDoesNotExist:
self.update_system(name, mac, power, profile, kopts, create=True)
self.logger.info("Added system: %s" % name)
def del_system(self, name):
system = self.system_by_name(name)
if not system:
err = "There is no system with name %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
self.server.remove_system(name, self.token)
self.logger.info("Removed system %s" % name)
def profile_by_name(self, name):
profiles = self.server.find_profile({'name': name}, self.token)
if profiles:
if len(profiles) > 1:
err = "There are more than one profile"
" found by pattern: %s" % name
self.logger.error(err)
raise ProvisionException(err)
return profiles[0]
return None
def update_profile(self, name, distro, kickstart, create=False):
if create:
if self.profile_by_name(name):
err = "Trying to add profile that already exists: %s" % name
self.logger.error(err)
raise ProvisionAlreadyExists(err)
profile_id = self.server.new_profile(self.token)
else:
if not self.profile_by_name(name):
err = "Trying to edit profile"
" that does not exist: %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
profile_id = self.server.get_profile_handle(name, self.token)
self.server.modify_profile(profile_id, 'name', name, self.token)
self.server.modify_profile(profile_id, 'distro', distro, self.token)
self.server.modify_profile(
profile_id, 'kickstart', kickstart, self.token
)
self.server.save_profile(profile_id, self.token)
return self.profile_by_name(name)
def handle_profile(self, name, distro, seed):
try:
self.update_profile(name, distro, seed)
self.logger.info("Edited profile: %s" % name)
except ProvisionDoesNotExist:
self.update_profile(name, distro, seed, create=True)
self.logger.info("Added profile: %s" % name)
def del_profile(self, name):
profile = self.profile_by_name(name)
if not profile:
err = "Trying to remove profile that does not exist: %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
self.server.remove_profile(name, self.token)
self.logger.info("Removed profile: %s" % name)
def distro_by_name(self, name):
distros = self.server.find_distro({'name': name}, self.token)
if distros:
if len(distros) > 1:
err = "There are more than one distro"
" found by pattern: %s" % name
self.logger.error(err)
raise ProvisionException(err)
return distros[0]
return None
def update_distro(
self, name, kernel, initrd, arch, breed, osversion,
create=False):
if create:
if self.distro_by_name(name):
err = "Trying to add distro that already exists: %s" % name
self.logger.error(err)
raise ProvisionAlreadyExists(err)
distro_id = self.server.new_distro(self.token)
else:
if not self.distro_by_name(name):
err = "Trying to edit distro"
" that does not exist: %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
distro_id = self.server.get_distro_handle(name, self.token)
self.server.modify_distro(distro_id, 'name', name, self.token)
self.server.modify_distro(distro_id, 'kernel', kernel, self.token)
self.server.modify_distro(distro_id, 'initrd', initrd, self.token)
self.server.modify_distro(distro_id, 'arch', arch, self.token)
self.server.modify_distro(distro_id, 'breed', breed, self.token)
self.server.modify_distro(
distro_id, 'os_version', osversion, self.token
)
self.server.save_distro(distro_id, self.token)
return self.distro_by_name(name)
def handle_distro(self, name, kernel, initrd, arch, os, osversion):
try:
self.update_distro(name, kernel, initrd, arch, os, osversion)
self.logger.info("Edited distro: %s" % name)
except ProvisionDoesNotExist:
self.update_distro(
name, kernel, initrd, arch, os, osversion, create=True
)
self.logger.info("Added distro: %s" % name)
def del_distro(self, name):
distro = self.distro_by_name(name)
if not distro:
err = "Trying to remove distro"
" that does not exist: %s" % name
self.logger.error(err)
raise ProvisionDoesNotExist(err)
self.server.remove_distro(name, self.token)
self.logger.info("Removed distro %s" % name)
# API
def save_profile(self, profile):
self.handle_distro(profile.name,
profile.kernel,
profile.initrd,
profile.arch,
profile.os,
profile.osversion)
self.handle_profile(profile.name,
profile.name,
profile.seed)
def save_node(self, node):
self.handle_system(node.name,
node.mac,
node.power,
node.profile,
node.kopts,
)
def power_on(self, node):
self.power_system(node.name, 'on')
def power_off(self, node):
self.power_system(node.name, 'off')
def power_reboot(self, node):
self.power_system(node.name, 'reboot')
def power_status(self, node):
raise NotImplementedError