Skip to content

Commit

Permalink
PRE - Change repo backup strategy #2
Browse files Browse the repository at this point in the history
  • Loading branch information
aybarsm committed Jul 5, 2024
1 parent 1b633f1 commit 7481315
Show file tree
Hide file tree
Showing 17 changed files with 286 additions and 166 deletions.
4 changes: 2 additions & 2 deletions roles/ansible/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ ansible__manage_local_facts: true

ansible__local_fact_template: aybarsm_linux.json.fact.j2
ansible__local_fact_backup: true
ansible__host_facts_dir: "{{ (not lookup('config', 'DEFAULT_FACT_PATH')) | ternary('/etc/ansible/facts.d', lookup('config', 'DEFAULT_FACT_PATH')) }}"
ansible__local_fact_file: "{{ ansible__host_facts_dir }}/aybarsm_linux.fact"
ansible__local_facts_dir: "{{ (not lookup('config', 'DEFAULT_FACT_PATH')) | ternary('/etc/ansible/facts.d', lookup('config', 'DEFAULT_FACT_PATH')) }}"
ansible__local_fact_file: "{{ ansible__local_facts_dir }}/aybarsm_linux.fact"
25 changes: 3 additions & 22 deletions roles/ansible/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
---
- name: Re-assign host local facts to ansible facts
become: true
ansible.builtin.set_fact:
__ansible__host_facts: "{{ ansible__update_host_facts.__ansible__host_facts }}"
register: ansible__host_facts_reassign
listen: "ansible__host_facts_reassign"
notify: ansible__host_facts_settle

- name: Settle local facts on host if changed
become: true
ansible.builtin.template:
src: "{{ ansible__local_fact_template }}"
dest: "{{ ansible__local_fact_file }}"
backup: "{{ ansible__local_fact_backup | default(omit) | bool }}"
register: ansible__host_facts_settle
listen: "ansible__host_facts_settle"
notify: ansible__host_facts_reread
when: (ansible_local.aybarsm_linux | b64encode) != (__ansible__host_facts | b64encode)

- name: Re-read local facts
- name: Re-read local facts on the host
become: true
ansible.builtin.setup:
filter: ansible_local
register: ansible__host_facts_reread
listen: "ansible__host_facts_reread"
register: ansible__local_facts_reread
listen: "ansible__local_facts_reread"
5 changes: 5 additions & 0 deletions roles/ansible/tasks/assign_local_facts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Assign host local facts to ansible facts
ansible.builtin.set_fact:
__ansible__local_facts: "{{ ansible__updated_local_facts }}"
register: ansible__local_facts_assign
13 changes: 7 additions & 6 deletions roles/ansible/tasks/local_facts.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
- name: Create directory on host for ansible local facts
- name: Ensure ansible local facts directory exists on host
become: true
ansible.builtin.file:
state: directory
recurse: true
path: "{{ ansible__host_facts_dir }}"
path: "{{ ansible__local_facts_dir }}"
register: ansible__ensure_local_facts_dir

- name: Assign local facts as ansible facts
ansible.builtin.set_fact:
__ansible__host_facts: "{{ ansible_local[fact_basename] | default({}) }}"
- name: Import assign host local facts tasks
ansible.builtin.import_tasks:
file: assign_local_facts.yml
vars:
fact_basename: "{{ ansible__local_fact_file | basename | regex_replace('\\.fact$', '') }}"
ansible__updated_local_facts: "{{ ansible_local[__ansible__local_fact_name] | default({}) }}"
5 changes: 5 additions & 0 deletions roles/ansible/tasks/set_facts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Set facts for ansible role
ansible.builtin.set_fact:
__ansible__local_fact_name: "{{ ansible__local_fact_file | basename | regex_replace('\\.fact$', '') }}"
register: ansible__set_facts
53 changes: 28 additions & 25 deletions roles/ansible/tasks/update_local_facts.yml
Original file line number Diff line number Diff line change
@@ -1,41 +1,44 @@
---
- name: Update host local facts
ansible.utils.update_fact:
updates: "{{ host_fact_updates }}"
updates: "{{ local_fact_updates }}"
vars:
fact_basename: "{{ ansible__local_fact_file | basename | regex_replace('\\.fact$', '') }}"
host_fact_updates: "{{ dict((
ansible__host_fact_updates | map(attribute='path') |
map('regex_replace', '^ansible_local\\.' + fact_basename + '\\.|^ansible_local\\.', '') |
map('regex_replace', '^(?!__ansible__host_facts\\.)(.*)$', '__ansible__host_facts.\\1')) |
zip(ansible__host_fact_updates | map(attribute='value'))) |
dict2items(key_name='path', value_name='value') }}"
register: ansible__update_host_facts
update_paths: "{{ ansible__local_fact_updates | map(attribute='path') |
map('regex_replace', '^ansible_local\\.' + __ansible__local_fact_name + '\\.|^ansible_local\\.', '') |
map('regex_replace', '^(?!__ansible__local_facts\\.)(.*)$', '__ansible__local_facts.\\1') }}"
local_fact_updates: "{{ {'path': update_paths, 'value': (ansible__local_fact_updates | map(attribute='value'))} |
aybarsm.helper.to_list_of_dicts }}"
register: ansible__update_local_facts

