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

feat: Remove python expect dependency in crmsh #249

Merged
merged 1 commit into from
Dec 12, 2024
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
47 changes: 26 additions & 21 deletions tasks/enable-repositories/Suse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@
---
# All required repositories are already part of SLES for SAP 15 SP5+.

# High Availability Extension is required for cluster setup as well
# as qnetd/qdevice configuration.
- name: Gather package facts
ansible.builtin.package_facts:
manager: auto
# High Availability Extension (HAE) is required for cluster setup on SLES.
# All cluster packages are present on SLES_SAP and openSUSE,
# but not on base SLES without HAE.
- name: Execute only on SLES
when: ansible_distribution.split("_")[0] == 'SLES'
block:

- name: Check High Availability Extension presence using product file
ansible.builtin.stat:
path: /etc/products.d/sle-ha.prod
register: __ha_cluster_ha_ext_stat
- name: Gather package facts
ansible.builtin.package_facts:
manager: auto

# Registering HA Extension creates file /etc/products.d/sle-ha.prod and
# installs rpm sle-ha-release. Cluster software is not installed.
- name: Assert that High Availability Extension is present
ansible.builtin.assert:
that:
- "'sle-ha-release' in ansible_facts.packages"
- __ha_cluster_ha_ext_stat.stat.exists
success_msg: "High Availability Extension was detected."
fail_msg: "High Availability Extension is not registered!
Register HA Extension before executing again."
# Fatal fail will occur if any of cluster nodes is missing HAE
any_errors_fatal: true
- name: Check High Availability Extension presence using product file
ansible.builtin.stat:
path: /etc/products.d/sle-ha.prod
register: __ha_cluster_ha_ext_stat

# Registering HA Extension creates file /etc/products.d/sle-ha.prod and
# installs rpm sle-ha-release. Cluster software is not installed.
- name: Assert that High Availability Extension is present
ansible.builtin.assert:
that:
- "'sle-ha-release' in ansible_facts.packages"
- __ha_cluster_ha_ext_stat.stat.exists
success_msg: "High Availability Extension was detected."
fail_msg: "High Availability Extension is not registered!
Register HA Extension before executing again."
# Fatal fail will occur if any of cluster nodes is missing HAE
any_errors_fatal: true
8 changes: 8 additions & 0 deletions tasks/set_vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
loop:
- "{{ ansible_facts['os_family'] }}.yml"
- "{{ ansible_facts['distribution'] }}.yml"
# Enables loading of shared vars between SLES and SLES_SAP
- >-
{{ ansible_facts['distribution'].split("_")[0] ~ '_' ~
ansible_facts['distribution_major_version'] }}.yml
- >-
{{ ansible_facts['distribution'].split("_")[0] ~ '_' ~
ansible_facts['distribution_version'] }}.yml

- >-
{{ ansible_facts['distribution'] ~ '_' ~
ansible_facts['distribution_major_version'] }}.yml
Expand Down
25 changes: 1 addition & 24 deletions tasks/shell_crmsh/create-and-push-cib.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,6 @@
check_mode: false
changed_when: not ansible_check_mode

# Meta-attrs is-managed will conflict with maintenance mode as well as
# individual resource maintenance attributes. Expect will skip their deletion.
# - name: Put cluster in maintenance mode to freeze cib changes
# ansible.builtin.expect:
# command: crm --force configure property maintenance-mode=true
# responses:
# ".*is-managed.*": "n"
# ".*already.*": "n"
# run_once: true # noqa: run_once[task]
# check_mode: false
# changed_when: true

# Maintenance mode is required, because CIB version changes with cluster
# status changes, resulting in shadow CIB outdated and unable to patch.
- name: Put cluster in maintenance mode to freeze cib changes
Expand Down Expand Up @@ -124,6 +112,7 @@
## Ensure that stonith is disabled before executing crm configure.
## This is usually disabled by running crm init.
## Executing crm configure without stonith results in "config not valid".
## This results in Blind Faith: not fencing unseen nodes warning
- name: Set property stonith-enabled to false
ansible.builtin.command:
cmd: >-
Expand Down Expand Up @@ -329,18 +318,6 @@
when: __ha_cluster_cib_diff.rc == 1
run_once: true # noqa: run_once[task]

