Merge "Improves EPEL and RDO repo setup"

This commit is contained in:
Jenkins
2013-10-23 04:49:23 +00:00
committed by Gerrit Code Review
9 changed files with 165 additions and 84 deletions

View File

@@ -587,7 +587,7 @@ def remove_remote_var_dirs():
""" """
for host in gethostlist(controller.CONF): for host in gethostlist(controller.CONF):
try: try:
host_dir = controller.temp_map[host] host_dir = controller.CONF['HOST_DETAILS'][host]['tmpdir']
except KeyError: except KeyError:
# Nothing was added to this host yet, so we have nothing to delete # Nothing was added to this host yet, so we have nothing to delete
continue continue

View File

@@ -36,17 +36,11 @@ class Controller(object):
return self.__single return self.__single
def __init__(self): def __init__(self):
# XXX: Right now this will only hold all temp dirs on each host.
# Method for temp dir creation should be implemented in this
# class, when it will start behaving like controller and not
# only like data container
self.temp_map = {}
# Resources that should be copied to each host along with the puppet # Resources that should be copied to each host along with the puppet
# files, on the remote host the file will be placed in # files, on the remote host the file will be placed in
# $PACKSTACK_VAR_DIR/resources. As with temp_map, this controller # $PACKSTACK_VAR_DIR/resources. This controller should copy the files,
# should copy the files, for now the puppet plugin is doing it # for now the puppet plugin is doing it format
# format {'host':[('/path/to/fileordirectory', 'filenameonremotehost'), ..]} # {'host':[('/path/to/fileordirectory', 'filenameonremotehost'), ..]}
self.resources = {} self.resources = {}

View File

@@ -15,6 +15,8 @@ def filtered_hosts(config, exclude=True, dbhost=True):
result = set() result = set()
dbinst = config.get('CONFIG_MYSQL_INSTALL') == 'y' dbinst = config.get('CONFIG_MYSQL_INSTALL') == 'y'
for hosttype, hostname in utils.host_iter(config): for hosttype, hostname in utils.host_iter(config):
# if dbhost is being taken into account and we are not installing MySQL
# then we should omit the MySQL host
if dbhost and not dbinst and hosttype == 'CONFIG_MYSQL_HOST': if dbhost and not dbinst and hosttype == 'CONFIG_MYSQL_HOST':
continue continue
result.add(hostname) result.add(hostname)
@@ -28,4 +30,7 @@ def is_all_in_one(config):
Returns True if packstack is running allinone setup, otherwise Returns True if packstack is running allinone setup, otherwise
returns False. returns False.
""" """
return len(filtered_hosts(config, exclude=False)) == 1 # Even if some host have been excluded from installation, we must count
# with them when checking all-in-one. MySQL host should however be omitted
# if we are not installing MySQL
return len(filtered_hosts(config, exclude=False, dbhost=True)) == 1

View File

@@ -279,6 +279,11 @@ def disable_nm(config):
def discover(config): def discover(config):
"""
Discovers details about hosts.
"""
# TODO: Once Controller is refactored, move this function to it (facter can
# be used for that too).
details = {} details = {}
release_regexp = re.compile(r'^(?P<OS>.*) release (?P<release>[\d\.]*)') release_regexp = re.compile(r'^(?P<OS>.*) release (?P<release>[\d\.]*)')
for host in filtered_hosts(config): for host in filtered_hosts(config):
@@ -303,6 +308,18 @@ def discover(config):
opsys = re.sub(pattern, surr, opsys) opsys = re.sub(pattern, surr, opsys)
details[host]['os'] = opsys details[host]['os'] = opsys
details[host]['release'] = match.group('release') details[host]['release'] = match.group('release')
# Create the packstack tmp directory
server.clear()
server.append("mkdir -p %s" % basedefs.PACKSTACK_VAR_DIR)
# Separately create the tmp directory for this packstack run, this will
# fail if the directory already exists
host_dir = os.path.join(basedefs.PACKSTACK_VAR_DIR, uuid.uuid4().hex)
server.append("mkdir --mode 0700 %s" % host_dir)
for i in ('modules', 'resources'):
server.append("mkdir --mode 0700 %s" % os.path.join(host_dir, i))
server.execute()
details[host]['tmpdir'] = host_dir
config['HOST_DETAILS'] = details config['HOST_DETAILS'] = details