- name: Re-assign host local facts to ansible facts
ansible.builtin.set_fact:
__ansible__host_facts: "{{ ansible__update_host_facts.__ansible__host_facts }}"
register: ansible__host_facts_reassign
- name: Import assign host local facts tasks for re-assignment
ansible.builtin.import_tasks:
file: assign_local_facts.yml
vars:
ansible__updated_local_facts: "{{ ansible__update_local_facts.__ansible__local_facts }}"

- name: Settle local facts on host if changed
become: true
ansible.builtin.template:
src: "{{ ansible__local_fact_template }}"
dest: "{{ ansible__local_fact_file }}"
backup: "{{ ansible__local_fact_backup | default(omit) | bool }}"
register: ansible__host_facts_settle
vars:
fact_basename: "{{ ansible__local_fact_file | basename | regex_replace('\\.fact$', '') }}"
on_host: "{{ ansible_local[fact_basename] | default({}) | b64encode }}"
on_runtime: "{{ __ansible__host_facts | default({}) | b64encode }}"
on_host: "{{ ansible_local[__ansible__local_fact_name] | default({}) | b64encode }}"
on_runtime: "{{ __ansible__local_facts | default({}) | b64encode }}"
ansible_callback_diy_runner_on_skipped_msg: |
skipping: [{{ inventory_hostname }}]
msg: {{ (not ansible_check_mode and on_host != on_runtime) | ternary("Host local facts not changed.", "DRY-RUN") }}
ansible_callback_diy_runner_on_skipped_msg_color: green
when: on_host != on_runtime
notify: "ansible__local_facts_reread"
register: ansible__local_facts_settle

- name: Re-read local facts
become: true
ansible.builtin.setup:
filter: ansible_local
register: ansible__host_facts_reread
when: ansible__host_facts_settle.changed
# - name: Re-read local facts from the host
# become: true
# ansible.builtin.setup:
# filter: ansible_local
# register: ansible__host_facts_reread
# when: ansible__host_facts_settle.changed

# - name: Settle local facts if they have been modified
# ansible.builtin.meta: 'flush_handlers'
- name: Re-read local facts on the host if they have been modified
ansible.builtin.meta: 'flush_handlers'
4 changes: 2 additions & 2 deletions roles/ansible/templates/aybarsm_linux.json.fact.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% if __ansible__host_facts is defined %}
{{ __ansible__host_facts | to_nice_json }}
{% if __ansible__local_facts is defined %}
{{ __ansible__local_facts | to_nice_json }}
{% else %}
{
}
Expand Down
15 changes: 11 additions & 4 deletions roles/package_manager/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
---
package_manager__role_enabled: false

# Package Manager Strategy:
# Change the package manager strategy to use for the system i.e. ansible.builtin.apt vs ansible.builtin.package
# Available options: specific, common
package_manager__package_strategy: specific

package_manager__initial_upgrade: false
# Available options: full, dist, clean_full, clean_dist
# Upgrade Strategy:
# Upgrade the packages on the system either always, never or once
# Once option stores the state of the upgrade in host with ansible facts
# Once option requires ansible__role_enabled and ansible__manage_local_facts to be enabled
package_manager__upgrade_strategy: once

# Upgrade Mode:
# Available options for APT: full, clean_full, safe, clean_safe, yes, clean_yes, dist, clean_dist
# Available options for DNF: full, clean_full
# Clean options temproarily removes all repos other than OS default repos before upgrade
package_manager__initial_upgrade_strategy: clean_full
package_manager__deb_default_repos_template: etc/apt/default.sources.list.j2
package_manager__upgrade_mode: clean_full

# TODO: Implement this feature
# package_manager__package_simulation: true
Expand Down
33 changes: 33 additions & 0 deletions roles/package_manager/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- name: Update local facts for the host upgrade
ansible.builtin.include_role:
name: aybarsm.linux.ansible
tasks_from: update_local_facts.yml
vars:
ansible__local_fact_updates:
- path: package_manager.upgrade
value: "{{ (__ansible__local_facts.package_manager.upgrade | default([])) + [{'timestamp': now().utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')}] }}"
register: package_manager__upgrade_update_local_facts
listen: "package_manager__upgrade_update_local_facts"
when:
- package_manager__upgrade_strategy is defined
- package_manager__upgrade_strategy == 'once'

