Commit 25a85a0a authored by Jean-Michel Elyn's avatar Jean-Michel Elyn
Browse files

packages: Move role from all playbook

parent 95f6d49a
#!/usr/bin/python3
#######################################################################################################################
# DESCRIPTION
#
'''
Module for Ansible: package_enumerate.
It provides the dictionary of installed packages providing their repositories:
- package_dict:
package_1: repo_x
package_2: repo_y
package_3: repo_z
If there is no repo provided, it means it is one of the enabled repositories.
Arguments to provide:
- enabled_repos: repos that are enabled (all the others being disabled)
Files touched: None
'''
#######################################################################################################################
# IMPORTS
#
import json
import os
import re
import subprocess
import sys
import yaml
#######################################################################################################################
# GET MODULE ARGUMENTS
#
# Ansible guarantees to provide a file containing JSON arguments
# WANT_JSON : This word tells Ansible to provide arguments in JSON format
with open(sys.argv[1], 'r') as args_stream:
args_dict = json.load(args_stream)
# Check module arguments
if 'enabled_repos' not in args_dict:
print(json.dumps({'failed': True, 'msg': 'Missing module arguments'}))
sys.exit(1)
#######################################################################################################################
# CALCULATE PACKAGE LIST
#
# Get list of installed packages
cmd = 'yum list installed'
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(cmd_output, cmd_err) = process.communicate()
if process.returncode != 0:
print(json.dumps({'failed' : True, 'msg' : cmd_err}))
sys.exit(1)
if not cmd_output:
print(json.dumps({'failed' : True, 'msg' : 'empty list of installed packages'}))
sys.exit(1)
# Format yum output
package_dict = dict()
broken_line = ''
is_header = True
enabled_repo_set = set(args_dict['enabled_repos'])
for output_line in cmd_output.decode().splitlines():
# Skip header
if output_line == 'Installed Packages':
is_header = False
continue
if is_header:
continue
# Rebuild full lines (long lines are split)
field_list = output_line.split()
if len(field_list) < 3:
broken_line += output_line
if len(broken_line.split()) < 3:
continue
field_list = broken_line.split()
broken_line = ''
# Format package and repo names
package = re.sub('\.x86_64$|\.noarch$', '', field_list[0])
repo = field_list[2]
if re.search('^@/|installed|commandline|System', repo):
continue
repo = re.sub("@", "", repo)
# Populate dictionary of packages
if repo in enabled_repo_set:
repo = ''
package_dict[package] = repo
#######################################################################################################################
# RETURN ANSIBLE VALUES
#
print(json.dumps({'ok': True, 'dict': package_dict }))
sys.exit(0)
#!/usr/bin/python3
#######################################################################################################################
# DESCRIPTION
#
'''
Module for Ansible: install_packages.
It install packages on the system.
Arguments to provide:
- installed_packages: list of installed packages
- required_packages: dict of packages that should be present on local host
- banned_packages: dict of packages that should NOT be present on local host
Files touched: Files from installed packages
'''
#######################################################################################################################
# IMPORTS
#
import json
import os
import re
import subprocess
import sys
import yaml
#######################################################################################################################
# FUNCTIONS
#
#----------------------------------------------------------------------------------------------------------------------
def install_packages(package_dict, repo):
global ansible_state
global installed_set
if repo not in package_dict or len(package_dict[repo]) == 0:
return
ansible_state = 'changed'
installed_set |= package_dict[repo]
if repo == 'enabled_repos':
repo_option = ''
else:
repo_option = '--enablerepo=' + repo + ' '
cmd = 'yum install -y ' + repo_option + ' '.join(package_dict[repo])
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(cmd_output, cmd_error) = process.communicate()
output = cmd_output.decode()
error = cmd_error.decode()
if process.returncode != 0 and error and not re.match('Error: Nothing to do', error) and not re.match('Non-fatal POSTIN scriptlet failure', error):
print(json.dumps({'failed' : True, 'msg' : error}))
sys.exit(1)
#----------------------------------------------------------------------------------------------------------------------
def remove_packages(package_set):
global ansible_state
global removed_set
if len(package_set) == 0:
return
ansible_state = 'changed'
removed_set |= package_set
cmd = 'yum remove -y ' + ' '.join(package_set)
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(cmd_output, cmd_error) = process.communicate()
output = cmd_output.decode()
error = cmd_error.decode()
if process.returncode != 0 and error:
print(json.dumps({'failed' : True, 'msg' : error}))
sys.exit(1)
#######################################################################################################################
# GET MODULE ARGUMENTS
#
# Ansible guarantees to provide a file containing arguments
# WANT_JSON : This word tells Ansible to provide arguments in JSON format
with open(sys.argv[1], 'r') as args_stream:
args_dict = json.load(args_stream)
# Check module arguments
if 'installed_packages' not in args_dict \
or 'required_packages' not in args_dict \
or 'banned_packages' not in args_dict:
print(json.dumps({'failed': True, 'msg': 'Missing module arguments'}))
sys.exit(1)
#######################################################################################################################
# MANAGE PACKAGES
#
# Ansible init
ansible_state = 'ok'
installed_set = set()
removed_set = set()
# Calculate packages to remove
packages_to_remove_set = set(args_dict['banned_packages'].keys()) & set(args_dict['installed_packages'].keys())
# Calculate packages to install
packages_to_install_dict = { package: repo for package, repo in args_dict['required_packages'].items() \
if package not in args_dict['installed_packages'] and package not in args_dict['banned_packages'] }
# Format packages to install
packages_to_install_by_repos_dict = dict()
for package, repo in packages_to_install_dict.items():
if not repo or repo == 'None':
repo = 'enabled_repos'
if repo not in packages_to_install_by_repos_dict:
packages_to_install_by_repos_dict[repo] = set()
packages_to_install_by_repos_dict[repo].add(package)
# First, remove banned packages
remove_packages(packages_to_remove_set)
# Second, install packages from enabled_repos
install_packages(packages_to_install_by_repos_dict, 'enabled_repos')
# Third, install packages from other repos
for repo in [r for r in packages_to_install_by_repos_dict if r != 'enabled_repos']:
install_packages(packages_to_install_by_repos_dict, repo)
installed_list = sorted(installed_set)
removed_list = sorted(removed_set)
#######################################################################################################################
# RETURN ANSIBLE VALUES
#
print(json.dumps({ ansible_state: True, 'installed_list': installed_list, 'removed_list': removed_list }))
sys.exit(0)
#!/usr/bin/python3
#######################################################################################################################
# DESCRIPTION
#
'''
Module for Ansible: package_update.
It updates all packages enabling repos when necessary.
Arguments to provide:
- installed_packages: list of installed packages sorted by repos
Files touched:
- all updates files
'''
#######################################################################################################################
# IMPORTS
#
import json
import os
import re
import subprocess
import sys
import yaml
#######################################################################################################################
# FUNCTIONS
#
def update_packages(repo):
if repo == 'enabled_repos':
cmd = 'yum update -y --allowerasing'
else:
cmd = 'yum update -y --exclude="WinCC_OA*" --allowerasing --enablerepo=' + repo
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(cmd_output, cmd_err) = process.communicate()
if process.returncode != 0 and cmd_err and cmd_err != 'Error: Nothing to do\n':
print(json.dumps({'failed' : True, 'msg' : cmd_err.decode()}))
sys.exit(1)
#######################################################################################################################
# GET MODULE ARGUMENTS
#
# Ansible guarantees to provide a file containing JSON arguments
# WANT_JSON : This word tells Ansible to provide arguments in JSON format
with open(sys.argv[1], 'r') as args_stream:
args_dict = json.load(args_stream)
# Check module arguments
if 'installed_packages' not in args_dict:
print(json.dumps({'failed': True, 'msg': 'Missing module arguments'}))
sys.exit(1)
#######################################################################################################################
# UPDATE PACKAGES
#
# Format packages to update
package_dict = dict()
for package, repo in args_dict['installed_packages'].items():
if repo == '':
repo = 'enabled_repos'
if repo not in package_dict:
package_dict[repo] = set()
package_dict[repo].add(package)
# First, update packages from enabled repos
update_packages('enabled_repos')
# Then, update packages from other repos, repo by repo
for repo, package_set in package_dict.items():
if repo == 'enabled_repos':
continue
if len(package_set) > 0:
update_packages(repo)
#######################################################################################################################
# RETURN ANSIBLE VALUES
#
print(json.dumps({ 'changed': True }))
sys.exit(0)
- name: Get list of installed rpm
package_enumerate:
enabled_repos: '{{ repos.enabled_repos }}'
register: r_package_enumerate
- name: Update rpm
package_update:
installed_packages: '{{ r_package_enumerate.dict }}'
when: allow_yum and r_repo_config.changed or snapdate == 'canary'
- name: Get facts again
setup:
filter: localhost
when: r_repo_config.changed
- name: Install/remove rpm
package_install:
installed_packages: '{{ r_package_enumerate.dict }}'
required_packages: '{{ required_packages }}'
banned_packages: '{{ banned_packages }}'
register: r_packages
when: allow_yum
- name: Display installed/removed rpm
debug:
msg: '{{ item }}'
when: r_packages.changed
loop:
- 'installed packages: {{ r_packages.installed_list }}'
- 'removed packages: {{ r_packages.removed_list }}'
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment