Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corosync role variable handling #75

Merged
merged 5 commits into from
Oct 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,18 +418,18 @@ pve_cluster_enabled: no # Set this to yes to configure hosts to be clustered tog
pve_cluster_clustername: "{{ pve_group }}" # Should be set to the name of the PVE cluster
```

Information about the following can be found in the PVE Documentation in the
[Cluster Manager][pvecm-network] chapter.
The following variables are used to provide networking information to corosync.
These are known as ring0_addr/ring1_addr or link0_addr/link1_addr, depending on
PVE version. They should be IPv4 or IPv6 addresses. For more information, refer
to the [Cluster Manager][pvecm-network] chapter in the PVE Documentation.

```
pve_cluster_ring0_addr: "{{ ansible_default_ipv4.address }}"
pve_cluster_bindnet0_addr: "{{ pve_cluster_ring0_addr }}"
# pve_cluster_ring1_addr: "another interface's IP address or hostname"
# pve_cluster_bindnet1_addr: "{{ pve_cluster_ring1_addr }}"
# pve_cluster_addr0: "{{ ansible_default_ipv4.address }}"
# pve_cluster_addr1: "another interface's IP address or hostname"
```

You can set options in the datacenter.cfg configuration file:

```
pve_datacenter_cfg:
keyboard: en-us
Expand Down
10 changes: 2 additions & 8 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,8 @@ pve_ceph_crush_rules: []
# pve_ssl_certificate: "contents of certificate"
pve_cluster_enabled: no
pve_cluster_clustername: "{{ pve_group }}"
# PVE 5.x (Debian Stretch) clustering options
pve_cluster_ring0_addr: "{{ ansible_default_ipv4.address }}"
pve_cluster_bindnet0_addr: "{{ pve_cluster_ring0_addr }}"
# pve_cluster_ring1_addr: "another interface's IP address or hostname"
# pve_cluster_bindnet1_addr: "{{ pve_cluster_ring1_addr }}"
# PVE 6.x (Debian Buster) clustering options
pve_cluster_link0_addr: "{{ ansible_default_ipv4.address }}"
# pve_cluster_link1_addr: "another interface's IP address or hostname"
# pve_cluster_addr0: "{{ ansible_default_ipv4.address }}"
Copy link
Collaborator

@trickert76 trickert76 Oct 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just my two cents, I've learned, that the default interfaces may change. For example docker installations add docker0 and then because d is before e, the default interfaces in ansible changes. Maybe we should mention that. I've added somewhere else in my playbook a set_fact based on a filter of all interfaces starting with 'e' to get the first address. But when you use more then one ethernet device, this will maybe overridden. Nothing to change here.

# pve_cluster_addr1: "{{ ansible_eth1.ipv4.address }}
pve_datacenter_cfg: {}
pve_ssl_letsencrypt: false
pve_groups: []
Expand Down
43 changes: 43 additions & 0 deletions tasks/load_variables.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
- name: Gather distribution specific variables
include_vars: "debian-{{ ansible_distribution_release }}.yml"

- block:
# Per Proxmox documentation, bindnet_addr is expected to be an IP address and
# ring_addr can be either hostname or IP, but this role has always used an IP
# address. Thus, we're deprecating them. See below references.
# https://pve.proxmox.com/wiki/Separate_Cluster_Network#Setup_at_Cluster_Creation
# https://git.proxmox.com/?p=pve-cluster.git;a=blob;f=data/PVE/Corosync.pm;h=8b5c91e0da084da4e9ba7423176872a0c16ef5af;hb=refs/heads/stable-5#l209
- name: LEGACY - Define pve_cluster_addr0 from bindnet0_addr/ring0_addr
set_fact:
pve_cluster_addr0: "{{ pve_cluster_bindnet0_addr | default(pve_cluster_ring0_addr) }}"
when: pve_cluster_ring0_addr is defined and ansible_distribution_release == 'stretch'

