Skip to content

Commit ad53c72

Browse files
committed
c-foreach-nt: reimplemented in Python
1 parent 83eddce commit ad53c72

File tree

5 files changed

+123
-76
lines changed

5 files changed

+123
-76
lines changed

c-foreach-nt

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,25 @@
1-
#!/bin/bash
2-
3-
set -e
4-
5-
# If we're running from an uninstalled working-copy, then use the working-copy
6-
# version of the shell include, otherwise assume it is installed.
7-
if [ -r `dirname $0`/functions ]; then
8-
. `dirname $0`/functions
9-
else
10-
. /usr/share/cassandra-tools-wmf/functions
11-
fi
12-
13-
14-
magenta() {
15-
printf "\033[%sm%s\033[0m\n" "35" "$1"
16-
}
17-
18-
cyan() {
19-
printf "\033[%sm%s\033[0m\n" "36" "$1"
20-
}
21-
22-
COUNT=0
23-
24-
# Prepends the supplied instance ID to each line of stdin.
25-
prepend_instance_id() {
26-
while read line; do
27-
if test $(($COUNT % 2)) = 0; then
28-
magenta "$1: $line"
29-
else
30-
cyan "$1: $line"
31-
fi
32-
done
33-
}
34-
35-
for i in `instances`; do
36-
nodetool-$i "$@" | prepend_instance_id $i
37-
COUNT=$(($COUNT+1))
38-
done
39-
40-
# Kludge for hosts not yet converted to multi-instance
41-
if test $COUNT -le 1; then
42-
nodetool "$@"
43-
fi
1+
#!/usr/bin/python
2+
3+
4+
import logging
5+
import sys
6+
7+
from cassandra.tools import get_instances
8+
from cassandra.tools.config import LOG_LEVEL
9+
from cassandra.tools.nodetool import NodetoolOutputWriter
10+
from cassandra.tools.output import MAGENTA, CYAN
11+
12+
13+
logging.basicConfig(level=LOG_LEVEL)
14+
15+
16+
def main():
17+
for (i, instance) in enumerate(get_instances()):
18+
color = MAGENTA if (i % 2) == 0 else CYAN
19+
instance.nodetool.run(
20+
*sys.argv[1:],
21+
output=NodetoolOutputWriter(color, False, instance.name))
22+
23+
24+
if __name__ == "__main__":
25+
main()

cassandra/tools/commands.py

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,16 @@
11

22
import logging
3-
import subprocess
43

5-
from .config import DRY_RUN
6-
7-
8-
def __ansi_color(code):
9-
def inner(text, bold=False):
10-
c = code
11-
if bold:
12-
c = "1;%s" % c
13-
return "\033[%sm%s\033[0m" % (c, text)
14-
return inner
4+
from subprocess import Popen, PIPE
155

16-
17-
RED = __ansi_color("31")
18-
GREEN = __ansi_color("32")
19-
YELLOW = __ansi_color("33")
20-
BLUE = __ansi_color("34")
21-
MAGENTA = __ansi_color("35")
22-
CYAN = __ansi_color("36")
23-
WHITE = __ansi_color("37")
6+
from .config import DRY_RUN
247

258

26-
def call(*args, **kwargs):
9+
def call(*args):
2710
if DRY_RUN:
2811
logging.info("%s (dry-run)", " ".join(list(args)))
2912
return 0
3013
else:
31-
return subprocess.call(list(args))
14+
process = Popen(args, stdout=PIPE, stderr=PIPE)
15+
(stdout, stderr) = process.communicate()
16+
return (process.returncode, stdout, stderr)

cassandra/tools/instances.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
import logging
55
import os
66
import socket
7+
from time import sleep
78
import yaml
89

