Skip to content

Commit

Permalink
Add initial support for Urchin
Browse files Browse the repository at this point in the history
Adds support in ccm for urchin, it aligns with  urchin limitation: e.g.
support vnodes configuration only and supports only an install-dir

To set environemnt execute source urchin_env.sh

Requires an addition of a conf/ directory and a cassandra.yaml file
under urchin install_dir

To create an urchin cluster execute:
ccm create urchin --urchin --vnodes -n 3 --install-dir=<urchin-dir>

To start nodes execute:
ccm start --no-wait

On start starts all instances with --smp 1 (does not pin instances to
specific cores)

To stop and remove execute:
ccm remove

requires two urchin patches: Enable seeds parsing from configuration,
and Asias bootstrap patch

Signed-off-by: Shlomi Livne <shlomi@cloudius-systems.com>
  • Loading branch information
slivne committed Jun 14, 2015
1 parent 2063466 commit eb60291
Show file tree
Hide file tree
Showing 5 changed files with 658 additions and 4 deletions.
5 changes: 4 additions & 1 deletion ccmlib/cluster_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ccmlib import common
from ccmlib.cluster import Cluster
from ccmlib.dse_cluster import DseCluster
from ccmlib.urchin_cluster import UrchinCluster
from ccmlib import repository
from ccmlib.node import Node

Expand All @@ -24,7 +25,9 @@ def load(path, name):
install_dir = data['cassandra_dir']
repository.validate(install_dir)

if common.isDse(install_dir):
if common.isUrchin(install_dir):
cluster = UrchinCluster(path, data['name'], install_dir=install_dir, create_directory=False)
elif common.isDse(install_dir):
cluster = DseCluster(path, data['name'], install_dir=install_dir, create_directory=False)
else:
cluster = Cluster(path, data['name'], install_dir=install_dir, create_directory=False)
Expand Down
9 changes: 8 additions & 1 deletion ccmlib/cmds/cluster_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ccmlib.cluster import Cluster
from ccmlib.cmds.command import Cmd
from ccmlib.dse_cluster import DseCluster
from ccmlib.urchin_cluster import UrchinCluster
from ccmlib.dse_node import DseNode
from ccmlib.cluster_factory import ClusterFactory

Expand Down Expand Up @@ -102,9 +103,13 @@ def get_parser(self):
help="Enable client authentication (only vaid with --ssl)", default=False)
parser.add_option('--node-ssl', type="string", dest="node_ssl_path",
help="Path to keystore.jks and truststore.jks for internode encryption", default=None)
parser.add_option("--urchin", action="store_true", dest="urchin",
help="Must specify --install-dir holding Urchin")
return parser

def validate(self, parser, options, args):
if options.urchin and (not options.install_dir or not options.vnodes):
parser.error("must specify install_dir and vnodes when using urchin")
Cmd.validate(self, parser, options, args, cluster_name=True)
if options.ipprefix and options.ipformat:
parser.print_help()
Expand All @@ -123,7 +128,9 @@ def validate(self, parser, options, args):

def run(self):
try:
if self.options.dse or (not self.options.version and common.isDse(self.options.install_dir)):
if self.options.urchin:
cluster = UrchinCluster(self.path, self.name, install_dir=self.options.install_dir, version=self.options.version, verbose=True)
elif self.options.dse or (not self.options.version and common.isDse(self.options.install_dir)):
cluster = DseCluster(self.path, self.name, install_dir=self.options.install_dir, version=self.options.version, dse_username=self.options.dse_username, dse_password=self.options.dse_password, opscenter=self.options.opscenter, verbose=True)
else:
cluster = Cluster(self.path, self.name, install_dir=self.options.install_dir, version=self.options.version, verbose=True)
Expand Down
31 changes: 29 additions & 2 deletions ccmlib/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
CASSANDRA_CONF_DIR= "conf"
DSE_CASSANDRA_CONF_DIR="resources/cassandra/conf"
OPSCENTER_CONF_DIR= "conf"
URCHIN_CONF_DIR= "conf"