- name: LEGACY - Define pve_cluster_addr0 from link0_addr
set_fact:
pve_cluster_addr0: "{{ pve_cluster_link0_addr }}"
when: pve_cluster_link0_addr is defined and ansible_distribution_release == 'buster'
when: pve_cluster_addr0 is not defined

- block:
- name: LEGACY - Define pve_cluster_addr1 from bindnet1_addr/ring1_addr
set_fact:
pve_cluster_addr1: "{{ pve_cluster_bindnet1_addr | default(pve_cluster_ring1_addr) }}"
when: pve_cluster_ring1_addr is defined and ansible_distribution_release == 'stretch'

- name: LEGACY - Define pve_cluster_addr1 from link1_addr
set_fact:
pve_cluster_addr1: "{{ pve_cluster_link1_addr }}"
when: pve_cluster_link1_addr is defined and ansible_distribution_release == 'buster'
when: pve_cluster_addr1 is not defined

- name: Define pve_cluster_addr0 if not provided
set_fact:
pve_cluster_addr0: "{{ pve_cluster_addr0 | default(_pve_cluster_addr0) }}"

- name: Calculate list of SSH addresses
set_fact:
pve_cluster_ssh_addrs: >-
["{{ ansible_fqdn }}", "{{ ansible_hostname }}",
"{{ pve_cluster_addr0 }}",
{% if pve_cluster_addr1 is defined %}"{{ pve_cluster_addr1 }}"{% endif %}]
55 changes: 43 additions & 12 deletions tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
---
# tasks file for ansible-role-proxmox
- name: Gather distribution specific variables
include_vars: "debian-{{ ansible_distribution_release }}.yml"
- import_tasks: load_variables.yml

- name: Ensure that we have an IP address for all cluster hosts
- name: Ensure that facts are present for all cluster hosts
assert:
that:
- "hostvars[item].ansible_default_ipv4.address is defined"
msg: "Missing IP address and other information for {{ item }}. Have you gathered its facts?"
- "hostvars[item].ansible_facts"
msg: "Could not load facts for {{ item }}. Please run your playbook against all hosts in {{ pve_group }}."
with_items: "{{ groups[pve_group] }}"

- name: Ensure this host is in the group specified
Expand All @@ -27,25 +26,57 @@
blockinfile:
dest: /etc/hosts
marker: "# {mark} ANSIBLE MANAGED: Proxmox Cluster Hosts"
content: |
{% for host in groups[pve_group] %}
{{ hostvars[host].ansible_default_ipv4.address }} {{ hostvars[host].ansible_fqdn }} {{ hostvars[host].ansible_hostname }}{% if ansible_fqdn == hostvars[host].ansible_fqdn %} pvelocalhost{% endif %}
content: "\
{% for host in groups[pve_group] %}\
{{ hostvars[host].pve_cluster_addr0 }}
{{ hostvars[host].ansible_fqdn }}
{{ hostvars[host].ansible_hostname }}\
{% if ansible_fqdn == hostvars[host].ansible_fqdn %} pvelocalhost{% endif %}
{% endfor %}
{% endfor %}"

