diff --git a/package/yast2-sap-ha.changes b/package/yast2-sap-ha.changes index e95373e..959479a 100644 --- a/package/yast2-sap-ha.changes +++ b/package/yast2-sap-ha.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Mon Nov 4 21:34:50 UTC 2024 - Peter Varkoly + +- yast-sap-ha does not support SAPHanaSR-angi (bsc#1232807) +- Adapt to new SAPHanaSR-angi +- 4.5.12 + ------------------------------------------------------------------- Fri Mar 15 17:38:52 UTC 2024 - Peter Varkoly diff --git a/package/yast2-sap-ha.spec b/package/yast2-sap-ha.spec index daadb2d..6eb6de2 100644 --- a/package/yast2-sap-ha.spec +++ b/package/yast2-sap-ha.spec @@ -17,7 +17,7 @@ Name: yast2-sap-ha -Version: 4.5.11 +Version: 4.5.12 Release: 0 BuildArch: noarch Source0: %{name}-%{version}.tar.bz2 @@ -44,7 +44,6 @@ Requires: openssh Requires: HANA-Firewall >= 2.0.3 %endif Requires: util-linux -Requires: SAPHanaSR Requires: kmod # for pidof Requires: sysvinit-tools diff --git a/src/clients/sap_ha.rb b/src/clients/sap_ha.rb index 834d925..95d3788 100644 --- a/src/clients/sap_ha.rb +++ b/src/clients/sap_ha.rb @@ -244,6 +244,10 @@ def main @sequence["product_check"][:hana] = "file_import_check" if @config.imported Wizard.CreateDialog Wizard.SetDialogTitle("HA Setup for SAP Products") + if not @config.hana.check_rsa_version + Popup.Error("There are no SUSE SAP Resource Agents installed.") + return + end begin if @config.unattended Sequencer.Run(@aliases, @unattended_sequence) diff --git a/src/data/sap_ha/GLOBAL_INI_NON_PROD.erb b/src/data/sap_ha/GLOBAL_INI_NON_PROD.erb deleted file mode 100644 index 333df6e..0000000 --- a/src/data/sap_ha/GLOBAL_INI_NON_PROD.erb +++ /dev/null @@ -1,2 +0,0 @@ -[memorymanager] -global_allocation_limit = <%= @production_constraints[:global_alloc_limit_non] -%> diff --git a/src/data/sap_ha/GLOBAL_INI_SAPHANA_SR b/src/data/sap_ha/GLOBAL_INI_SAPHANA_SR deleted file mode 100644 index 6ddde79..0000000 --- a/src/data/sap_ha/GLOBAL_INI_SAPHANA_SR +++ /dev/null @@ -1,7 +0,0 @@ -[ha_dr_provider_saphanasr] -provider = SAPHanaSR -path = /usr/share/SAPHanaSR/ -execution_order = 1 - -[trace] -ha_dr_saphanasr = info diff --git a/src/data/sap_ha/GLOBAL_INI_SUS_CHKSRV b/src/data/sap_ha/GLOBAL_INI_SUS_CHKSRV deleted file mode 100644 index f9bb4b6..0000000 --- a/src/data/sap_ha/GLOBAL_INI_SUS_CHKSRV +++ /dev/null @@ -1,8 +0,0 @@ -[ha_dr_provider_suschksrv] -provider = susChkSrv -path = /usr/share/SAPHanaSR/ -execution_order = 3 -action_on_lost=stop - -[trace] -ha_dr_suschksrv = info diff --git a/src/data/sap_ha/GLOBAL_INI_SUS_COSTOPT.erb b/src/data/sap_ha/GLOBAL_INI_SUS_COSTOPT.erb deleted file mode 100644 index b35ce3d..0000000 --- a/src/data/sap_ha/GLOBAL_INI_SUS_COSTOPT.erb +++ /dev/null @@ -1,14 +0,0 @@ -[memorymanager] -global_allocation_limit = <%= @production_constraints[:global_alloc_limit_prod] -%> - -[system_replication] -preload_column_tables = <%= @production_constraints[:preload_column_tables] -%> - -[ha_dr_provider_suscostopt] -provider = susCostOpt -path = /usr/share/SAPHanaSR/ -userkey = sus_<%= @system_id -%>_costopt -execution_order = 2 - -[trace] -ha_dr_suscostopt = info diff --git a/src/data/sap_ha/GLOBAL_INI_SUS_TKOVER b/src/data/sap_ha/GLOBAL_INI_SUS_TKOVER deleted file mode 100644 index c5f2055..0000000 --- a/src/data/sap_ha/GLOBAL_INI_SUS_TKOVER +++ /dev/null @@ -1,7 +0,0 @@ -[ha_dr_provider_sustkover] -provider = susTkOver -path = /usr/share/SAPHanaSR/ -execution_order = 2 - -[trace] -ha_dr_sustkover = info diff --git a/src/data/sap_ha/tmpl_cluster_config.erb b/src/data/sap_ha/tmpl_cluster_config.erb deleted file mode 100644 index cd380d6..0000000 --- a/src/data/sap_ha/tmpl_cluster_config.erb +++ /dev/null @@ -1,93 +0,0 @@ -# -# defaults -# - -property cib-bootstrap-options: \ - have-watchdog="true" \ - stonith-enabled="true" \ - stonith-action="reboot" \ - stonith-timeout="150s" - -rsc_defaults rsc-options: \ - resource-stickiness="1000" \ - migration-threshold="3" - -op_defaults op-options: \ - timeout="600" \ - record-pending=true - -# -# production HANA -# - -primitive rsc_SAPHanaTopology_<%= @system_id -%>_HDB<%= @instance -%> ocf:suse:SAPHanaTopology \ - op monitor interval="10" timeout="600" \ - op start interval="0" timeout="600" \ - op stop interval="0" timeout="300" \ - params SID="<%= @system_id -%>" InstanceNumber="<%= @instance -%>" - -clone cln_SAPHanaTopology_<%= @system_id -%>_HDB<%= @instance -%> rsc_SAPHanaTopology_<%= @system_id -%>_HDB<%= @instance -%> \ - meta clone-node-max="1" interleave="true" - -primitive rsc_SAPHana_<%= @system_id -%>_HDB<%= @instance -%> ocf:suse:SAPHana \ - op start interval="0" timeout="3600" \ - op stop interval="0" timeout="3600" \ - op promote interval="0" timeout="3600" \ - op monitor interval="60" role="Master" timeout="700" \ - op monitor interval="61" role="Slave" timeout="700" \ - params SID="<%= @system_id -%>" InstanceNumber="<%= @instance -%>" PREFER_SITE_TAKEOVER="<%= @prefer_takeover -%>" \ - DUPLICATE_PRIMARY_TIMEOUT="7200" AUTOMATED_REGISTER="<%= @auto_register -%>" \ - meta priority="100" - -ms msl_SAPHana_<%= @system_id -%>_HDB<%= @instance -%> rsc_SAPHana_<%= @system_id -%>_HDB<%= @instance -%> \ - meta clone-max="2" clone-node-max="1" interleave="true" maintenance="true" - -primitive rsc_ip_<%= @system_id -%>_HDB<%= @instance -%> ocf:heartbeat:IPaddr2 \ - op monitor interval="10" timeout="20" \ - params ip="<%= @virtual_ip %>" cidr_netmask="<%= @virtual_ip_mask %>" - -<% if @global_config.platform == "azure" %> - -primitive rsc_nc_<%= @system_id -%>_HDB<%= @instance -%> azure-lb port=625<%= @instance -%> \ - op monitor timeout=20s interval=10 \ - meta resource-stickiness=0 - -group g_ip_<%= @system_id -%>_HDB<%= @instance -%> rsc_ip_<%= @system_id -%>_HDB<%= @instance -%> rsc_nc_<%= @system_id -%>_HDB<%= @instance -%> - -colocation col_saphana_ip_<%= @system_id -%>_HDB<%= @instance -%> <%= @additional_instance ? "3000" : "2000" -%>: g_ip_<%= @system_id -%>_HDB<%= @instance -%>:Started \ - msl_SAPHana_<%= @system_id -%>_HDB<%= @instance -%>:Master - -<% else %> - -colocation col_saphana_ip_<%= @system_id -%>_HDB<%= @instance -%> <%= @additional_instance ? "3000" : "2000" -%>: rsc_ip_<%= @system_id -%>_HDB<%= @instance -%>:Started \ - msl_SAPHana_<%= @system_id -%>_HDB<%= @instance -%>:Master - -<% end %> - -order ord_SAPHana_<%= @system_id -%>_HDB<%= @instance -%> Optional: cln_SAPHanaTopology_<%= @system_id -%>_HDB<%= @instance -%> \ - msl_SAPHana_<%= @system_id -%>_HDB<%= @instance -%> - -<% if @additional_instance %> - -# -# non-production HANA and constraints -# - -primitive rsc_SAP_<%= @np_system_id -%>_HDB<%= @np_instance -%> ocf:heartbeat:SAPInstance \ - params InstanceName="<%= @np_system_id -%>_HDB<%= @np_instance -%>_<%= secondary_host_name -%>" \ - MONITOR_SERVICES="hdbindexserver|hdbnameserver" \ - START_PROFILE="/usr/sap/QAS/SYS/profile/<%= @np_system_id -%>_HDB<%= @np_instance -%>_<%= secondary_host_name -%>" \ - op start interval="0" timeout="600" \ - op monitor interval="120" timeout="700" \ - op stop interval="0" timeout="300" - -location loc_<%= @np_system_id -%>_never_<%= primary_host_name -%> rsc_SAP_<%= @np_system_id -%>_HDB<%= @np_instance -%> -inf: <%= primary_host_name -%> - -colocation col_<%= @np_system_id -%>_never_with_<%= @system_id -%>ip -inf: rsc_SAP_<%= @np_system_id -%>_HDB<%= @np_instance -%>:Started \ - rsc_ip_<%= @system_id -%>_HDB<%= @instance -%> - -order ord_<%= @np_system_id -%>_stop_before_<%= @system_id -%>-promote mandatory: \ - rsc_SAP_<%= @np_system_id -%>_HDB<%= @np_instance -%>:stop \ - msl_SAPHana_<%= @system_id -%>_HDB<%= @instance -%>:promote - -<% end %> diff --git a/src/lib/sap_ha/configuration/hana.rb b/src/lib/sap_ha/configuration/hana.rb index 9305366..9437bb3 100644 --- a/src/lib/sap_ha/configuration/hana.rb +++ b/src/lib/sap_ha/configuration/hana.rb @@ -31,26 +31,27 @@ module SapHA module Configuration # HANA configuration class HANA < BaseConfig - attr_accessor :system_id, + attr_accessor :additional_instance, + :auto_register, + :backup_file, + :backup_user, :instance, :np_system_id, :np_instance, - :virtual_ip, - :virtual_ip_mask, + :operation_mode, + :perform_backup, :prefer_takeover, - :auto_register, + :production_constraints, + :replication_mode, + :rsa_version, :site_name_1, :site_name_2, - :backup_file, - :backup_user, - :perform_backup, - :replication_mode, - :operation_mode, - :additional_instance, - :production_constraints + :system_id, + :virtual_ip, + :virtual_ip_mask HANA_REPLICATION_MODES = ["sync", "syncmem", "async"].freeze - HANA_OPERATION_MODES = ["delta_datashipping", "logreplay"].freeze + HANA_OPERATION_MODES = ["logreplay", "logreplay_readaccess", "delta_datashipping"].freeze HANA_FW_SERVICES = [ "hana-cockpit", "hana-database-client", @@ -63,13 +64,17 @@ class HANA < BaseConfig "sap-special-support" ].freeze + Yast.import "UI" + include Yast::I18n include Yast::UIShortcuts include SapHA::System::ShellCommands include Yast::Logger def initialize(global_config) super + textdomain "hana-ha" log.debug "--- #{self.class}.#{__callee__} ---" + @manage_provider = "/usr/bin/SAPHanaSR-manageProvider" @screen_name = "HANA Configuration" @system_id = "" @instance = "" @@ -90,6 +95,7 @@ def initialize(global_config) @np_system_id = "QAS" @np_instance = "10" @production_constraints = {} + @rsa_version = "" end def additional_instance=(value) @@ -97,15 +103,13 @@ def additional_instance=(value) return unless value @prefer_takeover = false @production_constraints = { - global_alloc_limit_prod: "0", - global_alloc_limit_non: "0", - preload_column_tables: "false" + global_alloc_limit_prod: "0", + global_alloc_limit_non: "0", + preload_column_tables: "false" } end - def np_instance=(value) - @np_instance = value - end + attr_writer :np_instance def configured? validate(:silent) @@ -140,7 +144,7 @@ def validate(verbosity = :verbose) "There is no such HANA user store key detected.", "Secure store key") end if @additional_instance - check.hana_is_installed(@np_system_id,@global_config.cluster.other_nodes) + check.hana_is_installed(@np_system_id, @global_config.cluster.other_nodes) check.sap_instance_number(@np_instance, nil, "Non-Production Instance Number") check.sap_sid(@np_system_id, nil, "Non-Production System ID") check.not_equal(@instance, @np_instance, "SAP HANA instance numbers should not collide", @@ -152,6 +156,44 @@ def validate(verbosity = :verbose) end end + # Checks the installed SAP HANA RSA version and sets the variables. + # If no SAP HANA RSA is installed but @rsa_version ist set install it. + # If no SAP HANA RSA is installed and @rsa_version is not set ask and install it. + # Return false if as result no SAP HANA RSA could be installed. + def check_rsa_version + package_to_remove = [] + if Yast::PackageSystem.PackageInstalled("SAPHanaSR") + if @rsa_version == "angi" + package_to_remove << "SAPHanaSR" + else + @manage_provider = "/usr/sbin/SAPHanaSR-manageProvider" + @rsa_version = "classic" + return true + end + end + if Yast::PackageSystem.PackageInstalled("SAPHanaSR-angi") + if @rsa_version == "classic" + package_to_remove << "SAPHanaSR-angi" + else + @rsa_version = "angi" + return true + end + end + @rsa_version = select_rsa_version if @rsa_version.nil? || @rsa_version == "" + case @rsa_version + when "classic" + Yast::PackageSystem.DoInstallAndRemove(["SAPHanaSR"], package_to_remove) + @manage_provider = "/usr/sbin/SAPHanaSR-manageProvider" + @rsa_version = "classic" + when "angi" + Yast::PackageSystem.DoInstallAndRemove(["SAPHanaSR-angi"], package_to_remove) + @rsa_version = "angi" + else + return false + end + true + end + def description prepare_description do |dsc| dsc.header("Production instance") if @additional_instance @@ -225,6 +267,7 @@ def apply(role) SapHA::System::Hana.copy_ssfs_keys(@system_id, secondary_host_name, secondary_password) SapHA::System::Hana.enable_primary(@system_id, @site_name_1) else # secondary node + check_rsa_version SapHA::System::Hana.hdb_stop(@system_id) primary_host_name = @global_config.cluster.other_nodes_ext.first[:hostname] SapHA::System::Hana.enable_secondary(@system_id, @site_name_2, @@ -243,12 +286,40 @@ def finalize activating_msr end - private + private + + def select_rsa_version + content = VBox( + VSpacing(1), + Left(Heading(_("Select the SAP HANA Resource Agents Version to install."))), + VSpacing(1), + RadioButtonGroup( + Id(:version), + HBox( + RadioButton(Id("classic"), _("Classic Version")), + HSpacing(1), + RadioButton(Id("angi"), _("New Version (angi)")) + ) + ), + VSpacing(1), + HBox( + HStretch(), + PushButton(Id(:ok), _("OK")), + HStretch(), + PushButton(Id(:abort), _("Abort")), + HStretch() + ) + ) + Yast::UI.OpenDialog(content) + ui = Yast::UI.UserInput + return Yast::UI.QueryWidget(Id(:version), :CurrentButton) if ui == :ok + nil + end def configure_crm primary_host_name = @global_config.cluster.get_primary_on_primary secondary_host_name = @global_config.cluster.other_nodes_ext.first[:hostname] - crm_conf = Helpers.render_template("tmpl_cluster_config.erb", binding) + crm_conf = Helpers.render_template("tmpl_cluster_config.#{@rsa_version}.erb", binding) file_path = Helpers.write_var_file("cluster.config", crm_conf) out, status = exec_outerr_status("crm", "configure", "load", "update", file_path) @nlog.log_status(status.exitstatus == 0, @@ -259,12 +330,12 @@ def configure_crm # Wait until the node is in state S_IDLE but maximal 60 seconds def wait_idle(node) counter = 0 - while true - out, status = exec_outerr_status("crmadmin","--quiet","--status",node) + loop do + out, status = exec_outerr_status("crmadmin", "--quiet", "--status", node) break if out == "S_IDLE" log.info("wait_idle status of #{node} is #{out}") - counter += 1 - break if counter > 10 + counter += 1 + break if counter > 10 sleep 6 end end @@ -303,7 +374,7 @@ def configure_firewall(role) when "done" @nlog.info("Firewall is already configured") if role != :master - _s = exec_status("/usr/bin/firewall-cmd", "--add-port", "8080/tcp") + _s = exec_status("/usr/bin/firewall-cmd", "--add-port", "8080/tcp") end when "off" @nlog.info("Firewall will be turned off") @@ -317,7 +388,7 @@ def configure_firewall(role) _s = exec_status("/usr/sbin/hana-firewall", "generate-firewalld-services") _s = exec_status("/usr/bin/firewall-cmd", "--reload") if role != :master - _s = exec_status("/usr/bin/firewall-cmd", "--add-port", "8080/tcp") + _s = exec_status("/usr/bin/firewall-cmd", "--add-port", "8080/tcp") end _s = exec_status("/usr/bin/firewall-cmd", "--add-service", "cluster") _s = exec_status("/usr/bin/firewall-cmd", "--permanent", "--add-service", "cluster") @@ -326,14 +397,14 @@ def configure_firewall(role) _s = exec_status("/usr/bin/firewall-cmd", "--permanent", "--add-service", service) end else - @nlog.info("Invalide firewall configuration status") + @nlog.info("Invalide firewall configuration status") end end # Creates the sudoers file def adapt_sudoers if File.exist?(SapHA::Helpers.data_file_path("SUDOERS_HANASR.erb")) - Helpers.write_file("/etc/sudoers.d/saphanasr.conf",Helpers.render_template("SUDOERS_HANASR.erb", binding)) + Helpers.write_file("/etc/sudoers.d/saphanasr.conf", Helpers.render_template("SUDOERS_HANASR.erb", binding)) end end @@ -353,16 +424,16 @@ def adjust_global_ini(role) add_plugin_to_global_ini("SUS_TKOVER", @system_id) end command = ["hdbnsutil", "-reloadHADRProviders"] - su_exec_outerr_status("#{@system_id.downcase}adm", *command) + _out, _status = su_exec_outerr_status("#{@system_id.downcase}adm", *command) end # Activates the plugin in global ini def add_plugin_to_global_ini(plugin, sid) - sr_path = Helpers.data_file_path("GLOBAL_INI_#{plugin}") + sr_path = Helpers.data_file_path("GLOBAL_INI_#{plugin}.#{@rsa_version}") if File.exist?("#{sr_path}.erb") - sr_path = Helpers.write_var_file(plugin, Helpers.render_template("GLOBAL_INI_#{plugin}.erb", binding)) + sr_path = Helpers.write_var_file(plugin, Helpers.render_template("GLOBAL_INI_#{plugin}.#{@rsa_version}.erb", binding)) end - command = ["/usr/sbin/SAPHanaSR-manageProvider", "--add", "--reconfigure", "--sid", sid, sr_path] + command = [@manage_provider, "--add", "--reconfigure", "--sid", sid, sr_path] _out, _status = su_exec_outerr_status("#{sid.downcase}adm", *command) end end