# Meta-attrs is-managed will conflict with maintenance mode as well as
# individual resource maintenance attributes. Expect will skip their deletion.
# - name: Disable maintenance mode
# ansible.builtin.expect:
# command: crm --force configure property maintenance-mode=false
# responses:
# ".*is-managed.*": "n"
# ".*already.*": "n"
# check_mode: false
# changed_when: true
# run_once: true # noqa: run_once[task]

- name: Disable maintenance mode
ansible.builtin.command:
cmd: crm --force configure property maintenance-mode=false
Expand Down
38 changes: 20 additions & 18 deletions tasks/shell_crmsh/crm-cib-constraint-colocation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
failed_when:
- "'does not exist' in __ha_cluster_constraint_resource_leader.stderr"

# Verify if constraint.resourceresource_follower_leader.id exists
# Verify if constraint.resource_follower_leader.id exists
- name: Verify resource_follower presence {{ constraint.resource_follower.id }}
ansible.builtin.command:
cmd: >-
Expand Down Expand Up @@ -49,46 +49,48 @@
check_mode: false
changed_when: not ansible_check_mode

# Expect module is used to combat crmsh freezing when asking for user input

# Yes command will skip all prompts, resulting in rc>0
# exit $? reveals return code of crm, which is masked by yes
- name: Configure colocation constraint {{ __ha_cluster_constraint_id }}
ansible.builtin.expect:
command: |
crm -c {{ __ha_cluster_crm_shadow }}
configure colocation {{ __ha_cluster_constraint_id }}
ansible.builtin.shell:
cmd: |
yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} \
configure colocation {{ __ha_cluster_constraint_id }} \
{% for option in constraint.options | d([]) if option.name == 'score' %}
{{ option.value | lower | replace('infinity', 'inf') | quote }}:
{{ option.value | lower | replace('infinity', 'inf') | quote }}: \
{% else %}
inf:
inf: \
{% endfor %}
{% if constraint.resource_follower.role | d() and
constraint.resource_follower.role | lower in __ha_cluster_crmsh_roles %}
{{ constraint.resource_follower.id | quote }}:{{
constraint.resource_follower.role | lower | capitalize | quote }}
constraint.resource_follower.role | lower | capitalize | quote }} \
{% else %}
{{ constraint.resource_follower.id | quote }}
{{ constraint.resource_follower.id | quote }} \
{% endif %}
{% if constraint.resource_leader.role | d() and
constraint.resource_leader.role | lower in __ha_cluster_crmsh_roles %}
{{ constraint.resource_leader.id | quote }}:{{
constraint.resource_leader.role | lower | capitalize | quote }}
constraint.resource_leader.role | lower | capitalize | quote }} \
{% else %}
{{ constraint.resource_leader.id | quote }}
{{ constraint.resource_leader.id | quote }} \
{% endif %}
{% for option in constraint.options | d([]) if option.name != 'score' %}
{{ option.name | quote }}={{ option.value | quote }}
{{ option.name | quote }}={{ option.value | quote }} \
{% endfor %}
# ERROR and "Do you still want to commit (y/n)?" trigger response "n".
responses:
".*ERROR.*": "n"
".*y/n*": "n"
;exit $?
check_mode: false
changed_when: not ansible_check_mode
ignore_errors: true
register: __ha_cluster_crmsh_output


- name: Display crm command error details
ansible.builtin.fail:
msg: "{{ __ha_cluster_crmsh_output.stdout_lines }}"
msg:
- "{{ __ha_cluster_crmsh_output.stderr_lines }}"
- "{{ __ha_cluster_crmsh_output.stdout_lines }}"
when:
- __ha_cluster_crmsh_output is defined
- __ha_cluster_crmsh_output.rc != 0
55 changes: 29 additions & 26 deletions tasks/shell_crmsh/crm-cib-constraint-location.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,49 +42,52 @@
check_mode: false
changed_when: not ansible_check_mode

# Expect module is used to combat crmsh freezing when asking for user input

