Skip to content

Commit

Permalink
Merge pull request #170 from elyezer/additional-repos
Browse files Browse the repository at this point in the history
Refactor repository management
  • Loading branch information
omaciel committed Apr 22, 2015
2 parents 30fae91 + 7708b21 commit c30c153
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 119 deletions.
123 changes: 9 additions & 114 deletions automation_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from re import search
from urlparse import urlsplit

from automation_tools.repository import enable_satellite_repos
from automation_tools.utils import distro_info, update_packages
from fabric.api import cd, env, execute, get, local, put, run
if sys.version_info[0] is 2:
from urlparse import urljoin # (import-error) pylint:disable=F0401
Expand Down Expand Up @@ -650,45 +652,6 @@ def install_prerequisites():
manage_daemon('start', 'ntpd', warn_only=True)


def manage_repos(cdn=False):
"""Enables only required RHEL repos for Satellite 6."""

if isinstance(cdn, str):
cdn = (cdn.lower() == 'true')

# Clean up system if Beaker-based
result = run('which yum-config-manager', warn_only=True)
if result.succeeded:
run('yum-config-manager --disable "beaker*"')
else:
run('mv /etc/yum.repos.d/beaker-* ~/', warn_only=True)
run('rm -rf /var/cache/yum*')

# Disable yum plugin for sub-man
run('sed -i -e "s/^enabled.*/enabled=0/" '
'/etc/yum/pluginconf.d/subscription-manager.conf')
# And disable all repos for now
run('subscription-manager repos --disable "*"')

os_version = distro_info()[1]
# If installing from CDN, use the real product
if cdn is True:
run(
'subscription-manager repos --enable '
'"rhel-{0}-server-satellite-6.0-rpms"'.format(os_version)
)
# Enable 'base' OS rpms
run('subscription-manager repos --enable "rhel-{0}-server-rpms"'.format(
os_version))
# Enable SCL
run('subscription-manager repos --enable "rhel-server-rhscl-{0}-rpms"'
''.format(os_version))
run('yum repolist')

# Update packages
update_packages(warn_only=True)