CASSANDRA_CONF = "cassandra.yaml"
LOG4J_CONF = "log4j-server.properties"
Expand Down Expand Up @@ -302,6 +304,18 @@ def isDse(install_dir):
dse_script = os.path.join(bin_dir, 'dse')
return os.path.exists(dse_script)

def isUrchin(install_dir):
if install_dir is None:
raise ArgumentError('Undefined installation directory')

bin_dir = os.path.join(install_dir, os.path.join('build','release'))

if not os.path.exists(bin_dir):
return False

urchin_exec = os.path.join(bin_dir, 'seastar')
return os.path.exists(urchin_exec)

def isOpscenter(install_dir):
if install_dir is None:
raise ArgumentError('Undefined installation directory')
Expand All @@ -324,15 +338,18 @@ def validate_install_dir(install_dir):
raise ArgumentError('%s does not appear to be a cassandra or dse installation directory. Please use absolute pathing (e.g. C:/cassandra.' % install_dir)

bin_dir = os.path.join(install_dir, BIN_DIR)
if isDse(install_dir):
if isUrchin(install_dir):
bin_dir = os.path.join(install_dir, os.path.join('build','release'))
conf_dir = os.path.join(install_dir, URCHIN_CONF_DIR)
elif isDse(install_dir):
conf_dir = os.path.join(install_dir, DSE_CASSANDRA_CONF_DIR)
elif isOpscenter(install_dir):
conf_dir = os.path.join(install_dir, OPSCENTER_CONF_DIR)
else:
conf_dir = os.path.join(install_dir, CASSANDRA_CONF_DIR)
cnd = os.path.exists(bin_dir)
cnd = cnd and os.path.exists(conf_dir)
if not isOpscenter(install_dir):
if isUrchin(install_dir) or not isOpscenter(install_dir):
cnd = cnd and os.path.exists(os.path.join(conf_dir, CASSANDRA_CONF))
if not cnd:
raise ArgumentError('%s does not appear to be a cassandra or dse installation directory' % install_dir)
Expand Down Expand Up @@ -426,6 +443,9 @@ def get_version_from_build(install_dir=None, node_path=None):
if install_dir is None and node_path is not None:
install_dir = get_install_dir_from_cluster_conf(node_path)
if install_dir is not None:
urchin_version = get_urchin_version(install_dir)
if (urchin_version is not None):
return urchin_version
# 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):
Expand All @@ -444,6 +464,13 @@ def get_version_from_build(install_dir=None, node_path=None):
return match.group(1)
raise CCMError("Cannot find version")

def get_urchin_version(install_dir):
# FIXME
if isUrchin(install_dir):
return '3.0'
else:
return None

def get_dse_version(install_dir):
for root, dirs, files in os.walk(install_dir):
for file in files:
Expand Down
30 changes: 30 additions & 0 deletions ccmlib/urchin_cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# ccm clusters
import os
import shutil
import subprocess
import signal

from six import iteritems
from ccmlib import repository
from ccmlib.cluster import Cluster
from ccmlib.urchin_node import UrchinNode
from ccmlib import common

class UrchinCluster(Cluster):
def __init__(self, path, name, partitioner=None, install_dir=None, create_directory=True, version=None, verbose=False, **kwargs):
super(UrchinCluster, self).__init__(path, name, partitioner, install_dir, create_directory, version, verbose)

def load_from_repository(self, version, verbose):
raise Exception("no impl");
# return repository.setup_dse(version, self.dse_username, self.dse_password, verbose)

def create_node(self, name, auto_bootstrap, thrift_interface, storage_interface, jmx_port, remote_debug_port, initial_token, save=True, binary_interface=None):
return UrchinNode(name, self, auto_bootstrap, thrift_interface, storage_interface, jmx_port, remote_debug_port, initial_token, save, binary_interface)

def start(self, no_wait=False, verbose=False, wait_for_binary_proto=False, wait_other_notice=False, jvm_args=[], profile_options=None):
started = super(UrchinCluster, self).start(no_wait, verbose, wait_for_binary_proto, wait_other_notice, jvm_args, profile_options)
return started

def cassandra_version(self):
# FIXME
return '3.0'
Loading

0 comments on commit eb60291

Please sign in to comment.