- name: Remove conflicting lines in hosts files
lineinfile:
dest: /etc/hosts
# expanded, this turns out to be, for example:
# regexp: '^(?!10\.0\.3\.17 test01\.lxc test01( pvelocalhost)?)(?!10\.0\.3\.17)[\w:.]+(\s+.*)?\s(test01\.lxc|test01|pvelocalhost)(\s+.*|\s*)$'
# regexp: "^(?!10\.0\.3\.17\\ test01\.lxc\\ test01\\ pvelocalhost)(?!10\.0\.3\.17)[0-9a-f:.]+(\s+.*)?\s(test01\.lxc|test01|pvelocalhost)(\s+.*|\s*)$'
# basically first we ignore lines that match from the host enumeration task
# above, then we match against different IPs (e.g. NOT 10.0.3.17) that have
# the hostname/fqdn we inserted a record for previously, taking care also to
# detect word boundaries (\b wasn't working for some reason)
regexp: '^(?!{{ hostvars[item].ansible_default_ipv4.address | regex_escape() }} {{ hostvars[item].ansible_fqdn | regex_escape() }} {{ hostvars[item].ansible_hostname | regex_escape() }}( pvelocalhost)?)(?!{{ hostvars[item].ansible_default_ipv4.address | regex_escape() }})[\w:.]+(\s+.*)?\s({{ hostvars[item].ansible_fqdn | regex_escape() }}|{{ hostvars[item].ansible_hostname | regex_escape() }}{% if ansible_fqdn == hostvars[item].ansible_fqdn %}|pvelocalhost{% endif %})(\s+.*|\s*)$'
regexp: "\
^(?!\
{{ _correct_line | regex_escape() }}\
)\
{# Ignore lines starting with the current cluster host #}\
(?!{{ _correct_ip | regex_escape() }})\
{# Match an IPv4/v6 address at the start #}\
[0-9a-f:.]\
{# Match any hostnames, surrounded by whitespace #}\
+(\\s+.*)?\\s\
(\
{{ _match_hosts | map('regex_escape') | join('|') }}\
)\
(\\s+.*|\\s*)$"
state: absent
backup: yes
with_items: "{{ groups[pve_group] }}"
loop: "{{ groups[pve_group] }}"
vars:
_correct_line: "\
{{ hostvars[item].pve_cluster_addr0 }}
{{ hostvars[item].ansible_fqdn }}
{{ hostvars[item].ansible_hostname }}\
{% if ansible_fqdn == hostvars[item].ansible_fqdn %} pvelocalhost{% endif %}"
_correct_ip: "{{ hostvars[item].pve_cluster_addr0 }}"
_match_hosts: >-
[
"{{ hostvars[item].ansible_fqdn }}",
"{{ hostvars[item].ansible_hostname }}",
{% if ansible_fqdn == hostvars[item].ansible_fqdn %}
"pvelocalhost"
{% endif %}
]
- name: Trust Proxmox' packaging key
apt_key:
Expand Down
25 changes: 9 additions & 16 deletions tasks/pve_add_node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,19 @@
_pve_current_node: "{{ item }}"

- name: Add node to Proxmox cluster
command: "pvecm add {{ hostvars[groups[pve_group][0]]['ansible_default_ipv4']['address'] }} \
-use_ssh \
-ring0_addr {{ pve_cluster_ring0_addr }}{% if pve_cluster_ring1_addr is defined %} \
-ring1_addr {{ pve_cluster_ring1_addr }}{% endif %}"
command: >-
pvecm add {{ hostvars[groups[pve_group][0]].pve_cluster_addr0 }} -use_ssh
{{ addr0_flag }} {{ pve_cluster_addr0 }}
{% if pve_cluster_addr1 is defined %}
{{ addr1_flag }} {{ pve_cluster_addr1 }}
{% endif %}
args:
creates: "{{ pve_cluster_conf }}"
vars:
addr0_flag: "{{ (ansible_distribution_release == 'buster') | ternary('-link0', '-ring0_addr') }}"
addr1_flag: "{{ (ansible_distribution_release == 'buster') | ternary('-link1', '-ring1_addr') }}"
when:
- "inventory_hostname == _pve_current_node"
- "ansible_distribution_release == 'stretch'"

- name: Add node to Proxmox cluster
command: "pvecm add {{ hostvars[groups[pve_group][0]]['ansible_default_ipv4']['address'] }} \
-use_ssh \
-link0 {{ pve_cluster_link0_addr }}{% if pve_cluster_link1_addr is defined %} \
-link1 {{ pve_cluster_link1_addr }}{% endif %}"
args:
creates: "{{ pve_cluster_conf }}"
when:
- "inventory_hostname == _pve_current_node"
- "ansible_distribution_release == 'buster'"

- name: Remove stale corosync lock file due to lack of quorum during initialization
file:
Expand Down
26 changes: 9 additions & 17 deletions tasks/pve_cluster_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,20 @@
when: "(_pve_found_clusters | default([]) | length) == 1"

