diff --git a/roles/proxmox/defaults/main.yml b/roles/proxmox/defaults/main.yml index b84469d..4f03e9c 100644 --- a/roles/proxmox/defaults/main.yml +++ b/roles/proxmox/defaults/main.yml @@ -33,6 +33,8 @@ proxmox__clusters: [] proxmox__cluster_links: [] proxmox__ssh_port: 22 +proxmox__ssh_ciphers: "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" +proxmox__remove_subscription_warning: false proxmox__repo_url_enterprise: https://enterprise.proxmox.com/debian proxmox__repo_url_no_subscription: http://download.proxmox.com/debian @@ -62,6 +64,8 @@ proxmox__host: {} # Example configuration: # Purposes will be overwritten by the host configuration. # The type can be set other than the provided list to rule out. +## ZFS Consult with: https://pve.proxmox.com/wiki/ZFS_on_Linux#sysadmin_zfs_limit_memory_usage +## ZFS Consult with: https://pve.proxmox.com/wiki/ZFS_on_Linux#_configure_e_mail_notification # proxmox__default: # purposes: # pve: @@ -82,4 +86,7 @@ proxmox__host: {} # type: no-subscription # version: 8.1.0 # zfs: -# version: 2.2.4-pve1 \ No newline at end of file +# version: 2.2.4-pve1 +# params: 'zfs_arc_max=2147483648' +# zed_email: 'noc@example.com' +# post_install: "{{ playbook_dir }}/tasks/zfs_post_install.yml" \ No newline at end of file diff --git a/roles/proxmox/handlers/main.yml b/roles/proxmox/handlers/main.yml new file mode 100644 index 0000000..78b04ce --- /dev/null +++ b/roles/proxmox/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: Restart zfs-zed + ansible.builtin.service: + name: zfs-zed + state: restarted + register: proxmox__zfs_zed_apply_changes_service + listen: "proxmox__zfs_zed_apply_changes" + when: "'zfs-zed' in ansible_facts.packages" \ No newline at end of file diff --git a/roles/proxmox/tasks/auth.yml b/roles/proxmox/tasks/auth.yml new file mode 100644 index 0000000..6b6ec82 --- /dev/null +++ b/roles/proxmox/tasks/auth.yml @@ -0,0 +1,15 @@ +--- +- name: Import aybarsm auth role + ansible.builtin.import_role: + name: aybarsm.linux.auth + when: proxmox__manage_root_access or proxmox__manage_sshd_config or proxmox__manage_ssh_config + +- name: Add proxmox provided ciphers to SSH client config for root + ansible.builtin.lineinfile: + line: "Ciphers {{ proxmox__ssh_ciphers }}" + regexp: "^Ciphers .*" + insertbefore: BOF + create: yes + mode: 0644 + dest: /root/.ssh/config + when: proxmox__manage_ssh_config \ No newline at end of file diff --git a/roles/proxmox/tasks/main.yml b/roles/proxmox/tasks/main.yml index c2844ea..f927448 100644 --- a/roles/proxmox/tasks/main.yml +++ b/roles/proxmox/tasks/main.yml @@ -7,49 +7,72 @@ ansible.builtin.include_tasks: file: set_facts.yml -- name: Inform when host not cluster eligible - ansible.builtin.debug: - msg: 'Host is not cluster eligible.' - when: not __proxmox__cluster_eligible - delegate_to: localhost - -- name: Import aybarsm package_manager role - ansible.builtin.import_role: - name: aybarsm.linux.package_manager - when: - - proxmox__role_enabled - - proxmox__manage_repo_keys or proxmox__manage_repos or proxmox__manage_packages - -- name: Import aybarsm grub role - ansible.builtin.import_role: - name: aybarsm.linux.grub - when: - - proxmox__role_enabled - - proxmox__manage_grub - -- name: Import aybarsm network role - ansible.builtin.import_role: - name: aybarsm.linux.network - when: - - proxmox__role_enabled - - proxmox__manage_hostname or proxmox__manage_hosts - -- name: Reboot node and wait if upgraded, grub or network-hostname,systemd,interfaces changed - ansible.builtin.reboot: - test_command: "uptime" - vars: - chk_upgrade: "{{ package_manager__upgrade_deb is defined and package_manager__upgrade_deb is changed }}" - chk_grub: "{{ grub__deploy is defined and grub__deploy is changed }}" - chk_hostname: "{{ network__hostname_deploy is defined and network__hostname_deploy is changed }}" - chk_systemd: "{{ network__systemd_deploy is defined and network__systemd_deploy is changed }}" - chk_interfaces: "{{ network__interfaces_deploy is defined and network__interfaces_deploy is changed }}" - register: proxmox__primary_reboot - when: chk_upgrade or chk_grub or chk_hostname or chk_systemd or chk_interfaces - -- name: Import aybarsm auth role - ansible.builtin.import_role: - name: aybarsm.linux.auth - when: - - proxmox__role_enabled - - __proxmox__cluster_eligible - - proxmox__manage_root_access or proxmox__manage_sshd_config or proxmox__manage_ssh_config \ No newline at end of file +# - name: Inform when host not cluster eligible +# ansible.builtin.debug: +# msg: 'Host is not cluster eligible.' +# when: not __proxmox__cluster_eligible +# delegate_to: localhost + +# - name: Import aybarsm package_manager role +# ansible.builtin.import_role: +# name: aybarsm.linux.package_manager +# when: +# - proxmox__role_enabled +# - proxmox__manage_repo_keys or proxmox__manage_repos or proxmox__manage_packages + +# - name: Import aybarsm grub role +# ansible.builtin.import_role: +# name: aybarsm.linux.grub +# when: +# - proxmox__role_enabled +# - proxmox__manage_grub + +# - name: Import aybarsm network role +# ansible.builtin.import_role: +# name: aybarsm.linux.network +# when: +# - proxmox__role_enabled +# - proxmox__manage_hostname or proxmox__manage_hosts + +# - name: Reboot node and wait if upgraded, grub or network-hostname,systemd,interfaces changed +# ansible.builtin.reboot: +# test_command: "uptime" +# vars: +# chk_upgrade: "{{ package_manager__upgrade_deb is defined and package_manager__upgrade_deb is changed }}" +# chk_grub: "{{ grub__deploy is defined and grub__deploy is changed }}" +# chk_hostname: "{{ network__hostname_deploy is defined and network__hostname_deploy is changed }}" +# chk_systemd: "{{ network__systemd_deploy is defined and network__systemd_deploy is changed }}" +# chk_interfaces: "{{ network__interfaces_deploy is defined and network__interfaces_deploy is changed }}" +# register: proxmox__primary_reboot +# when: chk_upgrade or chk_grub or chk_hostname or chk_systemd or chk_interfaces + +# - name: Include auth tasks +# ansible.builtin.include_tasks: +# file: auth.yml +# when: +# - proxmox__role_enabled +# - __proxmox__cluster_eligible + +# - name: Remove subscription check wrapper function in web UI +# ansible.builtin.lineinfile: +# path: /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js +# line: ' orig_cmd(); return;' +# insertafter: '^\s+checked_command: function\(orig_cmd\) {$' +# firstmatch: yes +# backup: yes +# when: +# - proxmox__role_enabled +# - proxmox__remove_subscription_warning + +#TODO: Remove old kernel packages +#TODO: IPMI Watchdog + +- name: Gather package facts + ansible.builtin.package_facts: + manager: auto + register: proxmox__package_facts + +- name: Include ZFS tasks + ansible.builtin.include_tasks: + file: zfs.yml + when: proxmox__role_enabled \ No newline at end of file diff --git a/roles/proxmox/tasks/set_facts.yml b/roles/proxmox/tasks/set_facts.yml index b97101b..cc540a1 100644 --- a/roles/proxmox/tasks/set_facts.yml +++ b/roles/proxmox/tasks/set_facts.yml @@ -58,7 +58,12 @@ node_repo_keys: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo_key') if proxmox__manage_repo_keys else [] }}" node_repos: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'repo') if proxmox__manage_repos else [] }}" - node_packages: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'package') if proxmox__manage_packages else [] }}" + node_packages: "{{ __proxmox__purpose_packages | selectattr('type', 'eq', 'package') + [{ + 'type': 'package', + 'name': 'os-prober', + 'state': 'absent', + 'update_cache': true + }] if proxmox__manage_packages else [] }}" cluster_hosts: "{{ [cluster_play | aybarsm.helper.only_with(['hostname', 'fqdn', 'links'])] + cluster_members if cluster_eligible else None }}" node_hosts: "{{ { diff --git a/roles/proxmox/tasks/zfs.yml b/roles/proxmox/tasks/zfs.yml new file mode 100644 index 0000000..689eb3f --- /dev/null +++ b/roles/proxmox/tasks/zfs.yml @@ -0,0 +1,28 @@ +--- +- name: Load/Unload persistent ZFS module + community.general.modprobe: + name: zfs + params: "{{ proxmox__all.purposes.zfs.params | default(omit) }}" + persistent: "{{ 'present' if proxmox__all.purposes.zfs is defined else 'absent' }}" + state: "{{ 'present' if proxmox__all.purposes.zfs is defined else 'absent' }}" + register: proxmox__zfs_modprobe + +- name: Enable/Disable email address for ZFS event daemon notifications + ansible.builtin.lineinfile: + dest: /etc/zfs/zed.d/zed.rc + line: '{{ line_prefix }}"{{ zed_email }}"' + regexp: '^#?ZED_EMAIL_ADDR=' + vars: + is_enabled: "{{ proxmox__all.purposes.zfs.zed_email is defined and proxmox__all.purposes.zfs.zed_email | length > 0 }}" + line_prefix: "{{ is_enabled | ternary('', '#') }}ZED_EMAIL_ADDR=" + zed_email: "{{ is_enabled | ternary(proxmox__all.purposes.zfs.zed_email, '') }}" + register: proxmox__zfs_zed_email + notify: "proxmox__zfs_zed_apply_changes" + +- name: HOOK - Run ZFS post-install hook tasks + ansible.builtin.include_tasks: + file: "{{ proxmox__all.purposes.zfs.post_install }}" + register: proxmox__zfs_post_install + when: + - proxmox__all.purposes.zfs.post_install is defined + - proxmox__all.purposes.zfs.post_install | length > 0 \ No newline at end of file diff --git a/roles/proxmox/vars/main.yml b/roles/proxmox/vars/main.yml index 7473f96..f1f0aeb 100644 --- a/roles/proxmox/vars/main.yml +++ b/roles/proxmox/vars/main.yml @@ -1,6 +1,6 @@ # The combination strategy below is highly nested hierarchy compliant and recommended (Example provided below) # proxmox__host > proxmox__group > proxmox__default -proxmox__all: "{{ proxmox__default | combine(proxmox__group, proxmox__host, recursive=true, list_merge='replace') }}" +proxmox__all: "{{ {'purposes': {}} | combine(proxmox__default, proxmox__group, proxmox__host, recursive=true, list_merge='replace') }}" __proxmox__purpose_packages: >- {%- set proxmox_repo_keys = [proxmox__repo_keys[ansible_distribution_release] | combine({'type': 'repo_key', 'state': 'present'})] -%}