View File

@@ -92,7 +92,7 @@ def copyPuppetModules(config):
server = utils.ScriptRunner() server = utils.ScriptRunner()
for hostname in filtered_hosts(config): for hostname in filtered_hosts(config):
host_dir = controller.temp_map[hostname] host_dir = config['HOST_DETAILS'][hostname]['tmpdir']
server.append("cd %s/puppet" % basedefs.DIR_PROJECT_DIR) server.append("cd %s/puppet" % basedefs.DIR_PROJECT_DIR)
# copy Packstack facts # copy Packstack facts
server.append("tar --dereference -cpzf - facts | " server.append("tar --dereference -cpzf - facts | "
@@ -186,11 +186,11 @@ def applyPuppetManifest(config):
if "%s_" % hostname not in manifest: if "%s_" % hostname not in manifest:
continue continue
host_dir = controller.temp_map[hostname] host_dir = config['HOST_DETAILS'][hostname]['tmpdir']
print "Applying " + manifest print "Applying " + manifest
server = utils.ScriptRunner(hostname) server = utils.ScriptRunner(hostname)
man_path = os.path.join(controller.temp_map[hostname], man_path = os.path.join(config['HOST_DETAILS'][hostname]['tmpdir'],
basedefs.PUPPET_MANIFEST_RELATIVE, basedefs.PUPPET_MANIFEST_RELATIVE,
manifest) manifest)

View File

@@ -3,6 +3,7 @@ prepare server
""" """
import os import os
import re
import uuid import uuid
import logging import logging
import platform import platform
@@ -12,7 +13,7 @@ from packstack.installer import exceptions
from packstack.installer import utils from packstack.installer import utils
from packstack.installer import validators from packstack.installer import validators
from packstack.modules.common import filtered_hosts from packstack.modules.common import filtered_hosts, is_all_in_one
# Controller object will be initialized from main flow # Controller object will be initialized from main flow
controller = None controller = None
@@ -242,7 +243,8 @@ def initConfig(controllerObject):
"POST_CONDITION_MATCH" : True}, "POST_CONDITION_MATCH" : True},
] ]
if is_rhel(): if ((is_all_in_one(controller.CONF) and is_rhel()) or
not is_all_in_one(controller.CONF)):
conf_groups.append({"GROUP_NAME" : "RHEL", conf_groups.append({"GROUP_NAME" : "RHEL",
"DESCRIPTION" : "RHEL config", "DESCRIPTION" : "RHEL config",
"PRE_CONDITION" : lambda x: 'yes', "PRE_CONDITION" : lambda x: 'yes',
@@ -365,6 +367,87 @@ def run_rhsm_reg(host, username, password, beta):
server.execute(maskList=[password]) server.execute(maskList=[password])
def manage_epel(host, config):
"""
Installs and/or enables EPEL repo if it is required or disables it if it
is not required.
"""
mirrors = ('https://mirrors.fedoraproject.org/metalink?repo=epel-6&'
'arch=$basearch')
server = utils.ScriptRunner(host)
if (config['CONFIG_USE_EPEL'] == 'y' and
config['HOST_DETAILS'][host]['os'] != 'Fedora'):
server.append('REPOFILE=$(mktemp)')
server.append('cat /etc/yum.conf > $REPOFILE')
server.append("echo -e '[packstack-epel]\nname=packstack-epel\n"
"enabled=1\nmirrorlist=%(mirrors)s' >> $REPOFILE"
% locals())
server.append('( rpm -q epel-release ||'
' yum install -y --nogpg -c $REPOFILE epel-release ) '
'|| true')
server.append('rm -rf $REPOFILE')
try:
server.execute()
except exceptions.ScriptRuntimeError as ex:
msg = 'Failed to set EPEL repo on host %s:\n%s' % (host, ex)
raise exceptions.ScriptRuntimeError(msg)
if config['CONFIG_USE_EPEL'] == 'y':
cmd = 'enable'
enabled = '(1|True)'
else:
cmd = 'disable'
enabled = '(0|False)'
server.clear()
server.append('yum-config-manager --%(cmd)s epel' % locals())
# yum-config-manager returns 0 always, but returns current setup if succeeds
rc, out = server.execute()
match = re.search('enabled\s*\=\s*%(enabled)s' % locals(), out)
if not match:
msg = ('Failed to set EPEL repo on host %s:\nRPM file seems to be '
'installed, but appropriate repo file is probably missing '
'in /etc/yum.repos.d/' % host)
raise exceptions.ScriptRuntimeError(msg)
def manage_rdo(host, config):
"""
Installs and enables RDO repo on host in case it is installed locally.
"""
try:
cmd = "rpm -q rdo-release --qf='%{version}-%{release}.%{arch}\n'"
rc, out = utils.execute(cmd, use_shell=True)
except exceptions.ExecuteRuntimeError:
# RDO repo is not installed, so we don't need to continue
return
match = re.match(r'^(?P<version>\w+)\-(?P<release>\d+\.[\d\w]+)\n', out)
version, release = match.group('version'), match.group('release')
rdo_url = ("http://rdo.fedorapeople.org/openstack/openstack-%(version)s/"
"rdo-release-%(version)s-%(release)s.rpm" % locals())
server = utils.ScriptRunner(host)
server.append("(rpm -q 'rdo-release-%(version)s' ||"
" yum install -y --nogpg %(rdo_url)s) || true"
% locals())
try:
server.execute()
except exceptions.ScriptRuntimeError as ex:
msg = 'Failed to set RDO repo on host %s:\n%s' % (host, ex)
raise exceptions.ScriptRuntimeError(msg)
reponame = 'openstack-%s' % version
server.clear()
server.append('yum-config-manager --enable %(reponame)s' % locals())
# yum-config-manager returns 0 always, but returns current setup if succeeds
rc, out = server.execute()
match = re.search('enabled\s*=\s*(1|True)', out)
if not match:
msg = ('Failed to set RDO repo on host %s:\nRPM file seems to be '
'installed, but appropriate repo file is probably missing '
'in /etc/yum.repos.d/' % host)
raise exceptions.ScriptRuntimeError(msg)
def initSequences(controller): def initSequences(controller):
preparesteps = [ preparesteps = [
{'title': 'Preparing servers', 'functions':[serverprep]} {'title': 'Preparing servers', 'functions':[serverprep]}
@@ -400,7 +483,8 @@ def serverprep(config):
for hostname in filtered_hosts(config): for hostname in filtered_hosts(config):
# Subscribe to Red Hat Repositories if configured # Subscribe to Red Hat Repositories if configured
if rh_username: if rh_username:
run_rhsm_reg(hostname, rh_username, rh_password, config["CONFIG_RH_BETA_REPO"] == 'y') run_rhsm_reg(hostname, rh_username, rh_password,
config["CONFIG_RH_BETA_REPO"] == 'y')
# Subscribe to RHN Satellite if configured # Subscribe to RHN Satellite if configured
if sat_url and hostname not in sat_registered: if sat_url and hostname not in sat_registered:
@@ -408,58 +492,33 @@ def serverprep(config):
sat_registered.add(hostname) sat_registered.add(hostname)
server = utils.ScriptRunner(hostname) server = utils.ScriptRunner(hostname)
server.append('rpm -q --whatprovides yum-utils || '
'yum install -y yum-utils')
server.execute()
# install epel if on rhel (or popular derivative thereof) and epel is configured # enable or disable EPEL according to configuration
if config["CONFIG_USE_EPEL"] == 'y': manage_epel(hostname, config)
server.append("REPOFILE=$(mktemp)") # enable RDO if it is installed locally
server.append("cat /etc/yum.conf > $REPOFILE") manage_rdo(hostname, config)
server.append("echo -e '[packstack-epel]\nname=packstack-epel\n"
"enabled=1\n"
"mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch'"
">> $REPOFILE")
server.append("grep -e 'Red Hat Enterprise Linux' -e 'CentOS' -e 'Scientific Linux' /etc/redhat-release && " reponame = 'rhel-server-ost-6-4-rpms'
"( rpm -q epel-release || yum install -y --nogpg -c $REPOFILE epel-release ) || echo -n ''") server.clear()
server.append("rm -rf $REPOFILE") server.append('yum install -y yum-plugin-priorities || true')
# TO-DO: enable this once we will have RHN channel for Havana
#server.append('rpm -q epel-release && yum-config-manager '
# set highest priority of RHOS repository if EPEL is installed and # '--setopt="%(reponame)s.priority=1" '
# the repo rhel-server-ost-6-folsom-rpms exists in redhat.repo # '--save %(reponame)s' % locals())
# If RHOS has been installed we can diable EPEL when installing openstack-utils
yum_opts = ""
if rh_username:
yum_opts += "--disablerepo='epel*'"
server.append("rpm -q epel-release && "
"yum install -y %s openstack-utils yum-plugin-priorities || true" % yum_opts)
subs_cmd = ('rpm -q epel-release && '
'grep %(repo)s %(repo_file)s && '
'openstack-config --set %(repo_file)s %(repo)s priority %(priority)s || true')
server.append(subs_cmd % {"repo_file": "/etc/yum.repos.d/redhat.repo",
"repo": "rhel-server-ost-6-folsom-rpms",
"priority": 1})
# Create the packstack tmp directory
if hostname not in controller.temp_map:
# TO-DO: Move this to packstack.installer.setup_controller
server.append("mkdir -p %s" % basedefs.PACKSTACK_VAR_DIR)
# Separately create the tmp directory for this packstack run, this will fail if
# the directory already exists
host_dir = os.path.join(basedefs.PACKSTACK_VAR_DIR, uuid.uuid4().hex)
server.append("mkdir --mode 0700 %s" % host_dir)
server.append("mkdir %s/resources" % host_dir)
server.append("mkdir --mode 0700 %s" %
os.path.join(host_dir, 'modules'))
controller.temp_map[hostname] = host_dir
# Add yum repositories if configured # Add yum repositories if configured
CONFIG_REPO = config["CONFIG_REPO"].strip() CONFIG_REPO = config["CONFIG_REPO"].strip()
if CONFIG_REPO: if CONFIG_REPO:
for i, url in enumerate(CONFIG_REPO.split(',')): for i, repourl in enumerate(CONFIG_REPO.split(',')):
reponame = 'packstack_%d' % i reponame = 'packstack_%d' % i
server.append('echo "[%s]\nname=%s\nbaseurl=%s\nenabled=1\npriority=1\ngpgcheck=0"' server.append('echo "[%(reponame)s]\nname=%(reponame)s\n'
' > /etc/yum.repos.d/%s.repo' % (reponame, reponame, url, reponame)) 'baseurl=%(repourl)s\nenabled=1\n'
'priority=1\ngpgcheck=0"'
' > /etc/yum.repos.d/%(reponame)s.repo'
% locals())
server.append("yum clean metadata") server.append("yum clean metadata")
server.execute() server.execute()

View File

@@ -17,13 +17,14 @@
import os import os
import shutil import shutil
import subprocess
import sys import sys
from unittest import TestCase from unittest import TestCase
from packstack.modules import ospluginutils, puppet from packstack.modules import ospluginutils, puppet
from packstack.installer import run_setup, basedefs from packstack.installer import run_setup, basedefs
from ..test_base import PackstackTestCaseMixin from ..test_base import PackstackTestCaseMixin, FakePopen
class CommandLineTestCase(PackstackTestCaseMixin, TestCase): class CommandLineTestCase(PackstackTestCaseMixin, TestCase):
@@ -42,6 +43,11 @@ class CommandLineTestCase(PackstackTestCaseMixin, TestCase):
Popen is replaced in PackstackTestCaseMixin so no actual commands get Popen is replaced in PackstackTestCaseMixin so no actual commands get
run on the host running the unit tests run on the host running the unit tests
""" """
# we need following to pass manage_epel(enabled=1) and
# manage_rdo(havana-6.noarch\nenabled=0) functions
fake = FakePopen()
fake.stdout = 'havana-6.noarch\nenabled=0enabled=1'
subprocess.Popen = fake
# create a dummy public key # create a dummy public key
dummy_public_key = os.path.join(self.tempdir, 'id_rsa.pub') dummy_public_key = os.path.join(self.tempdir, 'id_rsa.pub')
@@ -51,7 +57,7 @@ class CommandLineTestCase(PackstackTestCaseMixin, TestCase):
orig_argv = sys.argv orig_argv = sys.argv
sys.argv = ['packstack', '--ssh-public-key=%s' % dummy_public_key, sys.argv = ['packstack', '--ssh-public-key=%s' % dummy_public_key,
'--install-hosts=127.0.0.1', '--os-swift-install=y', '--install-hosts=127.0.0.1', '--os-swift-install=y',
'--nagios-install=y'] '--nagios-install=y', '--use-epel=y']
# There is no puppet logfile to validate, so replace # There is no puppet logfile to validate, so replace
# ospluginutils.validate_puppet_logfile with a mock function # ospluginutils.validate_puppet_logfile with a mock function

View File

@@ -18,10 +18,10 @@ import os
from unittest import TestCase from unittest import TestCase
from test_base import PackstackTestCaseMixin from test_base import PackstackTestCaseMixin
from packstack.plugins import serverprep_901 from packstack.plugins import serverprep_949
from packstack.installer.setup_controller import Controller from packstack.installer.setup_controller import Controller
serverprep_901.controller = Controller() serverprep_949.controller = Controller()
class OSPluginUtilsTestCase(PackstackTestCaseMixin, TestCase): class OSPluginUtilsTestCase(PackstackTestCaseMixin, TestCase):
@@ -30,30 +30,30 @@ class OSPluginUtilsTestCase(PackstackTestCaseMixin, TestCase):
# On non-RHEL, the CONFIG_{RH,SATELLITE} options are never set, # On non-RHEL, the CONFIG_{RH,SATELLITE} options are never set,
# i.e. this test would always fail. Therefore, only run it on RHEL. # i.e. this test would always fail. Therefore, only run it on RHEL.
if not serverprep_901.is_rhel(): if not serverprep_949.is_rhel():
return return
password = "dasd|'asda%><?" password = "dasd|'asda%><?"
serverprep_901.controller.CONF["CONFIG_KEYSTONE_HOST"] = "1.2.3.4" serverprep_949.controller.CONF["CONFIG_KEYSTONE_HOST"] = "1.2.3.4"
serverprep_901.controller.CONF["CONFIG_USE_EPEL"] = "n" serverprep_949.controller.CONF["CONFIG_USE_EPEL"] = "n"
serverprep_901.controller.CONF["CONFIG_REPO"] = "" serverprep_949.controller.CONF["CONFIG_REPO"] = ""
serverprep_901.controller.CONF["CONFIG_RH_USER"] = "testuser" serverprep_949.controller.CONF["CONFIG_RH_USER"] = "testuser"
serverprep_901.controller.CONF["CONFIG_RH_PW"] = password serverprep_949.controller.CONF["CONFIG_RH_PW"] = password
serverprep_901.controller.CONF["CONFIG_RH_BETA_REPO"] = "n" serverprep_949.controller.CONF["CONFIG_RH_BETA_REPO"] = "n"
serverprep_901.controller.CONF["CONFIG_SATELLITE_FLAGS"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_FLAGS"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_URL"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_URL"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_USER"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_USER"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_PW"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_PW"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_CACERT"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_CACERT"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_AKEY"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_AKEY"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_PROFILE"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_PROFILE"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_PROXY"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_PROXY"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_PROXY_USER"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_PROXY_USER"] = ""
serverprep_901.controller.CONF["CONFIG_SATELLITE_PROXY_PW"] = "" serverprep_949.controller.CONF["CONFIG_SATELLITE_PROXY_PW"] = ""
serverprep_901.serverprep(serverprep_901.controller.CONF) serverprep_949.serverprep(serverprep_949.controller.CONF)
self.assertNotEqual( self.assertNotEqual(
self.fake_popen.data.find('--password="%s"' % password), -1 self.fake_popen.data.find('--password="%s"' % password), -1