def upstream_install(
admin_password=None, sam=False, run_katello_installer=True):
"""Task to install Foreman nightly using katello-deploy script"""
Expand Down Expand Up @@ -1003,7 +966,13 @@ def product_install(distribution, create_vm=False, certificate_url=None,

execute(install_prerequisites, host=host)
execute(setenforce, selinux_mode, host=host)
execute(manage_repos, cdn=distribution.endswith('cdn'), host=host)
execute(
enable_satellite_repos,
cdn=distribution.endswith('cdn'),
host=host
)
execute(update_packages, warn_only=True)

# execute returns a dictionary mapping host strings to the given task's
# return value
installer_options.update(execute(
Expand Down Expand Up @@ -1136,61 +1105,6 @@ def create_personal_git_repo(name, private=False):
local('rm -rf {0}'.format(repo_name))


def distro_info():
"""Task which figures out the distro information based on the
/etc/redhat-release file
A `(distro, major_version)` tuple is returned if called as a function. For
RHEL X.Y.Z it will return ('rhel', X). For Fedora X it will return
('fedora', X). Be aware that the major_version is an integer.
"""
# Create/manage host cache
cache = env.get('distro_info_cache')
host = env['host']
if cache is None:
cache = env['distro_info_cache'] = {}

if host not in cache:
# Grab the information and store on cache
release_info = run('cat /etc/redhat-release', quiet=True)
if release_info.failed:
print('Failed to read /etc/redhat-release file')
sys.exit(1)

# Discover the distro
if release_info.startswith('Red Hat Enterprise Linux'):
distro = 'rhel'
elif release_info.startswith('Fedora'):
distro = 'fedora'
else:
distro = None

# Discover the version
match = search(r' ([0-9.]+) ', release_info)
if match is not None:
parts = match.group(1).split('.')
# extract the major version
major_version = int(parts[0])
# extract the minor version
if len(parts) > 1:
minor_version = int(parts[1])
else:
minor_version = None
else:
major_version = minor_version = None

if distro is None or major_version is None:
print('Was not possible to fetch distro information')
sys.exit(1)

cache[host] = distro, major_version, minor_version

distro, major_version, minor_version = cache[host]
print('{0} {1} {2}'.format(distro, major_version, minor_version))
return distro, major_version, minor_version


def performance_tuning(running_on_vm=True):
"""Task which tunes up the Satellite 6 performance
Expand Down Expand Up @@ -1498,25 +1412,6 @@ def run_errata():
# Run `<package2>-downgrade` if you want to revert to the old packages


def update_packages(*args, **kwargs):
"""Updates all system packages or only ones specified by `args`
Use this if you want to simply update all packages or some on system.
Possibly useful for when doing upgrades, etc.
"""
if len(args) > 0:
arguments = ' '.join(args)
else:
arguments = ''

run(
'yum update -y {0}'.format(arguments),
quiet=kwargs.get('quiet', False),
warn_only=kwargs.get('warn_only', False),
)


# =============================================================================
# Utility tasks
# =============================================================================
Expand Down
157 changes: 157 additions & 0 deletions automation_tools/repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"""Taks for managing repositories"""
from __future__ import print_function

import sys

from automation_tools.utils import distro_info
from fabric.api import put, run

if sys.version_info[0] == 2:
from StringIO import StringIO # pylint:disable=import-error
else:
from io import StringIO


def disable_repos(*args):
"""Disable repos passed as ``args`` using ``subscription-manager repos
--disable``.
For example::
disable_repos('repo1', 'repo2')
Will run the command ``subscription-manager repos --disable repo1 repo2``.
"""
run('subscription-manager repos --disable {0}'
.format(' '.join(['"{0}"'.format(repo) for repo in args])))


def delete_custom_repos(**args):
"""Delete repos files on ``/etc/yum.repos.d``.
All files that match ``<filename>.repo`` will be deleted. Be aware that
this task can delete repository files created by ``subscription-manager``
and other tools. But will raise ``ValueError`` if the repository name is
``redhat``.
:raise: ``ValueError`` if repository name is 'redhat'.
"""
for name in args:
name = name.rstrip('.repo')
if name == 'redhat':
raise ValueError('This task will not delete redhat.repo file.')
run('rm -f /etc/yum.repos.d/{0}.repo'.format(name), warn_only=True)


def enable_repos(*args, **kwargs):
"""Enable repos passed as ``args`` using ``subscription-manager repos
--enable``.
For example::
enable_repos('repo1', 'repo2')
Will run the command ``subscription-manager repos --enable repo1 repo2``.
"""
run('subscription-manager repos --enable {0}'
.format(' '.join(['"{0}"'.format(repo) for repo in args])))


def create_custom_repos(**kwargs):
"""Create custom repofiles.
Each ``kwargs`` item will result in one repository file created. Where the
key is the repository filename and repository name, and the value is the
repository URL.
For example::
create_custom_repo(custom_repo='http://repourl.domain.com/path')
Will create a repository file named ``custom_repo.repo`` with the following
contents::
[custom_repo]
name=custom_repo
baseurl=http://repourl.domain.com/path
enabled=1
gpgcheck=0
"""
for name, url in kwargs.items():
repo_file = StringIO()
repo_file.write(
'[{name}]\n'
'name={name}\n'
'baseurl={url}\n'
'enabled=1\n'
'gpgcheck=0\n'
.format(name=name, url=url)
)
put(local_path=repo_file,
remote_path='/etc/yum.repos.d/{0}.repo'.format(name))
repo_file.close()


def enable_satellite_repos(cdn=False, disable_enabled=True):
"""Enable repositories required to install Satellite 6
If ``disable_enabled`` is ``True``, then this task will first disable any
already enabled repository, including beaker ones.
"""
if isinstance(cdn, str):
cdn = (cdn.lower() == 'true')
if isinstance(disable_enabled, str):
disable_enabled = (disable_enabled.lower() == 'true')

if disable_enabled is True:
disable_beaker_repos()
disable_repos('*')

repos = [
'rhel-{0}-server-rpms',
'rhel-server-rhscl-{0}-rpms',
]

if cdn is True:
repos.append('rhel-{0}-server-satellite-6.0-rpms')

enable_repos(*[repo.format(distro_info()[1]) for repo in repos])

run('yum repolist')


def disable_beaker_repos():
"""Disable beaker repositories
If yum-config-manager is available this task will disable the repos, if not
it will move the beaker repo files to the running user home directory
"""
# Clean up system if Beaker-based
result = run('which yum-config-manager', warn_only=True)
if result.succeeded:
run('yum-config-manager --disable "beaker*"')
else:
run('mv /etc/yum.repos.d/beaker-* ~/', warn_only=True)
run('rm -rf /var/cache/yum*')


def manage_custom_repos(**kwargs):
"""Enable or disable custom repositories.
The keyword key is the repository filename and the boolean value indicates
if it should enable if ``True`` or disable if ``False``.
"""
for name, enable in kwargs.items():
repo_file = '/etc/yum.repos.d/{0}.repo'.format(name)
run('sed -i -e "s/^enabled=.*/enabled={0}/" {1}'.format(
1 if enable is True else 0,
repo_file
))
81 changes: 81 additions & 0 deletions automation_tools/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Utilities tasks and functions"""
from __future__ import print_function

import re
import sys

from fabric.api import env, run


def distro_info():
"""Task which figures out the distro information based on the
/etc/redhat-release file
A ``(distro, major_version)`` tuple is returned if called as a function.
For RHEL X.Y.Z it will return ``('rhel', X)``. For Fedora X it will return
``('fedora', X)``. Be aware that the major_version is an integer.
"""
# Create/manage host cache
cache = env.get('distro_info_cache')
host = env['host']
if cache is None:
cache = env['distro_info_cache'] = {}

if host not in cache:
# Grab the information and store on cache
release_info = run('cat /etc/redhat-release', quiet=True)
if release_info.failed:
print('Failed to read /etc/redhat-release file')
sys.exit(1)

# Discover the distro
if release_info.startswith('Red Hat Enterprise Linux'):
distro = 'rhel'
elif release_info.startswith('Fedora'):
distro = 'fedora'
else:
distro = None

# Discover the version
match = re.search(r' ([0-9.]+) ', release_info)
if match is not None:
parts = match.group(1).split('.')
# extract the major version
major_version = int(parts[0])
# extract the minor version
if len(parts) > 1:
minor_version = int(parts[1])
else:
minor_version = None
else:
major_version = minor_version = None

if distro is None or major_version is None:
print('Was not possible to fetch distro information')
sys.exit(1)

cache[host] = distro, major_version, minor_version

distro, major_version, minor_version = cache[host]
print('{0} {1} {2}'.format(distro, major_version, minor_version))
return distro, major_version, minor_version


def update_packages(*args, **kwargs):
"""Updates all system packages or only ones specified by `args`
Use this if you want to simply update all packages or some on system.
Possibly useful for when doing upgrades, etc.
"""
if len(args) > 0:
arguments = ' '.join(args)
else:
arguments = ''

run(
'yum update -y {0}'.format(arguments),
quiet=kwargs.get('quiet', False),
warn_only=kwargs.get('warn_only', False),
)

0 comments on commit c30c153

Please sign in to comment.