- name: Initialize a Proxmox cluster
command: "pvecm create {{ pve_cluster_clustername }} -bindnet0_addr {{ pve_cluster_bindnet0_addr }} \
-ring0_addr {{ pve_cluster_ring0_addr }}\
{% if pve_cluster_bindnet1_addr is defined and pve_cluster_ring1_addr is defined %} \
-bindnet1_addr {{ pve_cluster_bindnet1_addr }} -ring1_addr {{ pve_cluster_ring1_addr }}{% endif %}"
args:
creates: "{{ pve_cluster_conf }}"
when:
- "_pve_found_clusters is not defined"
- "inventory_hostname == groups[pve_group][0]"
- "ansible_distribution_release == 'stretch'"

- name: Initialize a Proxmox cluster
command: "pvecm create {{ pve_cluster_clustername }} \
-link0 {{ pve_cluster_link0_addr }}\
{% if pve_cluster_link1_addr is defined %} \
-link1 {{ pve_cluster_link1_addr }}{% endif %}"
command: >-
pvecm create {{ pve_cluster_clustername }}
{{ addr0_flag }} {{ pve_cluster_addr0 }}
{% if pve_cluster_addr1 is defined %}
{{ addr1_flag }} {{ pve_cluster_addr1 }}
{% endif %}
args:
creates: "{{ pve_cluster_conf }}"
vars:
addr0_flag: "{{ (ansible_distribution_release == 'buster') | ternary('-link0', '-ring0_addr') }}"
addr1_flag: "{{ (ansible_distribution_release == 'buster') | ternary('-link1', '-ring1_addr') }}"
when:
- "_pve_found_clusters is not defined"
- "inventory_hostname == groups[pve_group][0]"
- "ansible_distribution_release == 'buster'"

- name: Wait for quorum on initialization node
proxmox_query:
Expand Down
6 changes: 3 additions & 3 deletions tasks/ssh_cluster_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
marker: "# {mark}: PVE host configuration options (managed by ansible)."
content: |
{% for host in groups[pve_group] %}
Host {{ hostvars[host].ansible_fqdn }} {{ hostvars[host].ansible_hostname }} {{ hostvars[host].ansible_default_ipv4.address }}
Host {{ hostvars[host].pve_cluster_ssh_addrs | join(" ") }}
IdentityFile /root/.ssh/id_rsa
Port {{ pve_ssh_port }}
{% endfor %}
Expand All @@ -44,7 +44,7 @@
marker: "# {mark}: Allow root logins from PVE hosts (managed by ansible)."
content: |
{% for host in groups[pve_group] %}
Match Address {{ hostvars[host].ansible_default_ipv4.address }}
Match Address {{ hostvars[host].pve_cluster_ssh_addrs | join(",") }}
PermitRootLogin prohibit-password
{% endfor %}
validate: "/usr/sbin/sshd -t -f %s"
Expand Down Expand Up @@ -74,7 +74,7 @@
content: |
{% for host in groups[pve_group] %}
{% for keytype in ['rsa', 'ed25519', 'ecdsa'] %}
{{ hostvars[host].ansible_fqdn }},{{ hostvars[host].ansible_hostname }},{{ hostvars[host].ansible_default_ipv4.address }} {{ ' '.join(lookup('file', pve_fetch_directory + '/' + host + '/ssh_host_' + keytype + '_key.pub').split()[:-1]) }}
{{ hostvars[host].pve_cluster_ssh_addrs | join(",") }} {{ ' '.join(lookup('file', pve_fetch_directory + '/' + host + '/ssh_host_' + keytype + '_key.pub').split()[:-1]) }}
{% endfor %}
{% endfor %}
when:
Expand Down
3 changes: 3 additions & 0 deletions vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
# vars file for ansible-role-proxmox
pve_base_dir: "/etc/pve"
pve_cluster_conf: "{{ pve_base_dir }}/corosync.conf"

# defaults that need to be host facts
_pve_cluster_addr0: "{{ ansible_default_ipv4.address }}"