ccmlib/hcd/hcd_node.py (115 lines of code) (raw):

# 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. # DataStax Hyper-Converged Database (HCD) nodes from __future__ import absolute_import, with_statement import os import shutil import yaml from distutils.version import LooseVersion from six.moves import urllib, xrange from ccmlib import common, node from ccmlib.node import Node class HcdNode(Node): """ Provides interactions to a HCD node. """ @staticmethod def get_version_from_build(install_dir=None, node_path=None, cassandra=False): if install_dir is None and node_path is not None: install_dir = node.get_install_dir_from_cluster_conf(node_path) if install_dir is not None: # Binary cassandra installs will have a 0.version.txt file version_file = os.path.join(install_dir, '0.version.txt') if os.path.exists(version_file): with open(version_file) as f: return LooseVersion(f.read().strip()) # For HCD look for a hcd*.jar and extract the version number from ccmlib.hcd.hcd_cluster import get_hcd_version hcd_version = get_hcd_version(install_dir) if (hcd_version is not None): if cassandra: from ccmlib.hcd.hcd_cluster import get_hcd_cassandra_version return get_hcd_cassandra_version(install_dir) else: return LooseVersion(hcd_version) raise common.CCMError("Cannot find version") def __init__(self, name, cluster, auto_bootstrap, thrift_interface, storage_interface, jmx_port, remote_debug_port, initial_token, save=True, binary_interface=None, byteman_port='0', environment_variables=None, derived_cassandra_version=None, **kwargs): super(HcdNode, self).__init__(name, cluster, auto_bootstrap, thrift_interface, storage_interface, jmx_port, remote_debug_port, initial_token, save, binary_interface, byteman_port, environment_variables=environment_variables, derived_cassandra_version=derived_cassandra_version, **kwargs) def get_install_cassandra_root(self): return os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra') def get_node_cassandra_root(self): return os.path.join(self.get_path(), 'resources', 'cassandra') def get_conf_dir(self): """ Returns the path to the directory where Cassandra config are located """ return os.path.join(self.get_path(), 'resources', 'cassandra', 'conf') def get_tool(self, toolname): return common.join_bin(os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra'), 'bin', toolname) def get_tool_args(self, toolname): return [common.join_bin(os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra'), 'bin', toolname)] def get_env(self): env = self.make_hcd_env(self.get_install_dir(), self.get_path()) # adjust JAVA_HOME to one supported by this hcd_version env = common.update_java_version(jvm_version=None, install_dir=self.get_install_dir(), env=env, info_message=self.name) return env def node_setup(self, version, verbose): from ccmlib.hcd.hcd_cluster import setup_hcd dir, v = setup_hcd(version, verbose=verbose) return dir def get_launch_bin(self): cdir = os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd') launch_bin = common.join_bin(cdir, 'bin', 'hcd') shutil.copy(launch_bin, self.get_bin_dir()) return common.join_bin(self.get_path(), 'bin', 'hcd') def add_custom_launch_arguments(self, args): args.append('cassandra') def copy_config_files(self): for product in ['hcd', 'cassandra']: src_conf = os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', product, 'conf') dst_conf = os.path.join(self.get_path(), 'resources', product, 'conf') if not os.path.isdir(src_conf): continue if os.path.isdir(dst_conf): common.rmdirs(dst_conf) shutil.copytree(src_conf, dst_conf) def import_bin_files(self): common.copy_directory(os.path.join(self.get_install_dir(), 'bin'), self.get_bin_dir()) cassandra_bin_dir = os.path.join(self.get_path(), 'resources', 'cassandra', 'bin') shutil.rmtree(cassandra_bin_dir, ignore_errors=True) os.makedirs(cassandra_bin_dir) common.copy_directory(os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra', 'bin'), cassandra_bin_dir) if os.path.exists(os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra', 'tools')): cassandra_tools_dir = os.path.join(self.get_path(), 'resources', 'cassandra', 'tools') shutil.rmtree(cassandra_tools_dir, ignore_errors=True) shutil.copytree(os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra', 'tools'), cassandra_tools_dir) self.export_hcd_home_in_hcd_env_sh() def export_hcd_home_in_hcd_env_sh(self): ''' Due to the way CCM lays out files, separating the repository from the node(s) confs, the `hcd-env.sh` script of each node needs to have its HCD_HOME var set and exported. The stock `hcd-env.sh` file includes a commented-out place to do exactly this, intended for installers. Basically: read in the file, write it back out and add the two lines. 'sstableloader' is an example of a node script that depends on this, when used in a CCM-built cluster. ''' with open(self.get_bin_dir() + "/hcd-env.sh", "r") as hcd_env_sh: buf = hcd_env_sh.readlines() with open(self.get_bin_dir() + "/hcd-env.sh", "w") as out_file: for line in buf: out_file.write(line) if line == "# This is here so the installer can force set HCD_HOME\n": out_file.write("HCD_HOME=" + os.path.join(self.get_install_dir(), 'distribution', 'hcd' , 'target', 'hcd') + "\nexport HCD_HOME\n") def _get_directories(self): dirs = [] for i in ['commitlogs', 'saved_caches', 'logs', 'bin', 'resources']: dirs.append(os.path.join(self.get_path(), i)) for x in xrange(0, self.cluster.data_dir_count): dirs.append(os.path.join(self.get_path(), 'data{0}'.format(x))) return dirs def make_hcd_env(self, install_dir, node_path): env = os.environ.copy() env['MAX_HEAP_SIZE'] = os.environ.get('CCM_MAX_HEAP_SIZE', '500M') env['HEAP_NEWSIZE'] = os.environ.get('CCM_HEAP_NEWSIZE', '50M') env['MAX_DIRECT_MEMORY'] = os.environ.get('CCM_MAX_DIRECT_SIZE', '2048M') env['HCD_HOME'] = os.path.join(install_dir, 'distribution', 'hcd' , 'target', 'hcd') env['HCD_CONF'] = os.path.join(node_path, 'resources', 'hcd', 'conf') env['CASSANDRA_HOME'] = os.path.join(install_dir, 'distribution', 'hcd' , 'target', 'hcd', 'resources', 'cassandra') env['CASSANDRA_CONF'] = os.path.join(node_path, 'resources', 'cassandra', 'conf') env['HCD_LOG_ROOT'] = os.path.join(node_path, 'logs', 'hcd') env['CASSANDRA_LOG_DIR'] = os.path.join(node_path, 'logs') return env