# Yes command will skip all prompts, resulting in rc>0
# exit $? reveals return code of crm, which is masked by yes
- name: Configure location constraint {{ __ha_cluster_constraint_id }}
ansible.builtin.expect:
command: |
crm -c {{ __ha_cluster_crm_shadow }}
ansible.builtin.shell:
cmd: >-
yes 'n' | crm -c {{ __ha_cluster_crm_shadow }}
configure location {{ __ha_cluster_constraint_id }}
{% if constraint.resource.pattern | d() %}
{%- if constraint.resource.pattern | d() %}
/{{ constraint.resource.pattern | quote }}/
{% else %}
{%- else %}
{{ constraint.resource.id | quote }}
{% endif %}\
{% if constraint.resource.role | d() and
{%- endif %}
{%- if constraint.resource.role | d() and
constraint.resource.role | lower in __ha_cluster_crmsh_roles %}
role={{
constraint.resource.role | lower | capitalize | quote
}}
{% endif %}
rule
{% for option in constraint.options | d([]) if option.name == 'score' %}
{{ option.value | lower | replace('infinity', 'inf') | quote }}:
{% else %}
inf:
{% endfor %}
{% if constraint.rule | d() %}
rule {{ constraint.rule }}
{% else %}
'\'#uname eq {{ constraint.node }}
{% endif %}
{%- endif %}
{%- if constraint.rule | d() %}
rule {{ __score }}{{ constraint.rule }}
{%- else %}
{{ __score }} {{ constraint.node }}
{%- endif %}
{% for option in constraint.options | d([]) if option.name != 'score' %}
{{ option.name | quote }}={{ option.value | quote }}
\ {{ option.name | quote }}={{ option.value | quote }}
{% endfor %}
# ERROR and "Do you still want to commit (y/n)?" trigger response "n".
responses:
".*ERROR.*": "n"
".*y/n*": "n"
;exit $?
check_mode: false
changed_when: not ansible_check_mode
ignore_errors: true
register: __ha_cluster_crmsh_output
vars:
__score: >-
{%- for option in constraint.options | d([]) if option.name == 'score' %}
{{ option.value | lower | replace('infinity', 'inf') | quote }}:
{%- else %}
inf:
{%- endfor %}


- name: Display crm command error details
ansible.builtin.fail:
msg: "{{ __ha_cluster_crmsh_output.stdout_lines }}"
msg:
- "{{ __ha_cluster_crmsh_output.stderr_lines }}"
- "{{ __ha_cluster_crmsh_output.stdout_lines }}"
when:
- __ha_cluster_crmsh_output is defined
- __ha_cluster_crmsh_output.rc != 0
30 changes: 16 additions & 14 deletions tasks/shell_crmsh/crm-cib-constraint-order.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,37 +48,39 @@
check_mode: false
changed_when: not ansible_check_mode

# Expect module is used to combat crmsh freezing when asking for user input

# Yes command will skip all prompts, resulting in rc>0
# exit $? reveals return code of crm, which is masked by yes
- name: Configure order constraint {{ __ha_cluster_constraint_id }}
ansible.builtin.expect:
command: |
crm -c {{ __ha_cluster_crm_shadow }}
configure order {{ __ha_cluster_constraint_id | quote }}
ansible.builtin.shell:
cmd: |
yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} \
configure order {{ __ha_cluster_constraint_id | quote }} \
{% for option in constraint.options | d([]) if option.name == 'kind' %}
{{ option.value | quote }}:
{{ option.value | quote }}: \
{% endfor %}
{{ constraint.resource_first.id
| quote }}:{{ constraint.resource_first.action
| default('start') | quote }}
| default('start') | quote }} \
{{ constraint.resource_then.id
| quote }}:{{ constraint.resource_then.action
| default('start') | quote }}
| default('start') | quote }} \
{% for option in constraint.options | d([])
if option.name != 'score' and option.name != 'kind'%}
{{ option.name | quote }}={{ option.value | quote }}
{{ option.name | quote }}={{ option.value | quote }} \
{% endfor %}
# ERROR and "Do you still want to commit (y/n)?" trigger response "n".
responses:
".*ERROR.*": "n"
".*y/n*": "n"
;exit $?
check_mode: false
changed_when: not ansible_check_mode
ignore_errors: true
register: __ha_cluster_crmsh_output


- name: Display crm command error details
ansible.builtin.fail:
msg: "{{ __ha_cluster_crmsh_output.stdout_lines }}"
msg:
- "{{ __ha_cluster_crmsh_output.stderr_lines }}"
- "{{ __ha_cluster_crmsh_output.stdout_lines }}"
when:
- __ha_cluster_crmsh_output is defined
- __ha_cluster_crmsh_output.rc != 0
Loading
Loading