glusterfs

Форк
0
/
volfilter.py 
168 строк · 4.6 Кб
1
# Copyright (c) 2010-2011 Red Hat, Inc.
2
#
3
# This file is part of HekaFS.
4
#
5
# HekaFS is free software: you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License, version 3, as published by the Free
7
# Software Foundation.
8
#
9
# HekaFS is distributed in the hope that it will be useful, but WITHOUT ANY
10
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License * along
14
# with HekaFS.  If not, see <http://www.gnu.org/licenses/>.
15

16
from __future__ import print_function
17
import copy
18
import string
19
import sys
20
import types
21

22
good_xlators = [
23
	"cluster/afr",
24
	"cluster/dht",
25
	"cluster/distribute",
26
	"cluster/replicate",
27
	"cluster/stripe",
28
	"debug/io-stats",
29
	"features/access-control",
30
	"features/locks",
31
	"features/marker",
32
	"features/uidmap",
33
	"performance/io-threads",
34
	"protocol/client",
35
	"protocol/server",
36
	"storage/posix",
37
]
38

39
def copy_stack (old_xl, suffix, recursive=False):
40
	if recursive:
41
		new_name = old_xl.name + "-" + suffix
42
	else:
43
		new_name = suffix
44
	new_xl = Translator(new_name)
45
	new_xl.type = old_xl.type
46
	# The results with normal assignment here are . . . amusing.
47
	new_xl.opts = copy.deepcopy(old_xl.opts)
48
	for sv in old_xl.subvols:
49
		new_xl.subvols.append(copy_stack(sv, suffix, True))
50
	# Patch up the path at the bottom.
51
	if new_xl.type == "storage/posix":
52
		new_xl.opts["directory"] += ("/" + suffix)
53
	return new_xl
54

55
def cleanup (parent, graph):
56
	if parent.type in good_xlators:
57
		# Temporary fix so that HekaFS volumes can use the
58
		# SSL-enabled multi-threaded socket transport.
59
		if parent.type == "protocol/server":
60
			parent.type = "protocol/server2"
61
			parent.opts["transport-type"] = "ssl"
62
		elif parent.type == "protocol/client":
63
			parent.type = "protocol/client2"
64
			parent.opts["transport-type"] = "ssl"
65
		sv = []
66
		for child in parent.subvols:
67
			sv.append(cleanup(child, graph))
68
		parent.subvols = sv
69
	else:
70
		parent = cleanup(parent.subvols[0], graph)
71
	return parent
72

73
class Translator:
74
	def __init__ (self, name):
75
		self.name = name
76
		self.type = ""
77
		self.opts = {}
78
		self.subvols = []
79
		self.dumped = False
80
	def __repr__ (self):
81
		return "<Translator %s>" % self.name
82

83
def load (path):
84
	# If it's a string, open it; otherwise, assume it's already a
85
	# file-like object (most notably from urllib*).
86
	if type(path) in (str,):
87
		fp = file(path, "r")
88
	else:
89
		fp = path
90
	all_xlators = {}
91
	xlator = None
92
	last_xlator = None
93
	while True:
94
		text = fp.readline()
95
		if text == "":
96
			break
97
		text = text.split()
98
		if not len(text):
99
			continue
100
		if text[0] == "volume":
101
			if xlator:
102
				raise RuntimeError("nested volume definition")
103
			xlator = Translator(text[1])
104
			continue
105
		if not xlator:
106
			raise RuntimeError("text outside volume definition")
107
		if text[0] == "type":
108
			xlator.type = text[1]
109
			continue
110
		if text[0] == "option":
111
			xlator.opts[text[1]] = ''.join(text[2:])
112
			continue
113
		if text[0] == "subvolumes":
114
			for sv in text[1:]:
115
				xlator.subvols.append(all_xlators[sv])
116
			continue
117
		if text[0] == "end-volume":
118
			all_xlators[xlator.name] = xlator
119
			last_xlator = xlator
120
			xlator = None
121
			continue
122
		raise RuntimeError("unrecognized keyword %s" % text[0])
123
	if xlator:
124
		raise RuntimeError("unclosed volume definition")
125
	return all_xlators, last_xlator
126

127
def generate (graph, last, stream=sys.stdout):
128
	for sv in last.subvols:
129
		if not sv.dumped:
130
			generate(graph, sv, stream)
131
			print("", file=stream)
132
			sv.dumped = True
133
	print("volume %s" % last.name, file=stream)
134
	print("    type %s" % last.type, file=stream)
135
	for k, v in last.opts.items():
136
		print("    option %s %s" % (k, v), file=stream)
137
	if last.subvols:
138
		print("    subvolumes %s" % ''.join(
139
			[ sv.name for sv in last.subvols ]), file=stream)
140
	print("end-volume", file=stream)
141

142
def push_filter (graph, old_xl, filt_type, opts={}):
143
	suffix = "-" + old_xl.type.split("/")[1]
144
	if len(old_xl.name) > len(suffix):
145
		if old_xl.name[-len(suffix):] == suffix:
146
			old_xl.name = old_xl.name[:-len(suffix)]
147
	new_xl = Translator(old_xl.name+suffix)
148
	new_xl.type = old_xl.type
149
	new_xl.opts = old_xl.opts
150
	new_xl.subvols = old_xl.subvols
151
	graph[new_xl.name] = new_xl
152
	old_xl.name += ("-" + filt_type.split("/")[1])
153
	old_xl.type = filt_type
154
	old_xl.opts = opts
155
	old_xl.subvols = [new_xl]
156
	graph[old_xl.name] = old_xl
157

158
def delete (graph, victim):
159
	if len(victim.subvols) != 1:
160
		raise RuntimeError("attempt to delete non-unary translator")
161
	for xl in graph.itervalues():
162
		while xl.subvols.count(victim):
163
			i = xl.subvols.index(victim)
164
			xl.subvols[i] = victim.subvols[0]
165

166
if __name__ == "__main__":
167
	graph, last = load(sys.argv[1])
168
	generate(graph, last)
169

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.