970ea7a919
see https://review.gluster.org/#/c/19788/, https://review.gluster.org/#/c/19871/, https://review.gluster.org/#/c/19952/, https://review.gluster.org/#/c/20104/, https://review.gluster.org/#/c/20162/, https://review.gluster.org/#/c/20185/, https://review.gluster.org/#/c/20207/, https://review.gluster.org/#/c/20227/, https://review.gluster.org/#/c/20307/, https://review.gluster.org/#/c/20320/, https://review.gluster.org/#/c/20332/, https://review.gluster.org/#/c/20364/, and https://review.gluster.org/#/c/20441/ Fixes some overlooked string.join()s: + AFAICT extras/profiler/glusterfs-profiler, extras/prot_filter.py, extras/rebalance.py, and extras/volfilter.py would only manifest at runtime. + xlators/experimental/fdl/src/gen_recon.py is a build-time error when using python3 during the build, thus was not noticed previously when building with python2. + extras/create_new_xlator/generate_xlator.py seems to be example code and does not affect the build or runtime AFAICT Note: Fedora packaging guidelines and SUSE rpmlint require explicit shebangs; popular practices like #!/usr/bin/env python and #!/usr/bin/python are not allowed; they must be #!/usr/bin/python2 or #!/usr/bin/python3 Note: Selected small fixes from 2to3 utility. Specifically apply, basestring, funcattrs, has_key, idioms, map, numliterals, raise, set_literal, types, urllib, and zip have already been applied. Also version agnostic imports for urllib, cpickle, socketserver, _thread, queue, etc., suggested by Aravinda in https://review.gluster.org/#/c/19767/1 Note: these 2to3 fixes report no changes are necessary: asserts, buffer, exec, execfile, exitfunc, filter, getcwdu, imports2, input, intern, itertools, metaclass, methodattrs, ne, next, nonzero, operator, paren, raw_input, reduce, reload, renames, repr, standarderror, sys_exc, throw, tuple_params, xreadlines. Change-Id: Ia1fe2958d136f4303e30f7e7e86b6fe7d7b52c81 updates: #411 Signed-off-by: Kaleb S. KEITHLEY <kkeithle@redhat.com>
169 lines
4.6 KiB
Python
169 lines
4.6 KiB
Python
# Copyright (c) 2010-2011 Red Hat, Inc.
|
|
#
|
|
# This file is part of HekaFS.
|
|
#
|
|
# HekaFS is free software: you can redistribute it and/or modify it under the
|
|
# terms of the GNU General Public License, version 3, as published by the Free
|
|
# Software Foundation.
|
|
#
|
|
# HekaFS is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License * along
|
|
# with HekaFS. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from __future__ import print_function
|
|
import copy
|
|
import string
|
|
import sys
|
|
import types
|
|
|
|
good_xlators = [
|
|
"cluster/afr",
|
|
"cluster/dht",
|
|
"cluster/distribute",
|
|
"cluster/replicate",
|
|
"cluster/stripe",
|
|
"debug/io-stats",
|
|
"features/access-control",
|
|
"features/locks",
|
|
"features/marker",
|
|
"features/uidmap",
|
|
"performance/io-threads",
|
|
"protocol/client",
|
|
"protocol/server",
|
|
"storage/posix",
|
|
]
|
|
|
|
def copy_stack (old_xl, suffix, recursive=False):
|
|
if recursive:
|
|
new_name = old_xl.name + "-" + suffix
|
|
else:
|
|
new_name = suffix
|
|
new_xl = Translator(new_name)
|
|
new_xl.type = old_xl.type
|
|
# The results with normal assignment here are . . . amusing.
|
|
new_xl.opts = copy.deepcopy(old_xl.opts)
|
|
for sv in old_xl.subvols:
|
|
new_xl.subvols.append(copy_stack(sv, suffix, True))
|
|
# Patch up the path at the bottom.
|
|
if new_xl.type == "storage/posix":
|
|
new_xl.opts["directory"] += ("/" + suffix)
|
|
return new_xl
|
|
|
|
def cleanup (parent, graph):
|
|
if parent.type in good_xlators:
|
|
# Temporary fix so that HekaFS volumes can use the
|
|
# SSL-enabled multi-threaded socket transport.
|
|
if parent.type == "protocol/server":
|
|
parent.type = "protocol/server2"
|
|
parent.opts["transport-type"] = "ssl"
|
|
elif parent.type == "protocol/client":
|
|
parent.type = "protocol/client2"
|
|
parent.opts["transport-type"] = "ssl"
|
|
sv = []
|
|
for child in parent.subvols:
|
|
sv.append(cleanup(child, graph))
|
|
parent.subvols = sv
|
|
else:
|
|
parent = cleanup(parent.subvols[0], graph)
|
|
return parent
|
|
|
|
class Translator:
|
|
def __init__ (self, name):
|
|
self.name = name
|
|
self.type = ""
|
|
self.opts = {}
|
|
self.subvols = []
|
|
self.dumped = False
|
|
def __repr__ (self):
|
|
return "<Translator %s>" % self.name
|
|
|
|
def load (path):
|
|
# If it's a string, open it; otherwise, assume it's already a
|
|
# file-like object (most notably from urllib*).
|
|
if type(path) in (str,):
|
|
fp = file(path, "r")
|
|
else:
|
|
fp = path
|
|
all_xlators = {}
|
|
xlator = None
|
|
last_xlator = None
|
|
while True:
|
|
text = fp.readline()
|
|
if text == "":
|
|
break
|
|
text = text.split()
|
|
if not len(text):
|
|
continue
|
|
if text[0] == "volume":
|
|
if xlator:
|
|
raise RuntimeError("nested volume definition")
|
|
xlator = Translator(text[1])
|
|
continue
|
|
if not xlator:
|
|
raise RuntimeError("text outside volume definition")
|
|
if text[0] == "type":
|
|
xlator.type = text[1]
|
|
continue
|
|
if text[0] == "option":
|
|
xlator.opts[text[1]] = ''.join(text[2:])
|
|
continue
|
|
if text[0] == "subvolumes":
|
|
for sv in text[1:]:
|
|
xlator.subvols.append(all_xlators[sv])
|
|
continue
|
|
if text[0] == "end-volume":
|
|
all_xlators[xlator.name] = xlator
|
|
last_xlator = xlator
|
|
xlator = None
|
|
continue
|
|
raise RuntimeError("unrecognized keyword %s" % text[0])
|
|
if xlator:
|
|
raise RuntimeError("unclosed volume definition")
|
|
return all_xlators, last_xlator
|
|
|
|
def generate (graph, last, stream=sys.stdout):
|
|
for sv in last.subvols:
|
|
if not sv.dumped:
|
|
generate(graph, sv, stream)
|
|
print("", file=stream)
|
|
sv.dumped = True
|
|
print("volume %s" % last.name, file=stream)
|
|
print(" type %s" % last.type, file=stream)
|
|
for k, v in last.opts.items():
|
|
print(" option %s %s" % (k, v), file=stream)
|
|
if last.subvols:
|
|
print(" subvolumes %s" % ''.join(
|
|
[ sv.name for sv in last.subvols ]), file=stream)
|
|
print("end-volume", file=stream)
|
|
|
|
def push_filter (graph, old_xl, filt_type, opts={}):
|
|
suffix = "-" + old_xl.type.split("/")[1]
|
|
if len(old_xl.name) > len(suffix):
|
|
if old_xl.name[-len(suffix):] == suffix:
|
|
old_xl.name = old_xl.name[:-len(suffix)]
|
|
new_xl = Translator(old_xl.name+suffix)
|
|
new_xl.type = old_xl.type
|
|
new_xl.opts = old_xl.opts
|
|
new_xl.subvols = old_xl.subvols
|
|
graph[new_xl.name] = new_xl
|
|
old_xl.name += ("-" + filt_type.split("/")[1])
|
|
old_xl.type = filt_type
|
|
old_xl.opts = opts
|
|
old_xl.subvols = [new_xl]
|
|
graph[old_xl.name] = old_xl
|
|
|
|
def delete (graph, victim):
|
|
if len(victim.subvols) != 1:
|
|
raise RuntimeError("attempt to delete non-unary translator")
|
|
for xl in graph.itervalues():
|
|
while xl.subvols.count(victim):
|
|
i = xl.subvols.index(victim)
|
|
xl.subvols[i] = victim.subvols[0]
|
|
|
|
if __name__ == "__main__":
|
|
graph, last = load(sys.argv[1])
|
|
generate(graph, last)
|