summaryrefslogtreecommitdiffstats
path: root/compass-tasks/deployment/installers/os_installers/cobbler/cobbler.py
diff options
context:
space:
mode:
Diffstat (limited to 'compass-tasks/deployment/installers/os_installers/cobbler/cobbler.py')
-rw-r--r--compass-tasks/deployment/installers/os_installers/cobbler/cobbler.py449
1 files changed, 0 insertions, 449 deletions
diff --git a/compass-tasks/deployment/installers/os_installers/cobbler/cobbler.py b/compass-tasks/deployment/installers/os_installers/cobbler/cobbler.py
deleted file mode 100644
index 9c2a935..0000000
--- a/compass-tasks/deployment/installers/os_installers/cobbler/cobbler.py
+++ /dev/null
@@ -1,449 +0,0 @@
-# Copyright 2014 Huawei Technologies Co. Ltd
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""os installer cobbler plugin.
-"""
-import logging
-import os
-import shutil
-import xmlrpclib
-
-from compass.deployment.installers.installer import OSInstaller
-from compass.deployment.utils import constants as const
-from compass.utils import setting_wrapper as compass_setting
-from compass.utils import util
-from copy import deepcopy
-
-
-NAME = 'CobblerInstaller'
-
-
-class CobblerInstaller(OSInstaller):
- """cobbler installer"""
- CREDENTIALS = "credentials"
- USERNAME = 'username'
- PASSWORD = 'password'
-
- INSTALLER_URL = "cobbler_url"
- TMPL_DIR = 'tmpl_dir'
- SYS_TMPL = 'system.tmpl'
- SYS_TMPL_NAME = 'system.tmpl'
- SYS_PROFILE_NAME = 'profile.tmpl'
- PROFILE = 'profile'
-
- POWER_TYPE = 'power_type'
- POWER_ADDR = 'power_address'
- POWER_USER = 'power_user'
- POWER_PASS = 'power_pass'
-
- def __init__(self, config_manager):
- super(CobblerInstaller, self).__init__()
-
- self.config_manager = config_manager
- installer_settings = self.config_manager.get_os_installer_settings()
- try:
- username = installer_settings[self.CREDENTIALS][self.USERNAME]
- password = installer_settings[self.CREDENTIALS][self.PASSWORD]
- cobbler_url = installer_settings[self.INSTALLER_URL]
- self.tmpl_dir = CobblerInstaller.get_tmpl_path()
-
- except KeyError as ex:
- raise KeyError(ex.message)
-
- # The connection is created when cobbler installer is initialized.
- self.remote = self._get_cobbler_server(cobbler_url)
- self.token = self._get_token(username, password)
- self.pk_installer_config = None
-
- logging.debug('%s instance created', 'CobblerInstaller')
-
- @classmethod
- def get_tmpl_path(cls):
- return os.path.join(compass_setting.TMPL_DIR, 'cobbler')
-
- def __repr__(self):
- return '%r[remote=%r,token=%r' % (
- self.__class__.__name__, self.remote, self.token)
-
- def _get_cobbler_server(self, cobbler_url):
- if not cobbler_url:
- logging.error("Cobbler URL is None!")
- raise Exception("Cobbler URL cannot be None!")
-
- return xmlrpclib.Server(cobbler_url)
-
- def _get_token(self, username, password):
- if self.remote is None:
- raise Exception("Cobbler remote instance is None!")
- return self.remote.login(username, password)
-
- def get_supported_oses(self):
- """get supported os versions.
-
- note::
- In cobbler, we treat profile name as the indicator
- of os version. It is just a simple indicator
- and not accurate.
- """
- profiles = self.remote.get_profiles()
- oses = []
- for profile in profiles:
- oses.append(profile['name'])
- return oses
-
- def deploy(self):
- """Sync cobbler to catch up the latest update config and start to
-
- install OS. Return both cluster and hosts deploy configs. The return
- format:
- {
- "cluster": {
- "id": 1,
- "deployed_os_config": {},
- },
- "hosts": {
- 1($clusterhost_id): {
- "deployed_os_config": {...},
- },
- ....
- }
- }
- """
- host_ids = self.config_manager.get_hosts_id_list_for_os_installation()
- if not host_ids:
- # No hosts need to install OS
- logging.info("Cobbler: No host needs to install OS.")
- return {}
-
- os_version = self.config_manager.get_os_version()
- profile = self._get_profile_from_server(os_version)
-
- global_vars_dict = self._get_cluster_tmpl_vars_dict()
-
- self.update_profile_config_to_cobbler(profile, global_vars_dict)
-
- hosts_deploy_config = {}
-
- for host_id in host_ids:
- hostname = self.config_manager.get_hostname(host_id)
- vars_dict = self._get_host_tmpl_vars_dict(host_id,
- global_vars_dict,
- hostname=hostname,
- profile=profile)
-
- self.update_host_config_to_cobbler(host_id, hostname, vars_dict)
-
- # set host deploy config
- host_config = {}
- host_config[const.DEPLOYED_OS_CONFIG] = vars_dict[const.OS_CONFIG]
- hosts_deploy_config[host_id] = host_config
-
- # sync to cobbler and trigger installtion.
- self._sync()
-
- cluster_config = global_vars_dict.setdefault(const.OS_CONFIG, {})
-
- return {
- const.CLUSTER: {
- const.ID: self.config_manager.get_cluster_id(),
- const.DEPLOYED_OS_CONFIG: cluster_config
- },
- const.HOSTS: hosts_deploy_config
- }
-
- def clean_progress(self):
- """clean log files and config for hosts which to deploy."""
- clusterhost_list = self.config_manager.get_host_id_list()
- log_dir_prefix = compass_setting.INSTALLATION_LOGDIR[NAME]
-
- for host_id in clusterhost_list:
- hostname = self.config_manager.get_hostname(host_id)
- self._clean_log(log_dir_prefix, hostname)
-
- def redeploy(self):
- """redeploy hosts."""
- host_ids = self.config_manager.get_host_id_list()
- if not host_ids:
- logging.info("Cobbler: hostlist is None, no host is redeployed")
- return
- for host_id in host_ids:
- hostname = self.config_manager.get_hostname(host_id)
- sys_id = self._get_create_system(hostname)
- if sys_id:
- # enable netboot for this host
- self._netboot_enabled(sys_id)
-
- self._sync()
-
- def set_package_installer_config(self, package_configs):
- """Cobbler can install and configure package installer right after
-
- OS installation compelets by setting package_config info provided
- by package installer.
-
- :param dict package_configs: The dict of config generated by package
- installer for each clusterhost. The IDs
- of clusterhosts are the keys of
- package_configs.
- """
- self.pk_installer_config = package_configs
-
- def _sync(self):
- """Sync the updated config to cobbler and trigger installation."""
- try:
- self.remote.sync(self.token)
- os.system('sudo service rsyslog restart')
- except Exception as ex:
- logging.debug("Failed to sync cobbler server! Error: %s" % ex)
- raise ex
-
- def dump_system_info(self, host_id):
-
- hostname = self.config_manager.get_hostname(host_id)
- if self.remote is None or not hostname:
- logging.info("[dump_system_info]Remote or hostname is None.")
- return {}
-
- return self.remote.get_system_as_rendered(hostname)
-
- def _generate_system_config(self, host_id, host_vars_dict):
- """Generate updated system config from the template.
-
- :param host_vars_dict: dict of variables for the system template to
- generate system config dict for each host.
- """
- os_version = self.config_manager.get_os_version()
-
- tmpl_path = os.path.join(
- os.path.join(self.tmpl_dir, os_version), self.SYS_TMPL_NAME
- )
- if not os.path.exists(tmpl_path):
- err_msg = "Template '%s' does not exists!" % tmpl_path
- logging.error(err_msg)
- raise Exception(err_msg)
- host_vars_dict[const.BASEINFO]['host_id'] = host_id
- system_config = self.get_config_from_template(tmpl_path,
- host_vars_dict)
-
- # update package config info to cobbler ksmeta
- if self.pk_installer_config and host_id in self.pk_installer_config:
- pk_config = self.pk_installer_config[host_id]
- ksmeta = system_config.setdefault("ksmeta", {})
- util.merge_dict(ksmeta, pk_config)
- system_config["ksmeta"] = ksmeta
-
- return system_config
-
- def _generate_profile_config(self, cluster_vars_dict):
- os_version = self.config_manager.get_os_version()
- tmpl_path = os.path.join(
- os.path.join(self.tmpl_dir, os_version), self.SYS_PROFILE_NAME
- )
-
- return self.get_config_from_template(tmpl_path, cluster_vars_dict)
-
- def _get_profile_from_server(self, os_version):
- """Get profile from cobbler server."""
- result = self.remote.find_profile({'name': os_version})
- if not result:
- raise Exception("Cannot find profile for '%s'", os_version)
-
- profile = result[0]
- return profile
-
- def _get_create_system(self, hostname):
- """get system reference id for the host."""
- sys_name = hostname
- sys_id = None
- system_info = self.remote.find_system({"name": hostname})
-
- if not system_info:
- # Create a new system
- sys_id = self.remote.new_system(self.token)
- self.remote.modify_system(sys_id, "name", hostname, self.token)
- logging.debug('create new system %s for %s', sys_id, sys_name)
- else:
- sys_id = self.remote.get_system_handle(sys_name, self.token)
-
- return sys_id
-
- def _get_profile_id(self, profilename):
- """get profile reference id for the cluster."""
- return self.remote.get_profile_handle(profilename, self.token)
-
- def _clean_system(self, hostname):
- """clean system."""
- sys_name = hostname
- try:
- self.remote.remove_system(sys_name, self.token)
- logging.debug('system %s is removed', sys_name)
- except Exception:
- logging.debug('no system %s found to remove', sys_name)
-
- def _update_system_config(self, sys_id, system_config):
- """update modify system."""
- for key, value in system_config.iteritems():
- self.remote.modify_system(sys_id, str(key), value, self.token)
-
- self.remote.save_system(sys_id, self.token)
-
- def _update_profile_config(self, profile_id, profile_config):
- for key, value in profile_config.iteritems():
- self.remote.modify_profile(profile_id, str(key), value, self.token)
-
- self.remote.save_profile(profile_id, self.token)
-
- def _netboot_enabled(self, sys_id):
- """enable netboot."""
- self.remote.modify_system(sys_id, 'netboot_enabled', True, self.token)
- self.remote.save_system(sys_id, self.token)
-
- def _clean_log(self, log_dir_prefix, system_name):
- """clean log."""
- log_dir = os.path.join(log_dir_prefix, system_name)
- shutil.rmtree(log_dir, True)
-
- def update_host_config_to_cobbler(self, host_id, hostname, host_vars_dict):
- """update host config and upload to cobbler server."""
- sys_id = self._get_create_system(hostname)
-
- system_config = self._generate_system_config(host_id, host_vars_dict)
- logging.debug('%s system config to update: %s', host_id, system_config)
-
- self._update_system_config(sys_id, system_config)
- self._netboot_enabled(sys_id)
-
- def update_profile_config_to_cobbler(self, profilename, cluster_vars_dict):
- """update profile config and upload to cobbler server."""
-
- profile_id = self._get_profile_id(profilename)
-
- profile_config = self._generate_profile_config(cluster_vars_dict)
- logging.debug(
- '%s profile config to update: %s', profilename, profile_config
- )
-
- self._update_profile_config(profile_id, profile_config)
-
- def delete_hosts(self):
- hosts_id_list = self.config_manager.get_host_id_list()
- logging.debug('delete hosts %s', hosts_id_list)
- for host_id in hosts_id_list:
- self.delete_single_host(host_id)
- self._sync()
-
- def delete_single_host(self, host_id):
- """Delete the host from cobbler server and clean up the installation
-
- progress.
- """
- hostname = self.config_manager.get_hostname(host_id)
- try:
- log_dir_prefix = compass_setting.INSTALLATION_LOGDIR[NAME]
- self._clean_system(hostname)
- self._clean_log(log_dir_prefix, hostname)
- except Exception as ex:
- logging.error("Deleting host got exception: %s", ex)
- logging.exception(ex)
-
- def _get_host_tmpl_vars_dict(self, host_id, global_vars_dict, **kwargs):
- """Generate template variables dictionary."""
- vars_dict = {}
- if global_vars_dict:
- # Set cluster template vars_dict from cluster os_config.
- vars_dict = deepcopy(global_vars_dict)
-
- # Set hostname, MAC address and hostname, networks, dns and so on.
- host_baseinfo = self.config_manager.get_host_baseinfo(host_id)
- vars_dict[const.BASEINFO] = host_baseinfo
-
- # Set profile
- if self.PROFILE in kwargs:
- profile = kwargs[self.PROFILE]
- else:
- os_version = self.config_manager.get_os_version()
- profile = self._get_profile_from_server(os_version)
-
- vars_dict[const.BASEINFO][self.PROFILE] = profile
-
- metadata = self.config_manager.get_os_config_metadata()
- os_config = self.config_manager.get_host_os_config(host_id)
-
- # Get template variables values from host os_config
- host_vars_dict = self.get_tmpl_vars_from_metadata(metadata, os_config)
- util.merge_dict(
- vars_dict.setdefault(const.OS_CONFIG, {}), host_vars_dict
- )
- return vars_dict
-
- def _get_cluster_tmpl_vars_dict(self):
- metadata = self.config_manager.get_os_config_metadata()
- os_config = self.config_manager.get_cluster_os_config()
-
- cluster_vas_dict = {}
- cluster_vas_dict[const.OS_CONFIG] = \
- self.get_tmpl_vars_from_metadata(metadata, os_config)
-
- return cluster_vas_dict
-
- def _check_and_set_system_impi(self, host_id, sys_id):
- if not sys_id:
- logging.info("System is None!")
- return False
-
- system = self.dump_system_info(host_id)
- if system[self.POWER_TYPE] != 'ipmilan' or not system[self.POWER_USER]:
- # Set sytem power type to ipmilan if needs and set IPMI info
- ipmi_info = self.config_manager.get_host_ipmi_info(host_id)
- if not ipmi_info:
- logging.info('No IPMI information found! Failed power on.')
- return False
-
- ipmi_ip, ipmi_user, ipmi_pass = ipmi_info
- power_opts = {}
- power_opts[self.POWER_TYPE] = 'ipmilan'
- power_opts[self.POWER_ADDR] = ipmi_ip
- power_opts[self.POWER_USER] = ipmi_user
- power_opts[self.POWER_PASS] = ipmi_pass
-
- self._update_system_config(sys_id, power_opts)
-
- return True
-
- def poweron(self, host_id):
- hostname = self.config_manager.get_hostname(host_id)
- sys_id = self._get_create_system(hostname)
- if not self._check_and_set_system_impi(sys_id):
- return
-
- self.remote.power_system(sys_id, self.token, power='on')
- logging.info("Host with ID=%d starts to power on!" % host_id)
-
- def poweroff(self, host_id):
- hostname = self.config_manager.get_hostname(host_id)
- sys_id = self._get_create_system(hostname)
- if not self._check_and_set_system_impi(sys_id):
- return
-
- self.remote.power_system(sys_id, self.token, power='off')
- logging.info("Host with ID=%d starts to power off!" % host_id)
-
- def reset(self, host_id):
- hostname = self.config_manager.get_hostname(host_id)
- sys_id = self._get_create_system(hostname)
- if not self._check_and_set_system_impi(sys_id):
- return
-
- self.remote.power_system(sys_id, self.token, power='reboot')
- logging.info("Host with ID=%d starts to reboot!" % host_id)