#!/usr/bin/env python import os import re import platform import subprocess import urllib from distutils.version import StrictVersion from shutil import copyfile try: from pkg_resources import parse_requirements, to_filename except ImportError: # Import local version if not installed from pkg_resources_local import parse_requirements, to_filename PUPPET_TARGET_VERSION = "3.6.2" PUPPET_DIR = os.path.join(os.path.dirname(__file__)) HIERA_FILE = os.path.join(PUPPET_DIR, 'hiera.yaml') MODULES_FILE_PATH = os.path.join(PUPPET_DIR, 'modules.txt') DIST_CMD = { 'ubuntu': { 'pkg_manager': 'apt-get', 'pkg_flags': '-y', 'rep_manager': 'dpkg', 'rep_flags': '-i', 'puppet_repo': 'https://apt.puppetlabs.com/', 'puppet_pkg': 'puppetlabs-release-%s.deb', }, 'centos': { 'pkg_manager': 'yum', 'pkg_flags': '-y', 'rep_manager': 'rpm', 'rep_flags': '-ivh', 'puppet_repo': 'http://yum.puppetlabs.com/', 'puppet_pkg': 'puppetlabs-release-el-%s.noarch.rpm', }, } def add_puppet_repository(): distro, release = get_release_name() cmd_dict = DIST_CMD[distro] rep_manager = cmd_dict['rep_manager'] flags = cmd_dict['rep_flags'] puppet_repo = cmd_dict['puppet_repo'] puppet_pkg = cmd_dict['puppet_pkg'] % (release) # Download repository file tmp_file = '/tmp/%s' % (puppet_pkg) download(puppet_repo + puppet_pkg, tmp_file) # Add repository cmd = [rep_manager, flags, tmp_file] if subprocess.call(cmd) != 0: print('Repository %s already set' % puppet_pkg) def package_install(package): distro, release = get_release_name() cmd_dict = DIST_CMD[distro] pkg_manager = cmd_dict['pkg_manager'] flags = cmd_dict['pkg_flags'] cmd = [pkg_manager, flags, 'install', package] return subprocess.call(cmd) def distro_update(): distro, release = get_release_name() cmd_dict = DIST_CMD[distro] pkg_manager = cmd_dict['pkg_manager'] flags = cmd_dict['pkg_flags'] cmd = [pkg_manager, flags, 'update'] return subprocess.call(cmd) def get_release_name(): distro = platform.dist()[0].lower() if distro == 'centos': with open('/etc/centos-release') as release_file: regex = r'CentOS release (\d)' release = re.search(regex, release_file.read()).group(1) return 'centos', release elif distro == 'ubuntu': with open('/etc/lsb-release') as release_file: regex = r'DISTRIB_CODENAME=([a-z]+)' release = re.search(regex, release_file.read()).group(1) return 'ubuntu', release else: return '', '' def get_modules_installed(): modules_list = os.popen('puppet module list').read().split('\n') modules_list = [line for line in modules_list if 'no modules' not in line] modules_list = [item.split()[1:] for item in modules_list] modules_list = [item for item in modules_list if item] modules_dict = {} for name, version in modules_list: modules_dict[name] = version.split('v')[1].replace( '\x1b[0m)', '' ) return modules_dict def run(cmd, module, version=''): if version: version = ' --version %s' % (version) cmd = 'puppet module %s %s%s' % (cmd, module, version) process = subprocess.Popen(cmd, shell=True, executable='/bin/bash') process.wait() def install_puppet_modules(): modules_installed = get_modules_installed() with open(MODULES_FILE_PATH) as modules_file: modules_requirements = modules_file.read().replace('/', '-') for module in parse_requirements(modules_requirements): current_cmd, compare, version, version_comparison = '', '', '', None module_name = to_filename(module.project_name).replace('_', '-', 1) if module_name in modules_installed: if module.specs: compare, version = module.specs[0] tmp_version = modules_installed[module_name] installed_version = StrictVersion(tmp_version) required_version = StrictVersion(version) if installed_version >= required_version: version_comparison = 0 else: version_comparison = -1 else: continue if version_comparison == 0 and compare is not '>': # module version installed is equal version continue else: # module version installed is smaller or bigger than version current_cmd = 'upgrade' else: current_cmd = 'install' if version and compare and '>' not in compare: run(current_cmd, module_name, version) else: if not version_comparison or version_comparison < 0: run(current_cmd, module_name) def iscentos(distro): return distro == 'centos' def isubuntu(distro): return distro == 'ubuntu' def download(url, filename): try: urllib.urlretrieve(url, filename) except IOError: print "Could not install puppet" raise def main(): distro, release = get_release_name() print('Distro %s, release %s' % (distro, release)) if not os.path.exists('/usr/bin/puppet'): # Add repository add_puppet_repository() # Install Puppet if isubuntu(distro): distro_update() result = package_install('puppet') if result != 0: print('Failed installing puppet') exit(result) if os.path.isfile(HIERA_FILE): copyfile(HIERA_FILE, '/etc/puppet/hiera.yaml') install_puppet_modules() if __name__ == '__main__': main()