| """ |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| """ |
| |
| # Python Imports |
| import os |
| import re |
| |
| # Ambari Commons & Resource Management Imports |
| from resource_management.core import shell |
| from resource_management.core.exceptions import Fail |
| from resource_management.core.logger import Logger |
| from resource_management.core.resources.system import Execute |
| from resource_management.libraries.functions import format |
| from resource_management.libraries.functions import stack_select |
| from resource_management.libraries.functions import StackFeature |
| from resource_management.libraries.functions.stack_features import check_stack_feature |
| from resource_management.libraries.functions.version import format_stack_version |
| |
| |
| def deregister(): |
| """ |
| Runs the "hive --service hiveserver2 --deregister <version>" command to |
| de-provision the server in preparation for an upgrade. This will contact |
| ZooKeeper to remove the server so that clients that attempt to connect |
| will be directed to other servers automatically. Once all |
| clients have drained, the server will shutdown automatically. |
| |
| However, since Ambari does not support Hive Server rolling upgrades due to the port change |
| affecting Hive Clients not using the ZK discovery service, the daemon might be forcefully |
| killed before it has been deregistered and drained. |
| |
| This function will obtain the Kerberos ticket if security is enabled. |
| :return: |
| """ |
| import params |
| |
| Logger.info('HiveServer2 executing "deregister" command to complete upgrade...') |
| |
| if params.security_enabled: |
| kinit_command=format("{kinit_path_local} -kt {smoke_user_keytab} {smokeuser_principal}; ") |
| Execute(kinit_command,user=params.smokeuser) |
| |
| # calculate the current hive server version |
| current_hiveserver_version = _get_current_hiveserver_version() |
| if current_hiveserver_version is None: |
| raise Fail('Unable to determine the current HiveServer2 version to deregister.') |
| |
| # fallback when upgrading because <stack-root>/current/hive-server2/conf/conf may not exist |
| hive_server_conf_dir = params.hive_server_conf_dir |
| if not os.path.exists(hive_server_conf_dir): |
| hive_server_conf_dir = "/etc/hive/conf" |
| |
| # deregister |
| hive_execute_path = params.execute_path |
| # If upgrading, the upgrade-target hive binary should be used to call the --deregister command. |
| # If downgrading, the downgrade-source hive binary should be used to call the --deregister command. |
| # By now <stack-selector-tool> has been called to set 'current' to target-stack |
| if params.downgrade_from_version is not None: |
| hive_execute_path = _get_hive_execute_path(params.downgrade_from_version) |
| |
| command = format('hive --config {hive_server_conf_dir} --service hiveserver2 --deregister ' + current_hiveserver_version) |
| Execute(command, user=params.hive_user, path=hive_execute_path, tries=1 ) |
| |
| |
| def _get_hive_execute_path(stack_version_formatted): |
| """ |
| Returns the exact execute path to use for the given stack-version. |
| This method does not return the "current" path |
| :param stack_version_formatted: Exact stack-version to use in the new path |
| :return: Hive execute path for the exact stack-version |
| """ |
| import params |
| |
| hive_execute_path = params.execute_path |
| formatted_stack_version = format_stack_version(stack_version_formatted) |
| if formatted_stack_version and check_stack_feature(StackFeature.ROLLING_UPGRADE, formatted_stack_version): |
| # hive_bin |
| new_hive_bin = format('{stack_root}/{stack_version_formatted}/hive/bin') |
| if (os.pathsep + params.hive_bin) in hive_execute_path: |
| hive_execute_path = hive_execute_path.replace(os.pathsep + params.hive_bin, os.pathsep + new_hive_bin) |
| # hadoop_bin_dir |
| new_hadoop_bin = stack_select.get_hadoop_dir_for_stack_version("bin", stack_version_formatted) |
| old_hadoop_bin = params.hadoop_bin_dir |
| if new_hadoop_bin and len(new_hadoop_bin) > 0 and (os.pathsep + old_hadoop_bin) in hive_execute_path: |
| hive_execute_path = hive_execute_path.replace(os.pathsep + old_hadoop_bin, os.pathsep + new_hadoop_bin) |
| return hive_execute_path |
| |
| |
| def _get_current_hiveserver_version(): |
| """ |
| Runs "hive --version" and parses the result in order |
| to obtain the current version of hive. |
| |
| :return: the hiveserver2 version, returned by "hive --version" |
| """ |
| import params |
| |
| try: |
| # When downgrading the source version should be the version we are downgrading from |
| source_version = params.version_for_stack_feature_checks |
| if params.downgrade_from_version is not None: |
| source_version = params.downgrade_from_version |
| |
| hive_execute_path = _get_hive_execute_path(source_version) |
| version_hive_bin = params.hive_bin |
| formatted_source_version = format_stack_version(source_version) |
| if formatted_source_version and check_stack_feature(StackFeature.ROLLING_UPGRADE, formatted_source_version): |
| version_hive_bin = format('{stack_root}/{source_version}/hive/bin') |
| command = format('{version_hive_bin}/hive --version') |
| return_code, output = shell.call(command, user=params.hive_user, path=hive_execute_path) |
| except Exception, e: |
| Logger.error(str(e)) |
| raise Fail('Unable to execute hive --version command to retrieve the hiveserver2 version.') |
| |
| if return_code != 0: |
| raise Fail('Unable to determine the current HiveServer2 version because of a non-zero return code of {0}'.format(str(return_code))) |
| |
| match = re.search('^(Hive) ([0-9]+.[0-9]+.\S+)', output, re.MULTILINE) |
| |
| if match: |
| current_hive_server_version = match.group(2) |
| return current_hive_server_version |
| else: |
| raise Fail('The extracted hiveserver2 version "{0}" does not matching any known pattern'.format(output)) |
| |
| |