object-storage: Restoring multi volume support in UFO.

* Currently, the users of UFO are restricted to use just one volume
  at any given point of time. This patch removes this limitation.

* The usage of gluster-swift-gen-builders has also changed. With this
  commit the users should mention the list of volumes that they want
  to expose through UFO. So, only the volumes mentioned during the
  ring file generation can be accessed.

  Usage: gluster-swift-gen-builders <vol-name1> [<vol-name2>]...

This is an intermediate fix until we remove the account, container and
object server processes. Once we have this frame work running, it will
completely eliminate the ring files.

Change-Id: I9ad3808519fec9c7c60ad846c4f8b653117a8337
BUG: 909053
Signed-off-by: Mohammed Junaid <junaid@redhat.com>
Reviewed-on: http://review.gluster.org/4485
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Reviewed-by: Peter Portante <pportant@redhat.com>
This commit is contained in:
Mohammed Junaid 2013-02-07 07:42:34 +05:30 committed by Vijay Bellur
parent b7b5c51bbe
commit 598ca6bbaa
6 changed files with 168 additions and 10 deletions

View File

@ -166,7 +166,8 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
NULL };
char *invalid_volnames[] = {"volume", "type", "subvolumes", "option",
"end-volume", "all", NULL};
"end-volume", "all", "volume_not_in_ring",
NULL};
char *w = NULL;
int op_count = 0;
int32_t replica_count = 1;

View File

@ -1,9 +1,25 @@
#!/bin/bash
# Note that these port numbers must match the configured values for the
# various servers in their configuration files.
declare -A port=(["account.builder"]=6012 ["container.builder"]=6011 \
["object.builder"]=6010)
builder_files="account.builder container.builder object.builder"
function create {
swift-ring-builder $1 create 0 1 1
swift-ring-builder $1 add z1-127.0.0.1:$2/$3_ 100.0
swift-ring-builder $1 create 1 1 1 >> /tmp/out
}
function add {
swift-ring-builder $1 add z$2-127.0.0.1:$3/$4_ 100.0
}
function rebalance {
swift-ring-builder $1 rebalance
}
function build {
swift-ring-builder $1
}
@ -12,8 +28,17 @@ if [ "$1x" = "x" ]; then
exit 1
fi
# Note that these port numbers must match the configured values for the
# various servers in their configuration files.
create account.builder 6012 $1
create container.builder 6011 $1
create object.builder 6010 $1
for builder_file in $builder_files
do
create $builder_file
zone=1
for volname in $@
do
add $builder_file $zone ${port[$builder_file]} $volname
zone=$(expr $zone + 1)
done
rebalance $builder_file
build $builder_file
done

View File

@ -67,7 +67,7 @@ def mount(root, drive):
if drive == export:
break
else:
logging.error('No export found in %r matching drive %s', el, drive)
logging.error('No export found in %r matching drive, %s', el, drive)
return False
# NOTE: root is typically the default value of /mnt/gluster-object

View File

@ -16,7 +16,8 @@
from webob.exc import HTTPBadRequest
import swift.common.constraints
from gluster.swift.common import Glusterfs
import swift.common.ring as _ring
from gluster.swift.common import Glusterfs, ring
MAX_OBJECT_NAME_COMPONENT_LENGTH = swift.common.constraints.constraints_conf_int(
@ -80,3 +81,9 @@ def gluster_check_mount(root, drive):
# Replace the original check mount with ours
swift.common.constraints.check_mount = gluster_check_mount
# Save the original Ring class
__Ring = _ring.Ring
# Replace the original Ring class
_ring.Ring = ring.Ring

View File

@ -0,0 +1,82 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# Licensed 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.
from ConfigParser import ConfigParser
from swift.common.ring import ring
from swift.common.utils import search_tree
from gluster.swift.common.Glusterfs import SWIFT_DIR
reseller_prefix = "AUTH_"
conf_files = search_tree(SWIFT_DIR, "proxy-server*", 'conf')
if conf_files:
conf_file = conf_files[0]
_conf = ConfigParser()
if conf_files and _conf.read(conf_file):
if _conf.defaults().get("reseller_prefix", None):
reseller_prefix = _conf.defaults().get("reseller_prefix")
else:
for key, value in _conf._sections.items():
if value.get("reseller_prefix", None):
reseller_prefix = value["reseller_prefix"]
break
if not reseller_prefix.endswith('_'):
reseller_prefix = reseller_prefix + '_'
class Ring(ring.Ring):
def get_nodes(self, account, container=None, obj=None):
"""
Get the partition and nodes for an account/container/object.
If a node is responsible for more than one replica, it will
only appear in the output once.
:param account: account name
:param container: container name
:param obj: object name
:returns: a tuple of (partition, list of node dicts)
Each node dict will have at least the following keys:
====== ===============================================================
id unique integer identifier amongst devices
weight a float of the relative weight of this device as compared to
others; this indicates how many partitions the builder will try
to assign to this device
zone integer indicating which zone the device is in; a given
partition will not be assigned to multiple devices within the
same zone
ip the ip address of the device
port the tcp port of the device
device the device's name on disk (sdb1, for example)
meta general use 'extra' field; for example: the online date, the
hardware description
====== ===============================================================
"""
false_node = [{'zone': 1, 'weight': 100.0, 'ip': '127.0.0.1', 'id': 0, \
'meta': '', 'device': 'volume_not_in_ring', \
'port': 6012}]
if account.startswith(reseller_prefix):
acc_name = account.replace(reseller_prefix, '', 1)
else:
acc_name = account
part = 0
seen_ids = set()
nodes = [dev for dev in self._devs \
if dev['device'] == acc_name \
and not (dev['id'] in seen_ids \
or seen_ids.add(dev['id']))]
if not nodes:
nodes = false_node
return part, nodes

View File

@ -0,0 +1,43 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# Licensed 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.
import unittest
import gluster.swift.common.constraints
from gluster.swift.common.ring import *
from gluster.swift.common.Glusterfs import SWIFT_DIR
def _mock_ring_data():
return [{'zone': 1, 'weight': 100.0, 'ip': '127.0.0.1', 'port': 6012, \
'meta': '', 'device': 'test', 'id': 0},
{'zone': 2, 'weight': 100.0, 'ip': '127.0.0.1', 'id': 1, \
'meta': '', 'device': 'iops', 'port': 6012}]
class TestRing(unittest.TestCase):
""" Tests for common.utils """
def setUp(self):
self.ring = Ring(SWIFT_DIR, ring_name='object')
def test_get_notes(self):
try:
__devs = self.ring._devs
self.ring._devs = _mock_ring_data()
part, node = self.ring.get_nodes('test')
assert node[0]['device'] == 'test'
part, node = self.ring.get_nodes('test2')
assert node
assert node[0]['device'] == 'volume'
finally:
self.ring._devs = __devs