diff --git a/tasks/enable-repositories/Suse.yml b/tasks/enable-repositories/Suse.yml index 2ae1bc89..bb95e518 100644 --- a/tasks/enable-repositories/Suse.yml +++ b/tasks/enable-repositories/Suse.yml @@ -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 diff --git a/tasks/set_vars.yml b/tasks/set_vars.yml index 13d0c69c..0bcb3d22 100644 --- a/tasks/set_vars.yml +++ b/tasks/set_vars.yml @@ -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 diff --git a/tasks/shell_crmsh/create-and-push-cib.yml b/tasks/shell_crmsh/create-and-push-cib.yml index d3a1e20f..b3a0490a 100644 --- a/tasks/shell_crmsh/create-and-push-cib.yml +++ b/tasks/shell_crmsh/create-and-push-cib.yml @@ -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 @@ -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: >- @@ -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 diff --git a/tasks/shell_crmsh/crm-cib-constraint-colocation.yml b/tasks/shell_crmsh/crm-cib-constraint-colocation.yml index cf3ac7c7..fefb69fa 100644 --- a/tasks/shell_crmsh/crm-cib-constraint-colocation.yml +++ b/tasks/shell_crmsh/crm-cib-constraint-colocation.yml @@ -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: >- @@ -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 diff --git a/tasks/shell_crmsh/crm-cib-constraint-location.yml b/tasks/shell_crmsh/crm-cib-constraint-location.yml index 684539b4..0abc6e67 100644 --- a/tasks/shell_crmsh/crm-cib-constraint-location.yml +++ b/tasks/shell_crmsh/crm-cib-constraint-location.yml @@ -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 diff --git a/tasks/shell_crmsh/crm-cib-constraint-order.yml b/tasks/shell_crmsh/crm-cib-constraint-order.yml index bcd766a6..eccebae4 100644 --- a/tasks/shell_crmsh/crm-cib-constraint-order.yml +++ b/tasks/shell_crmsh/crm-cib-constraint-order.yml @@ -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 diff --git a/tasks/shell_crmsh/crm-cib-constraint-set.yml b/tasks/shell_crmsh/crm-cib-constraint-set.yml index 3654bb1a..917d8d22 100644 --- a/tasks/shell_crmsh/crm-cib-constraint-set.yml +++ b/tasks/shell_crmsh/crm-cib-constraint-set.yml @@ -1,15 +1,15 @@ # SPDX-License-Identifier: MIT --- # Verify if resources in sets exist -- name: Verify set resources presence +- name: Verify presence of resources in resource_ids lists ansible.builtin.command: cmd: >- crm -c {{ __ha_cluster_crm_shadow }} - configure show {% for set in constraint.resource_sets %} - {% for resource in set.resource_ids %} - {{ resource | quote }} - {% endfor %} - {% endfor %} + configure show {{ item.resource_ids | join(' ') }} + loop: "{{ constraint.resource_sets }}" + loop_control: + index_var: resource_ids_index + label: "resource_ids_{{ resource_ids_index }}" register: __ha_cluster_constraint_resource_set changed_when: false failed_when: @@ -42,58 +42,74 @@ check_mode: false changed_when: not ansible_check_mode -# Expect module is used to combat crmsh freezing when asking for user input +- name: Empty list of resources in set + ansible.builtin.set_fact: + __ha_cluster_resource_ids_string: '' + +# All resource_ids lists are combined together into one string per set. +# Example: (rsc1 rsc2 sequential=false) (rsc3 rsc4 rsc5 require-all=true) +- name: Create list of resources in set + ansible.builtin.set_fact: + __ha_cluster_resource_ids_string: + "{{ __ha_cluster_resource_ids_string | d('') ~ ' ' ~ __resource_ids }}" + loop: "{{ constraint.resource_sets }}" + loop_control: + index_var: resource_ids_index + label: "resource_ids_{{ resource_ids_index }}" + vars: + __resource_ids: >- + \({{ item.resource_ids | join(' ') }} + {%- for option in item.options | d([]) if option.name != 'score' %} + {{ option.name | quote }}={{ option.value | quote }} + {%- endfor %}\) + + +# Yes command will skip all prompts, resulting in rc>0 +# exit $? reveals return code of crm, which is masked by yes - name: Configure {{ constraint_type }} constraint set '{{ __ha_cluster_constraint_id }}' # noqa name[template] - ansible.builtin.expect: - command: | - crm -c {{ __ha_cluster_crm_shadow }} configure + ansible.builtin.shell: + cmd: >- + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} configure {{ constraint_type if constraint_type != 'ticket' else 'rsc_ticket' }} {{ __ha_cluster_constraint_id }} - {% if constraint_type != 'ticket' %} - {% if constraint_type == 'order' %} - {% for option in constraint.options | d([]) + {%- if constraint_type != 'ticket' %} + {%- if constraint_type == 'order' %} + {%- for option in constraint.options | d([]) if option.name == 'kind' %} {{ option.value | quote }}: - {% else %} + {%- else %} Mandatory: - {% endfor %} - {% elif constraint_type == 'colocation' %} - {% for option in constraint.options | d([]) + {%- endfor %} + {%- elif constraint_type == 'colocation' %} + {%- for option in constraint.options | d([]) if option.name == 'score' %} {{ option.value | lower | replace('infinity', 'inf') | quote }}: - {% else %} + {%- else %} inf: - {% endfor %} - {% endif %} - {% for set in constraint.resource_sets %} - ({% for resource in set.resource_ids %} - {{ resource | quote }} - {% endfor %}) - {% endfor %} - {% else %} - {% for set in constraint.resource_sets %} - {{ constraint.ticket | quote }}: - {% for resource in set.resource_ids %} - {{ resource | quote }} - {% endfor %} - {% endfor %} - {% endif %} - {% for option in constraint.options | d([]) %} - {{ 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" + {%- endfor %} + {%- endif %} + {{ __ha_cluster_resource_ids_string }} + {%- else %} + {%- for set in constraint.resource_sets %} + {{ constraint.ticket | quote }}: {{ __ha_cluster_resource_ids_string }} + {%- endfor %} + {%- endif %} + ;exit $? check_mode: false changed_when: not ansible_check_mode ignore_errors: true register: __ha_cluster_crmsh_output + when: + - __ha_cluster_resource_ids_string is defined + - __ha_cluster_resource_ids_string | length > 0 + - 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 diff --git a/tasks/shell_crmsh/crm-cib-constraint-ticket.yml b/tasks/shell_crmsh/crm-cib-constraint-ticket.yml index 74e06aa4..25756805 100644 --- a/tasks/shell_crmsh/crm-cib-constraint-ticket.yml +++ b/tasks/shell_crmsh/crm-cib-constraint-ticket.yml @@ -38,35 +38,36 @@ 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 ticket constraint {{ __ha_cluster_constraint_id }} - ansible.builtin.expect: - command: | - crm -c {{ __ha_cluster_crm_shadow }} - configure rsc_ticket {{ __ha_cluster_constraint_id }} - {{ constraint.ticket | quote }}: + ansible.builtin.shell: + cmd: | + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} configure rsc_ticket \ + {{ __ha_cluster_constraint_id }} {{ constraint.ticket | quote }}: \ {% if constraint.resource.role | d() and constraint.resource.role | lower in __ha_cluster_crmsh_roles %} {{ constraint.resource.id | quote }}:{{ - constraint.resource.role | lower | capitalize | quote }} + constraint.resource.role | lower | capitalize | quote }} \ {% else %} - {{ constraint.resource.id | quote }} + {{ constraint.resource.id | quote }} \ {% endif %} {% for option in constraint.options | d([]) %} - {{ 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 diff --git a/tasks/shell_crmsh/crm-cib-resource-clone.yml b/tasks/shell_crmsh/crm-cib-resource-clone.yml index 489a2aab..fbe07941 100644 --- a/tasks/shell_crmsh/crm-cib-resource-clone.yml +++ b/tasks/shell_crmsh/crm-cib-resource-clone.yml @@ -11,7 +11,7 @@ failed_when: - "'does not exist' in __ha_cluster_constraint_resource.stderr" -- name: Define resouce clone resource_clone.id '{{ +- name: Define resource clone resource_clone.id '{{ resource_clone.id | d('cln_' + resource_clone.resource_id) }}' ansible.builtin.set_fact: __ha_cluster_resource_id: @@ -19,7 +19,7 @@ else 'cln_' + resource_clone.resource_id | quote }}" # Verify if Shadow CIB already contains same resource id. -- name: Verify resouce clone presence {{ __ha_cluster_resource_id }} +- name: Verify resource clone presence {{ __ha_cluster_resource_id }} ansible.builtin.command: cmd: >- crm -c {{ __ha_cluster_crm_shadow }} @@ -29,7 +29,7 @@ failed_when: false # Delete resource id in Shadow CIB to avoid errors during cibadmin patch. -- name: Delete present resouce clone {{ __ha_cluster_resource_id }} +- name: Delete present resource clone {{ __ha_cluster_resource_id }} ansible.builtin.command: cmd: >- crm --force -c {{ __ha_cluster_crm_shadow }} @@ -38,36 +38,38 @@ check_mode: false changed_when: not ansible_check_mode + # Clone is default resource type, unless attribute ms: true is specified # Pacemaker 2.0 deprecated use of ms, but it is still valid and supported # solution for SAP Hana clusters on SUSE using SAPHanaSR. -# 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 resource clone {{ __ha_cluster_resource_id }} - ansible.builtin.expect: - command: | - crm -c {{ __ha_cluster_crm_shadow }} - configure {% if resource_clone.ms is defined and - resource_clone.ms %} ms {% else %} clone {% endif %} - {{ __ha_cluster_resource_id }} + ansible.builtin.shell: + cmd: | + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} configure \ + {% if resource_clone.ms is defined and resource_clone.ms %} + ms {% else %} clone {% endif %} \ + {{ __ha_cluster_resource_id }} \ {{ resource_clone.resource_id | quote }} \ {% if resource_clone.meta_attrs[0].attrs | default(False) %} - meta - {% for attr in resource_clone.meta_attrs[0].attrs -%} - {{ attr.name | quote }}={{ attr.value | quote }} + meta {% for attr in resource_clone.meta_attrs[0].attrs -%} + {{ attr.name | quote }}={{ attr.value | quote }} \ {% endfor %} {% endif %} - # 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 diff --git a/tasks/shell_crmsh/crm-cib-resource-group.yml b/tasks/shell_crmsh/crm-cib-resource-group.yml index a2ce43a9..758a94f7 100644 --- a/tasks/shell_crmsh/crm-cib-resource-group.yml +++ b/tasks/shell_crmsh/crm-cib-resource-group.yml @@ -33,33 +33,34 @@ 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 resource group {{ resource_group.id }} - ansible.builtin.expect: - command: | - crm -c {{ __ha_cluster_crm_shadow }} configure group - {{ resource_group.id | quote }} + ansible.builtin.shell: + cmd: | + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} configure group \ + {{ resource_group.id | quote }} \ {% for resource in resource_group.resource_ids %} - {{ resource | quote }} - {% endfor %} \ + {{ resource | quote }} \ + {% endfor %} {% if resource_group.meta_attrs[0].attrs | default(False) %} - meta - {% for attr in resource_group.meta_attrs[0].attrs -%} - {{ attr.name | quote }}={{ attr.value | quote }} + meta {% for attr in resource_group.meta_attrs[0].attrs -%} + {{ attr.name | quote }}={{ attr.value | quote }} \ {% endfor %} {% endif %} - # 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 diff --git a/tasks/shell_crmsh/crm-cib-resource-primitive.yml b/tasks/shell_crmsh/crm-cib-resource-primitive.yml index 3940b55f..5ed189ea 100644 --- a/tasks/shell_crmsh/crm-cib-resource-primitive.yml +++ b/tasks/shell_crmsh/crm-cib-resource-primitive.yml @@ -18,50 +18,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 resource primitive {{ resource.id }} - ansible.builtin.expect: # noqa jinja[spacing] - command: | - crm -c {{ __ha_cluster_crm_shadow }} configure primitive + ansible.builtin.shell: # noqa jinja[spacing] + cmd: | + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} configure primitive \ {{ resource.id | quote }} {{ resource.agent | quote }} \ {% if resource.instance_attrs[0].attrs | default(False) %} - params - {% for attr in resource.instance_attrs[0].attrs -%} - {{ attr.name | quote }}={{ attr.value | quote }} + params {% for attr in resource.instance_attrs[0].attrs -%} + {{ attr.name | quote }}={{ attr.value | quote }} \ {% endfor %} - {% endif %}\ + {% endif %} {% if resource.meta_attrs[0].attrs | default(False) %} - meta - {% for attr in resource.meta_attrs[0].attrs -%} - {{ attr.name | quote }}={{ attr.value | quote }} + meta {% for attr in resource.meta_attrs[0].attrs -%} + {{ attr.name | quote }}={{ attr.value | quote }} \ {% endfor %} {% endif %} {% if resource.operations | default(False) %}\ {% for operation in resource.operations %} {% if operation.action | default(False) %} - op {{ operation.action | quote }} + op {{ operation.action | quote }} \ {% if operation.attrs | default(False) %} {%- for attr in operation.attrs -%} - {{ attr.name | quote }}={{ attr.value | quote }} + {{ attr.name | quote }}={{ attr.value | quote }} \ {% endfor %} - {% if not loop.last %}\ - {% endif %} {% endif %} {% endif %} {% endfor %} {% endif %} - # 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 diff --git a/tasks/shell_crmsh/crm-cib-stonith-level.yml b/tasks/shell_crmsh/crm-cib-stonith-level.yml index f0a61022..8a177544 100644 --- a/tasks/shell_crmsh/crm-cib-stonith-level.yml +++ b/tasks/shell_crmsh/crm-cib-stonith-level.yml @@ -20,25 +20,24 @@ 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 fencing_topology - ansible.builtin.expect: - command: >- - crm -c {{ __ha_cluster_crm_shadow }} configure fencing_topology + ansible.builtin.shell: + cmd: | + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} \ + configure fencing_topology \ {% for stonith_level in ha_cluster_stonith_levels -%} {% if stonith_level.target | d() %} - {{ stonith_level.target | quote }}: + {{ stonith_level.target | quote }}: \ {% elif stonith_level.target_pattern | d() %} - regexp%{{ stonith_level.target_pattern | quote }}: + regexp%{{ stonith_level.target_pattern | quote }}: \ {% endif %} {% for resource_id in stonith_level.resource_ids %} - {{ resource_id | quote }} + {{ resource_id | quote }} \ {% endfor %} {% 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 @@ -46,7 +45,9 @@ - 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 diff --git a/tasks/shell_crmsh/crm-rsc-op-defaults.yml b/tasks/shell_crmsh/crm-rsc-op-defaults.yml index 9101c992..7ab3b340 100644 --- a/tasks/shell_crmsh/crm-rsc-op-defaults.yml +++ b/tasks/shell_crmsh/crm-rsc-op-defaults.yml @@ -24,38 +24,36 @@ check_mode: false changed_when: not ansible_check_mode -# TODO: rule and score are not implemented due to cmrsh syntax +# Rule and score are supposed to be part of constraints instead +# Yes command will skip all prompts, resulting in rc>0 +# exit $? reveals return code of crm, which is masked by yes - name: Configure rsc/op defaults set {{ defaults_set.id | d(defaults_set_index) }} - ansible.builtin.expect: - command: > - crm -c {{ __ha_cluster_crm_shadow }} - configure + ansible.builtin.shell: + cmd: | + yes 'n' | crm -c {{ __ha_cluster_crm_shadow }} configure \ {% if operations %} - op_defaults + op_defaults \ {% else %} - rsc_defaults - {% endif %} - {% if defaults_set.id is defined %} - {{ defaults_set.id }}: + rsc_defaults \ {% endif %} {% if defaults_set.attrs | d([]) %} {% for attr in defaults_set.attrs %} - {{ attr.name | quote }}={{ attr.value | quote }} + {{ attr.name | quote }}={{ attr.value | quote }} \ {% endfor %} {% endif %} - # 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 diff --git a/vars/SLES_15.yml b/vars/SLES_15.yml index 3db0e930..1229c5e0 100644 --- a/vars/SLES_15.yml +++ b/vars/SLES_15.yml @@ -2,3 +2,40 @@ # Variables for SLES set in ansible_facts['distribution'] and # 15 set in ansible_facts['distribution_major_version'] + +# Variables specific to following versions: +# - SUSE Linux Enterprise Server for SAP Applications 15 +# - SUSE Linux Enterprise Server 15 + +# ClusterTools2 removed because it is SLES4SAP specific +# patterns-ha-ha_sles requires SLES 15 SP5+ or SLES4SAP 15 +__ha_cluster_role_essential_packages: + - 'patterns-ha-ha_sles' + - 'cluster-glue' + - 'openssl' +# - 'libxml2-tools' + +# Pattern patterns-ha-ha_sles includes all important packages for cluster on SLES +# Pattern is available only as part of SUSE Linux Enterprise High Availability Extension +# - 'conntrack-tools' +# - 'corosync' +# - 'crmsh' +# - 'csync2' +# - 'ctdb' +# - 'drbd' +# - 'drbd-utils' +# - 'fence-agents' +# - 'ha-cluster-bootstrap' +# - 'ha-cluster-webui' +# - 'ldirectord' +# - 'lvm2-lockd' +# - 'ocfs2-tools' +# - 'pacemaker' +# - 'python3-dateutil' +# - 'release-notes-ha' +# - 'resource-agents' +# - 'sbd' +# - 'yast2-cluster' +# - 'yast2-drbd' +# - 'yast2-iplb' +# - 'chrony' diff --git a/vars/Suse.yml b/vars/Suse.yml index 6ca017ae..3cc06b3f 100644 --- a/vars/Suse.yml +++ b/vars/Suse.yml @@ -12,14 +12,7 @@ __ha_cluster_role_essential_packages: - 'corosync' - 'crmsh' - 'fence-agents' - - 'ha-cluster-bootstrap' - - 'patterns-ha-ha_sles' - 'resource-agents' - - 'cluster-glue' - - 'socat' - - 'libxml2-tools' - - 'rsyslog' - - 'openssl' __ha_cluster_fullstack_node_packages: []