- name: Update DEB repo cache
become: true
ansible.builtin.apt:
update_cache: true
register: package_manager__deb_update_repo_cache
listen: "package_manager__deb_update_repo_cache"
when:
- ansible_os_family | lower == 'debian'

- name: Clean RPM repo metadata cache
become: true
ansible.builtin.command:
cmd: yum clean metadata
register: package_manager__rpm_clean_metadata_cache
listen: "package_manager__rpm_clean_metadata_cache"
when:
- ansible_os_family | lower == 'redhat'

13 changes: 13 additions & 0 deletions roles/package_manager/tasks/deb_upgrade.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name: Perform DEB package upgrade via APT
become: true
ansible.builtin.apt:
update_cache: "{{ package_manager__upgrade_update_repo_cache | default(omit) | bool }}"
upgrade: "{{ upgrade_mode }}"
dpkg_options: "{{ package_manager__upgrade_dpkg_options | default(omit) }}"
vars:
upgrade_mode: "{{ package_manager__upgrade_mode | regex_replace('clean_', '') }}"
register: package_manager__deb_upgrade
when:
- package_manager__upgrade_mode is defined
- upgrade_mode in __package_manager__upgrade_modes
95 changes: 0 additions & 95 deletions roles/package_manager/tasks/initial_upgrade.yml

This file was deleted.

29 changes: 21 additions & 8 deletions roles/package_manager/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
- name: Load common variables structured on OS related variables
ansible.builtin.include_vars: common.yml

- name: Import DEB initial upgrade (APT)
- name: Import aybarsm linux ansible role
ansible.builtin.import_role:
name: aybarsm.linux.ansible

- name: Set facts for package manager
ansible.builtin.import_tasks:
file: deb_initial_upgrade.yml
when:
- package_manager__role_enabled | default(false) | bool
- package_manager__initial_upgrade | default(false) | bool
- ansible__manage_local_facts | default(false) | bool
- __ansible__host_facts is defined
- ansible_os_family | lower == 'debian'
file: set_facts.yml
when: package_manager__role_enabled | default(false) | bool

- name: Import DEB repository and repository key tasks (APT)
ansible.builtin.import_tasks:
Expand All @@ -22,6 +21,20 @@
- package_manager__role_enabled | default(false) | bool
- ansible_os_family | lower == 'debian'

- name: Check upgrade strategy once compliance
ansible.builtin.fail:
msg: "Upgrade strategy has been set to 'once' but the required conditions are not met. Please enable the role and manage local facts to use 'once' strategy."
when:
- package_manager__upgrade_strategy == 'once'
- not __package_manager__upgrade_once_eligible

- name: Import upgrade tasks
ansible.builtin.import_tasks:
file: upgrade.yml
when:
- package_manager__role_enabled | default(false) | bool
- __package_manager__upgrade_perform

- name: Import DEB package tasks (APT)
ansible.builtin.import_tasks:
file: deb_packages.yml
Expand Down
7 changes: 7 additions & 0 deletions roles/package_manager/tasks/rpm_upgrade.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Perform RPM package upgrade via DNF
become: true
ansible.builtin.dnf:
name: "*"
state: latest
register: package_manager__rpm_upgrade
15 changes: 15 additions & 0 deletions roles/package_manager/tasks/set_facts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
- name: Set facts for package manager role
ansible.builtin.set_fact:
__package_manager__upgrade_once_eligible: "{{ upgrade_once_eligible }}"
__package_manager__upgrade_perform: "{{ is_upgrade_always or (is_upgrade_once and upgrade_once_eligible and not is_upgrade_defined) }}"
__package_manager__upgrade_clean: "{{ package_manager__upgrade_mode in __package_manager__clean_upgrade_modes }}"
vars:
is_upgrade_once: "{{ package_manager__upgrade_strategy == 'once' }}"
is_upgrade_always: "{{ package_manager__upgrade_strategy == 'always' }}"
is_ansible_role: "{{ ansible__role_enabled | default(false) | bool }}"
is_manage_local_facts: "{{ ansible__manage_local_facts | default(false) | bool }}"
is_local_facts_defined: "{{ __ansible__local_facts is defined }}"
is_upgrade_defined: "{{ __ansible__local_facts.package_manager.upgrade is defined }}"
upgrade_once_eligible: "{{ is_ansible_role and is_manage_local_facts and is_local_facts_defined }}"
register: package_manager__set_facts
Loading

0 comments on commit 7481315

Please sign in to comment.