9-
from time import sleep
10-
1110
from .commands import call
1211
from .config import DESCRIPTOR_DIR
1312
from .nodetool import Nodetool
@@ -52,8 +51,22 @@ def restart(self, retries=10, delay=6):
5251
self.nodetool.run("disablethrift")
5352
self.__log_info("Draining...")
5453
self.nodetool.run("drain")
54+
55+
# Restart Cassandra
5556
self.__log_info("Restarting service %s", self.service_name)
56-
call("systemctl", "restart", self.service_name)
57+
(retcode, stdout, stderr) = call("systemctl", "restart", self.service_name)
58+
if retcode != 0:
59+
self.__log_error("systemctl returned exit code %s", retcode)
60+
stdout = stdout.rstrip()
61+
stderr = stderr.rstrip()
62+
if stdout:
63+
for line in stdout.splitlines():
64+
self.__log_error(line)
65+
if stderr:
66+
for line in stderr.splitlines():
67+
self.__log_error(line)
68+
69+
# Wait for Cassandra to come back up before continuing
5770
listening = False
5871
for i in range(0, retries):
5972
logging.debug("Testing CQL port (attempt #%s)", (i + 1))

cassandra/tools/nodetool.py

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,66 @@
11

22

3-
import logging
3+
from sys import stdout, stderr
44

5-
from .commands import call
5+
from .commands import call
6+
from .output import RED, NONE
67

78

89
class Nodetool(object):
910
def __init__(self, host, port):
1011
self.host = host
11-
self.port = str(port)
12+
self.port = port
13+
14+
def run(self, *args, **kwargs):
15+
writer = kwargs.get("output", NodetoolOutputWriter())
16+
assert isinstance(writer, NodetoolOutputWriter)
17+
18+
command = ["nodetool", "--host", self.host, "--port", str(self.port)] + list(args)
19+
(retcode, output, error) = call(*command)
20+
21+
writer.output(output)
22+
writer.error(error)
1223

13-
def run(self, *args):
14-
command = ["nodetool", "--host", self.host, "--port", self.port] + list(args)
15-
retcode = call(*command)
1624
if retcode != 0:
17-
raise NodetoolCmdException("nodetool returned status {}".format(retcode))
25+
raise NodetoolCommandException(
26+
"nodetool command returned exit code {}".format(retcode),
27+
retcode)
28+
29+
def __repr__(self):
30+
return "Nodetool({}, {})".format(self.host, self.port)
31+
32+
def __str__(self):
33+
return "{}:{}".format(self.host, self.port)
34+
35+
class NodetoolOutputWriter(object):
36+
def __init__(self, color=None, bold=False, prefix=None):
37+
self.color = color if color else NONE
38+
self.bold = bold
39+
self.prefix = prefix
40+
41+
def output(self, text):
42+
data = text.rstrip()
43+
if data:
44+
for line in data.split('\n'):
45+
print >>stdout, self.color("{}{}".format(self.__prefix(), line), self.bold)
46+
47+
def error(self, text):
48+
data = text.rstrip()
49+
if data:
50+
for line in data.split('\n'):
51+
print >>stderr, RED("{}{}".format(self.__prefix(), line), True)
52+
53+
def __prefix(self):
54+
return "{}: ".format(self.prefix) if self.prefix else ""
55+
56+
def __repr__(self):
57+
return "NodetoolOutputWriter(prefix={})".format(self.prefix)
58+
59+
def __str__(self):
60+
return repr(self)
61+
62+
class NodetoolCommandException(Exception):
63+
def __init__(self, message, retcode):
64+
self.retcode = retcode
65+
super(NodetoolCommandException, self).__init__(message)
1866

19-
class NodetoolCmdException(Exception):
20-
pass

cassandra/tools/output.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
def __ansi_color(code):
3+
def inner(text, bold=False):
4+
c = code
5+
if bold:
6+
c = "1;%s" % c
7+
return "\033[%sm%s\033[0m" % (c, text)
8+
return inner
9+
10+
def __none(text, bold=False):
11+
return text
12+
13+
14+
RED = __ansi_color("31")
15+
GREEN = __ansi_color("32")
16+
YELLOW = __ansi_color("33")
17+
BLUE = __ansi_color("34")
18+
MAGENTA = __ansi_color("35")
19+
CYAN = __ansi_color("36")
20+
WHITE = __ansi_color("37")
21+
NONE = __none

0 commit comments

Comments
 (0)