175 lines
6.2 KiB
Python
175 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2014 Mirantis, Inc.
|
|
#
|
|
# 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.
|
|
|
|
import glob
|
|
import os
|
|
|
|
from fuel_upgrade.clients import SupervisorClient
|
|
from fuel_upgrade.engines.base import UpgradeEngine
|
|
from fuel_upgrade import utils
|
|
|
|
|
|
class HostSystemUpgrader(UpgradeEngine):
|
|
"""Upgrader for master node host system.
|
|
|
|
Required for upgrading of packages which
|
|
are not under docker, for example fuelclient,
|
|
dockerctl.
|
|
|
|
* add local repo with new packages
|
|
* run puppet apply
|
|
"""
|
|
|
|
templates_dir = os.path.abspath(
|
|
os.path.join(os.path.dirname(__file__), '../templates'))
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(HostSystemUpgrader, self).__init__(*args, **kwargs)
|
|
|
|
#: host system upgarder specific configs
|
|
self.host_system_config = self.config.host_system
|
|
|
|
#: path to puppet manifests
|
|
self.manifest_path = self.host_system_config['manifest_path']
|
|
|
|
#: path to puppet modules
|
|
self.puppet_modules_path = self.host_system_config[
|
|
'puppet_modules_path']
|
|
|
|
#: path to repo template
|
|
self.repo_template_path = os.path.join(
|
|
self.templates_dir, 'nailgun.repo')
|
|
|
|
#: new version of fuel
|
|
self.version = self.config.new_version
|
|
|
|
#: path to repository config
|
|
self.repo_config_path = self.host_system_config['repo_config_path']
|
|
|
|
#: packages to be installed before running puppet
|
|
self.packages = self.host_system_config['install_packages']
|
|
|
|
self.supervisor = SupervisorClient(
|
|
self.config, self.config.from_version)
|
|
|
|
@property
|
|
def required_free_space(self):
|
|
"""Required free space to run upgrade
|
|
|
|
Requires a lot of disk spaces for new repos and repo config.
|
|
|
|
:returns: dict where key is path to directory
|
|
and value is required free space in megabytes
|
|
"""
|
|
sources = glob.glob(self.host_system_config['repos']['src'])
|
|
repos_size = sum(map(utils.dir_size, sources))
|
|
|
|
return {
|
|
self.host_system_config['repos']['dst']: repos_size,
|
|
self.repo_config_path: 10,
|
|
}
|
|
|
|
def upgrade(self):
|
|
"""Run host system upgrade process"""
|
|
# The workaround we need in order to fix [1]. In few words,
|
|
# when new Docker is installed the containers MUST NOT start
|
|
# again because in this case puppet inside them will install
|
|
# latest packages and breaks dependencies in some soft.
|
|
#
|
|
# [1]: https://bugs.launchpad.net/fuel/+bug/1455419
|
|
self.supervisor.stop_all_services()
|
|
|
|
# The workaround we need in order to fix [1]. In few words,
|
|
# when the repositories is being installed, auxiliary repo is removed,
|
|
# the config should be removed as well.
|
|
#
|
|
# [1]: https://bugs.launchpad.net/fuel/+bug/1495481
|
|
self.remove_repo_config()
|
|
self.install_repos()
|
|
self.update_repo()
|
|
self.install_packages()
|
|
self.run_puppet()
|
|
|
|
def rollback(self):
|
|
"""The only thing which we can rollback here is yum config"""
|
|
self.remove_repo_config()
|
|
self.remove_repos()
|
|
|
|
self.supervisor.start_all_services()
|
|
|
|
def install_repos(self):
|
|
sources = glob.glob(self.host_system_config['repos']['src'])
|
|
for source in sources:
|
|
destination = os.path.join(
|
|
self.host_system_config['repos']['dst'],
|
|
os.path.basename(source))
|
|
utils.copy(source, destination)
|
|
|
|
def remove_repos(self):
|
|
sources = glob.glob(self.host_system_config['repos']['src'])
|
|
for source in sources:
|
|
destination = os.path.join(
|
|
self.host_system_config['repos']['dst'],
|
|
os.path.basename(source))
|
|
utils.remove(destination)
|
|
|
|
def update_repo(self):
|
|
"""Add new centos repository"""
|
|
utils.render_template_to_file(
|
|
self.repo_template_path,
|
|
self.repo_config_path,
|
|
{
|
|
'name': '{0}_nailgun'.format(self.version),
|
|
'baseurl': self.host_system_config['repo_master'],
|
|
'gpgcheck': 0,
|
|
'skip_if_unavailable': 0,
|
|
})
|
|
utils.exec_cmd('yum clean all')
|
|
|
|
def install_packages(self):
|
|
"""Install packages for new release"""
|
|
for package in self.packages:
|
|
utils.exec_cmd('yum install -v -y {0}'.format(package))
|
|
|
|
def run_puppet(self):
|
|
"""Run puppet to upgrade host system"""
|
|
utils.exec_cmd(
|
|
'puppet apply -d -v '
|
|
'{0} --modulepath={1}'.format(
|
|
self.manifest_path, self.puppet_modules_path))
|
|
|
|
def remove_repo_config(self):
|
|
"""Remove yum repository config"""
|
|
utils.remove_if_exists(self.repo_config_path)
|
|
|
|
# One more damn hack! We have to remove auxiliary repo config
|
|
# if we're rollbacking to the Fuel version that doesn't have
|
|
# auxiliary repo at all.
|
|
if utils.compare_version(self.config.from_version, '6.1') > 0:
|
|
utils.remove_if_exists(
|
|
self.host_system_config['repo_aux_config_path'])
|
|
else:
|
|
# By some pity reason we're managing auxiliary repo in puppet
|
|
# manifests, but there's no management code for rollbacking.
|
|
# Therefore, we need to clean-up its artifacts in case of
|
|
# upgrade rollback procedure here; otherwise another try
|
|
# of upgrade will fail.
|
|
path, name = os.path.split(
|
|
self.host_system_config['repo_aux_config_path'])
|
|
utils.remove_if_exists(os.path.join(path, '{0}_{1}'.format(
|
|
self.config.new_version,
|
|
name)))
|