Merge remote-tracking branch 'origin/master' into f17

Conflicts:
	.gitignore
	glusterfs.spec
This commit is contained in:
Kaleb S. KEITHLEY 2012-08-22 11:22:09 -04:00
commit 48dde7ef4b
13 changed files with 1596 additions and 1 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ glusterfs-3.2.5.tar.gz
glusterfs-3.2.6.tar.gz
glusterfs-3.2.7.tar.gz
glusterfs-3.3.0.tar.gz
swift-1.4.8.tar.gz

78
gluster-swift-account.init Executable file
View File

@ -0,0 +1,78 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: gluster-swift-account
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Stop: 0 1 6
# Short-Description: Swift account server
# Description: Account server for swift.
### END INIT INFO
# gluster-swift-account: swift account server
#
# chkconfig: - 20 80
# description: Account server for swift.
. /etc/rc.d/init.d/functions
. /usr/share/gluster-swift/functions
name="account"
[ -e "/etc/sysconfig/gluster-swift-$name" ] && . "/etc/sysconfig/gluster-swift-$name"
lockfile="/var/lock/subsys/gluster-swift-account"
start() {
swift_action "$name" start
retval=$?
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
swift_action "$name" stop
retval=$?
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
rh_status() {
swift_action "$name" status
}
rh_status_q() {
rh_status &> /dev/null
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart}"
exit 2
esac
exit $?

78
gluster-swift-container.init Executable file
View File

@ -0,0 +1,78 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: gluster-swift-container
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Stop: 0 1 6
# Short-Description: Swift container server
# Description: Container server for swift.
### END INIT INFO
# gluster-swift-container: swift container server
#
# chkconfig: - 20 80
# description: Container server for swift.
. /etc/rc.d/init.d/functions
. /usr/share/gluster-swift/functions
name="container"
[ -e "/etc/sysconfig/gluster-swift-$name" ] && . "/etc/sysconfig/gluster-swift-$name"
lockfile="/var/lock/subsys/gluster-swift-container"
start() {
swift_action "$name" start
retval=$?
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
swift_action "$name" stop
retval=$?
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
rh_status() {
swift_action "$name" status
}
rh_status_q() {
rh_status &> /dev/null
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart}"
exit 2
esac
exit $?

64
gluster-swift-functions Normal file
View File

@ -0,0 +1,64 @@
# vim: filetype=sh
. /etc/rc.d/init.d/functions
swift_action() {
retval=0
server="$1"
call="swift_$2"
if [[ -f "/etc/swift/$server-server.conf" ]]; then
$call "$server" \
"/etc/swift/$server-server.conf" \
"/var/run/swift/$server-server.pid"
[ $? -ne 0 ] && retval=1
elif [[ -d "/etc/swift/$server-server/" ]]; then
declare -i count=0
mkdir -p /var/run/swift/$server-server
for name in $( ls "/etc/swift/$server-server/" ); do
$call "$server" \
"/etc/swift/$server-server/$name" \
"/var/run/swift/$server-server/$count.pid"
[ $? -ne 0 ] && retval=1
count=$count+1
done
fi
return $retval
}
swift_start() {
name="$1"
long_name="$name-server"
conf_file="$2"
pid_file="$3"
ulimit -n ${SWIFT_MAX_FILES-32768}
echo -n "Starting swift-$long_name: "
daemon --pidfile $pid_file \
"/usr/bin/swift-$long_name $conf_file &>/var/log/swift-startup.log & echo \$! > $pid_file"
retval=$?
echo
return $retval
}
swift_stop() {
name="$1"
long_name="$name-server"
conf_name="$2"
pid_file="$3"
echo -n "Stopping swift-$long_name: "
killproc -p $pid_file -d ${SWIFT_STOP_DELAY-15} $long_name
retval=$?
echo
return $retval
}
swift_status() {
name="$1"
long_name="$name-server"
conf_name="$2"
pid_file="$3"
status -p $pid_file $long_name
}

79
gluster-swift-object.init Executable file
View File

@ -0,0 +1,79 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: gluster-swift-object
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Stop: 0 1 6
# Short-Description: Swift object server
# Description: Object server for swift.
### END INIT INFO
# gluster-swift-object: swift object server
#
# chkconfig: - 20 80
# description: Object server for swift.
. /etc/rc.d/init.d/functions
. /usr/share/gluster-swift/functions
name="object"
[ -e "/etc/sysconfig/gluster-swift-$name" ] && . "/etc/sysconfig/gluster-swift-$name"
lockfile="/var/lock/subsys/gluster-swift-object"
start() {
swift_action "$name" start
retval=$?
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
swift_action "$name" stop
retval=$?
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
rh_status() {
swift_action "$name" status
}
rh_status_q() {
rh_status &> /dev/null
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart}"
exit 2
esac
exit $?

Binary file not shown.

79
gluster-swift-proxy.init Executable file
View File

@ -0,0 +1,79 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: gluster-swift-proxy
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Stop: 0 1 6
# Short-Description: Swift proxy server
# Description: Account server for swift.
### END INIT INFO
# gluster-swift-proxy: swift proxy server
#
# chkconfig: - 20 80
# description: Proxy server for swift.
. /etc/rc.d/init.d/functions
. /usr/share/gluster-swift/functions
name="proxy"
[ -e "/etc/sysconfig/gluster-swift-$name" ] && . "/etc/sysconfig/gluster-swift-$name"
lockfile="/var/lock/subsys/gluster-swift-proxy"
start() {
swift_action "$name" start
retval=$?
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
swift_action "$name" stop
retval=$?
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
stop
start
}
rh_status() {
swift_action "$name" status
}
rh_status_q() {
rh_status &> /dev/null
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart}"
exit 2
esac
exit $?

797
glusterfs-3.3.0.swift.patch Normal file
View File

@ -0,0 +1,797 @@
diff --git a/setup.py b/setup.py
index d195d34..b5b5ca2 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,6 @@
#!/usr/bin/python
# Copyright (c) 2010-2012 OpenStack, LLC.
+# Copyright (c) 2011 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.
@@ -94,6 +95,7 @@ setup(
'tempurl=swift.common.middleware.tempurl:filter_factory',
'formpost=swift.common.middleware.formpost:filter_factory',
'name_check=swift.common.middleware.name_check:filter_factory',
+ 'gluster=swift.common.middleware.gluster:filter_factory',
],
},
)
diff --git a/swift/account/server.py b/swift/account/server.py
index 800b3c0..cb17970 100644
--- a/swift/account/server.py
+++ b/swift/account/server.py
@@ -1,4 +1,5 @@
# Copyright (c) 2010-2012 OpenStack, LLC.
+# Copyright (c) 2011 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.
@@ -31,7 +32,7 @@ import simplejson
from swift.common.db import AccountBroker
from swift.common.utils import get_logger, get_param, hash_path, \
- normalize_timestamp, split_path, storage_directory
+ normalize_timestamp, split_path, storage_directory, plugin_enabled
from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
check_mount, check_float, check_utf8
from swift.common.db_replicator import ReplicatorRpc
@@ -39,6 +40,8 @@ from swift.common.db_replicator import ReplicatorRpc
DATADIR = 'accounts'
+if plugin_enabled():
+ from swift.plugins.DiskDir import DiskAccount
class AccountController(object):
"""WSGI controller for the account server."""
@@ -52,8 +55,12 @@ class AccountController(object):
self.mount_check, logger=self.logger)
self.auto_create_account_prefix = \
conf.get('auto_create_account_prefix') or '.'
+ self.fs_object = None
def _get_account_broker(self, drive, part, account):
+ if self.fs_object:
+ return DiskAccount(self.root, account, self.fs_object);
+
hsh = hash_path(account)
db_dir = storage_directory(DATADIR, part, hsh)
db_path = os.path.join(self.root, drive, db_dir, hsh + '.db')
@@ -121,9 +128,15 @@ class AccountController(object):
if broker.is_deleted():
return HTTPConflict(request=req)
metadata = {}
- metadata.update((key, (value, timestamp))
- for key, value in req.headers.iteritems()
- if key.lower().startswith('x-account-meta-'))
+ if not self.fs_object:
+ metadata.update((key, (value, timestamp))
+ for key, value in req.headers.iteritems()
+ if key.lower().startswith('x-account-meta-'))
+ else:
+ metadata.update((key, value)
+ for key, value in req.headers.iteritems()
+ if key.lower().startswith('x-account-meta-'))
+
if metadata:
broker.update_metadata(metadata)
if created:
@@ -153,6 +166,9 @@ class AccountController(object):
broker.stale_reads_ok = True
if broker.is_deleted():
return HTTPNotFound(request=req)
+ if self.fs_object and not self.fs_object.object_only:
+ broker.list_containers_iter(None, None,None,
+ None, None)
info = broker.get_info()
headers = {
'X-Account-Container-Count': info['container_count'],
@@ -164,9 +180,16 @@ class AccountController(object):
container_ts = broker.get_container_timestamp(container)
if container_ts is not None:
headers['X-Container-Timestamp'] = container_ts
- headers.update((key, value)
- for key, (value, timestamp) in broker.metadata.iteritems()
- if value != '')
+ if not self.fs_object:
+ headers.update((key, value)
+ for key, (value, timestamp) in broker.metadata.iteritems()
+ if value != '')
+ else:
+ headers.update((key, value)
+ for key, value in broker.metadata.iteritems()
+ if value != '')
+
+
return HTTPNoContent(request=req, headers=headers)
def GET(self, req):
@@ -190,9 +213,15 @@ class AccountController(object):
'X-Account-Bytes-Used': info['bytes_used'],
'X-Timestamp': info['created_at'],
'X-PUT-Timestamp': info['put_timestamp']}
- resp_headers.update((key, value)
- for key, (value, timestamp) in broker.metadata.iteritems()
- if value != '')
+ if not self.fs_object:
+ resp_headers.update((key, value)
+ for key, (value, timestamp) in broker.metadata.iteritems()
+ if value != '')
+ else:
+ resp_headers.update((key, value)
+ for key, value in broker.metadata.iteritems()
+ if value != '')
+
try:
prefix = get_param(req, 'prefix')
delimiter = get_param(req, 'delimiter')
@@ -224,6 +253,7 @@ class AccountController(object):
content_type='text/plain', request=req)
account_list = broker.list_containers_iter(limit, marker, end_marker,
prefix, delimiter)
+
if out_content_type == 'application/json':
json_pattern = ['"name":%s', '"count":%s', '"bytes":%s']
json_pattern = '{' + ','.join(json_pattern) + '}'
@@ -298,15 +328,29 @@ class AccountController(object):
return HTTPNotFound(request=req)
timestamp = normalize_timestamp(req.headers['x-timestamp'])
metadata = {}
- metadata.update((key, (value, timestamp))
- for key, value in req.headers.iteritems()
- if key.lower().startswith('x-account-meta-'))
+ if not self.fs_object:
+ metadata.update((key, (value, timestamp))
+ for key, value in req.headers.iteritems()
+ if key.lower().startswith('x-account-meta-'))
+ else:
+ metadata.update((key, value)
+ for key, value in req.headers.iteritems()
+ if key.lower().startswith('x-account-meta-'))
if metadata:
broker.update_metadata(metadata)
return HTTPNoContent(request=req)
+ def plugin(self, env):
+ if env.get('Gluster_enabled', False):
+ self.fs_object = env.get('fs_object')
+ self.root = env.get('root')
+ self.mount_check = False
+ else:
+ self.fs_object = None
+
def __call__(self, env, start_response):
start_time = time.time()
+ self.plugin(env)
req = Request(env)
self.logger.txn_id = req.headers.get('x-trans-id', None)
if not check_utf8(req.path_info):
diff --git a/swift/common/middleware/gluster.py b/swift/common/middleware/gluster.py
new file mode 100644
index 0000000..341285d
--- /dev/null
+++ b/swift/common/middleware/gluster.py
@@ -0,0 +1,55 @@
+# Copyright (c) 2011 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 swift.common.utils import get_logger, plugin_enabled
+from swift import plugins
+from ConfigParser import ConfigParser
+
+class Gluster_plugin(object):
+ """
+ Update the environment with keys that reflect Gluster_plugin enabled
+ """
+
+ def __init__(self, app, conf):
+ self.app = app
+ self.conf = conf
+ self.fs_name = 'Glusterfs'
+ self.logger = get_logger(conf, log_route='gluster')
+
+ def __call__(self, env, start_response):
+ if not plugin_enabled():
+ return self.app(env, start_response)
+ env['Gluster_enabled'] =True
+ fs_object = getattr(plugins, self.fs_name, False)
+ if not fs_object:
+ raise Exception('%s plugin not found', self.fs_name)
+
+ env['fs_object'] = fs_object()
+ fs_conf = ConfigParser()
+ if fs_conf.read('/etc/swift/fs.conf'):
+ try:
+ env['root'] = fs_conf.get ('DEFAULT', 'mount_path')
+ except NoSectionError, NoOptionError:
+ self.logger.exception(_('ERROR mount_path not present'))
+ return self.app(env, start_response)
+
+def filter_factory(global_conf, **local_conf):
+ """Returns a WSGI filter app for use with paste.deploy."""
+ conf = global_conf.copy()
+ conf.update(local_conf)
+
+ def gluster_filter(app):
+ return Gluster_plugin(app, conf)
+ return gluster_filter
diff --git a/swift/common/utils.py b/swift/common/utils.py
index 47edce8..03701ce 100644
--- a/swift/common/utils.py
+++ b/swift/common/utils.py
@@ -1,4 +1,5 @@
# Copyright (c) 2010-2012 OpenStack, LLC.
+# Copyright (c) 2011 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.
@@ -1138,3 +1139,11 @@ def streq_const_time(s1, s2):
for (a, b) in zip(s1, s2):
result |= ord(a) ^ ord(b)
return result == 0
+
+def plugin_enabled():
+ swift_conf = ConfigParser()
+ swift_conf.read(os.path.join('/etc/swift', 'swift.conf'))
+ try:
+ return swift_conf.get('DEFAULT', 'Enable_plugin', 'no') in TRUE_VALUES
+ except NoOptionError, NoSectionError:
+ return False
diff --git a/swift/container/server.py b/swift/container/server.py
index 8a18cfd..93943a3 100644
--- a/swift/container/server.py
+++ b/swift/container/server.py
@@ -1,4 +1,5 @@
# Copyright (c) 2010-2012 OpenStack, LLC.
+# Copyright (c) 2011 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.
@@ -31,7 +32,8 @@ from webob.exc import HTTPAccepted, HTTPBadRequest, HTTPConflict, \
from swift.common.db import ContainerBroker
from swift.common.utils import get_logger, get_param, hash_path, \
- normalize_timestamp, storage_directory, split_path, validate_sync_to
+ normalize_timestamp, storage_directory, split_path, validate_sync_to, \
+ plugin_enabled
from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
check_mount, check_float, check_utf8
from swift.common.bufferedhttp import http_connect
@@ -40,6 +42,9 @@ from swift.common.db_replicator import ReplicatorRpc
DATADIR = 'containers'
+if plugin_enabled():
+ from swift.plugins.DiskDir import DiskDir
+
class ContainerController(object):
"""WSGI Controller for the container server."""
@@ -62,6 +67,7 @@ class ContainerController(object):
ContainerBroker, self.mount_check, logger=self.logger)
self.auto_create_account_prefix = \
conf.get('auto_create_account_prefix') or '.'
+ self.fs_object = None
def _get_container_broker(self, drive, part, account, container):
"""
@@ -73,6 +79,11 @@ class ContainerController(object):
:param container: container name
:returns: ContainerBroker object
"""
+ if self.fs_object:
+ return DiskDir(self.root, drive, part, account,
+ container, self.logger,
+ fs_object = self.fs_object)
+
hsh = hash_path(account, container)
db_dir = storage_directory(DATADIR, part, hsh)
db_path = os.path.join(self.root, drive, db_dir, hsh + '.db')
@@ -211,10 +222,18 @@ class ContainerController(object):
if broker.is_deleted():
return HTTPConflict(request=req)
metadata = {}
- metadata.update((key, (value, timestamp))
- for key, value in req.headers.iteritems()
- if key.lower() in self.save_headers or
- key.lower().startswith('x-container-meta-'))
+ #Note: check the structure of req.headers
+ if not self.fs_object:
+ metadata.update((key, (value, timestamp))
+ for key, value in req.headers.iteritems()
+ if key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-'))
+ else:
+ metadata.update((key, value)
+ for key, value in req.headers.iteritems()
+ if key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-'))
+
if metadata:
if 'X-Container-Sync-To' in metadata:
if 'X-Container-Sync-To' not in broker.metadata or \
@@ -222,6 +241,7 @@ class ContainerController(object):
broker.metadata['X-Container-Sync-To'][0]:
broker.set_x_container_sync_points(-1, -1)
broker.update_metadata(metadata)
+
resp = self.account_update(req, account, container, broker)
if resp:
return resp
@@ -245,6 +265,11 @@ class ContainerController(object):
broker.stale_reads_ok = True
if broker.is_deleted():
return HTTPNotFound(request=req)
+
+ if self.fs_object and not self.fs_object.object_only:
+ broker.list_objects_iter(None, None, None, None,
+ None, None)
+
info = broker.get_info()
headers = {
'X-Container-Object-Count': info['object_count'],
@@ -252,10 +277,17 @@ class ContainerController(object):
'X-Timestamp': info['created_at'],
'X-PUT-Timestamp': info['put_timestamp'],
}
- headers.update((key, value)
- for key, (value, timestamp) in broker.metadata.iteritems()
- if value != '' and (key.lower() in self.save_headers or
- key.lower().startswith('x-container-meta-')))
+ if not self.fs_object:
+ headers.update((key, value)
+ for key, (value, timestamp) in broker.metadata.iteritems()
+ if value != '' and (key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-')))
+ else:
+ headers.update((key, value)
+ for key, value in broker.metadata.iteritems()
+ if value != '' and (key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-')))
+
return HTTPNoContent(request=req, headers=headers)
def GET(self, req):
@@ -268,6 +300,7 @@ class ContainerController(object):
request=req)
if self.mount_check and not check_mount(self.root, drive):
return Response(status='507 %s is not mounted' % drive)
+
broker = self._get_container_broker(drive, part, account, container)
broker.pending_timeout = 0.1
broker.stale_reads_ok = True
@@ -280,10 +313,17 @@ class ContainerController(object):
'X-Timestamp': info['created_at'],
'X-PUT-Timestamp': info['put_timestamp'],
}
- resp_headers.update((key, value)
- for key, (value, timestamp) in broker.metadata.iteritems()
- if value != '' and (key.lower() in self.save_headers or
- key.lower().startswith('x-container-meta-')))
+ if not self.fs_object:
+ resp_headers.update((key, value)
+ for key, (value, timestamp) in broker.metadata.iteritems()
+ if value != '' and (key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-')))
+ else:
+ resp_headers.update((key, value)
+ for key, value in broker.metadata.iteritems()
+ if value != '' and (key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-')))
+
try:
path = get_param(req, 'path')
prefix = get_param(req, 'prefix')
@@ -414,10 +454,17 @@ class ContainerController(object):
return HTTPNotFound(request=req)
timestamp = normalize_timestamp(req.headers['x-timestamp'])
metadata = {}
- metadata.update((key, (value, timestamp))
- for key, value in req.headers.iteritems()
- if key.lower() in self.save_headers or
- key.lower().startswith('x-container-meta-'))
+ if not self.fs_object:
+ metadata.update((key, (value, timestamp))
+ for key, value in req.headers.iteritems()
+ if key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-'))
+ else:
+ metadata.update((key, value)
+ for key, value in req.headers.iteritems()
+ if key.lower() in self.save_headers or
+ key.lower().startswith('x-container-meta-'))
+
if metadata:
if 'X-Container-Sync-To' in metadata:
if 'X-Container-Sync-To' not in broker.metadata or \
@@ -427,8 +474,19 @@ class ContainerController(object):
broker.update_metadata(metadata)
return HTTPNoContent(request=req)
+ def plugin(self, env):
+ if env.get('Gluster_enabled', False):
+ self.fs_object = env.get('fs_object')
+ if not self.fs_object:
+ raise NoneTypeError
+ self.root = env.get('root')
+ self.mount_check = False
+ else:
+ self.fs_object = None
+
def __call__(self, env, start_response):
start_time = time.time()
+ self.plugin(env)
req = Request(env)
self.logger.txn_id = req.headers.get('x-trans-id', None)
if not check_utf8(req.path_info):
diff --git a/swift/obj/server.py b/swift/obj/server.py
index 9cca16b..a45daff 100644
--- a/swift/obj/server.py
+++ b/swift/obj/server.py
@@ -1,4 +1,5 @@
# Copyright (c) 2010-2012 OpenStack, LLC.
+# Copyright (c) 2011 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.
@@ -26,6 +27,7 @@ from hashlib import md5
from tempfile import mkstemp
from urllib import unquote
from contextlib import contextmanager
+from ConfigParser import ConfigParser
from webob import Request, Response, UTC
from webob.exc import HTTPAccepted, HTTPBadRequest, HTTPCreated, \
@@ -37,16 +39,23 @@ from eventlet import sleep, Timeout, tpool
from swift.common.utils import mkdirs, normalize_timestamp, \
storage_directory, hash_path, renamer, fallocate, \
- split_path, drop_buffer_cache, get_logger, write_pickle
+ split_path, drop_buffer_cache, get_logger, write_pickle, \
+ plugin_enabled
from swift.common.bufferedhttp import http_connect
-from swift.common.constraints import check_object_creation, check_mount, \
- check_float, check_utf8
+if plugin_enabled():
+ from swift.plugins.constraints import check_object_creation
+ from swift.plugins.utils import X_TYPE, X_OBJECT_TYPE, FILE, DIR, MARKER_DIR, \
+ OBJECT, DIR_TYPE, FILE_TYPE
+else:
+ from swift.common.constraints import check_object_creation
+
+from swift.common.constraints import check_mount, check_float, check_utf8
+
from swift.common.exceptions import ConnectionTimeout, DiskFileError, \
DiskFileNotExist
from swift.obj.replicator import tpooled_get_hashes, invalidate_hash, \
quarantine_renamer
-
DATADIR = 'objects'
ASYNCDIR = 'async_pending'
PICKLE_PROTOCOL = 2
@@ -339,6 +348,9 @@ class DiskFile(object):
raise
raise DiskFileNotExist('Data File does not exist.')
+if plugin_enabled():
+ from swift.plugins.DiskFile import Gluster_DiskFile
+
class ObjectController(object):
"""Implements the WSGI application for the Swift Object Server."""
@@ -377,6 +389,17 @@ class ObjectController(object):
'expiring_objects'
self.expiring_objects_container_divisor = \
int(conf.get('expiring_objects_container_divisor') or 86400)
+ self.fs_object = None
+
+ def get_DiskFile_obj(self, path, device, partition, account, container, obj,
+ logger, keep_data_fp=False, disk_chunk_size=65536):
+ if self.fs_object:
+ return Gluster_DiskFile(path, device, partition, account, container,
+ obj, logger, keep_data_fp,
+ disk_chunk_size, fs_object = self.fs_object);
+ else:
+ return DiskFile(path, device, partition, account, container,
+ obj, logger, keep_data_fp, disk_chunk_size)
def async_update(self, op, account, container, obj, host, partition,
contdevice, headers_out, objdevice):
@@ -493,7 +516,7 @@ class ObjectController(object):
content_type='text/plain')
if self.mount_check and not check_mount(self.devices, device):
return Response(status='507 %s is not mounted' % device)
- file = DiskFile(self.devices, device, partition, account, container,
+ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
if 'X-Delete-At' in file.metadata and \
@@ -548,7 +571,7 @@ class ObjectController(object):
if new_delete_at and new_delete_at < time.time():
return HTTPBadRequest(body='X-Delete-At in past', request=request,
content_type='text/plain')
- file = DiskFile(self.devices, device, partition, account, container,
+ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
orig_timestamp = file.metadata.get('X-Timestamp')
upload_expiration = time.time() + self.max_upload_time
@@ -580,12 +603,29 @@ class ObjectController(object):
if 'etag' in request.headers and \
request.headers['etag'].lower() != etag:
return HTTPUnprocessableEntity(request=request)
- metadata = {
- 'X-Timestamp': request.headers['x-timestamp'],
- 'Content-Type': request.headers['content-type'],
- 'ETag': etag,
- 'Content-Length': str(os.fstat(fd).st_size),
- }
+ content_type = request.headers['content-type']
+ if self.fs_object and not content_type:
+ content_type = FILE_TYPE
+ if not self.fs_object:
+ metadata = {
+ 'X-Timestamp': request.headers['x-timestamp'],
+ 'Content-Type': request.headers['content-type'],
+ 'ETag': etag,
+ 'Content-Length': str(os.fstat(fd).st_size),
+ }
+ else:
+ metadata = {
+ 'X-Timestamp': request.headers['x-timestamp'],
+ 'Content-Type': request.headers['content-type'],
+ 'ETag': etag,
+ 'Content-Length': str(os.fstat(fd).st_size),
+ X_TYPE: OBJECT,
+ X_OBJECT_TYPE: FILE,
+ }
+
+ if self.fs_object and \
+ request.headers['content-type'].lower() == DIR_TYPE:
+ metadata.update({X_OBJECT_TYPE: MARKER_DIR})
metadata.update(val for val in request.headers.iteritems()
if val[0].lower().startswith('x-object-meta-') and
len(val[0]) > 14)
@@ -612,7 +652,7 @@ class ObjectController(object):
'x-timestamp': file.metadata['X-Timestamp'],
'x-etag': file.metadata['ETag'],
'x-trans-id': request.headers.get('x-trans-id', '-')},
- device)
+ (self.fs_object and account) or device)
resp = HTTPCreated(request=request, etag=etag)
return resp
@@ -626,9 +666,9 @@ class ObjectController(object):
content_type='text/plain')
if self.mount_check and not check_mount(self.devices, device):
return Response(status='507 %s is not mounted' % device)
- file = DiskFile(self.devices, device, partition, account, container,
- obj, self.logger, keep_data_fp=True,
- disk_chunk_size=self.disk_chunk_size)
+ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
+ obj, self.logger, keep_data_fp=True,
+ disk_chunk_size=self.disk_chunk_size)
if file.is_deleted() or ('X-Delete-At' in file.metadata and
int(file.metadata['X-Delete-At']) <= time.time()):
if request.headers.get('if-match') == '*':
@@ -702,7 +742,7 @@ class ObjectController(object):
return resp
if self.mount_check and not check_mount(self.devices, device):
return Response(status='507 %s is not mounted' % device)
- file = DiskFile(self.devices, device, partition, account, container,
+ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
if file.is_deleted() or ('X-Delete-At' in file.metadata and
int(file.metadata['X-Delete-At']) <= time.time()):
@@ -744,7 +784,7 @@ class ObjectController(object):
if self.mount_check and not check_mount(self.devices, device):
return Response(status='507 %s is not mounted' % device)
response_class = HTTPNoContent
- file = DiskFile(self.devices, device, partition, account, container,
+ file = self.get_DiskFile_obj(self.devices, device, partition, account, container,
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
if 'x-if-delete-at' in request.headers and \
int(request.headers['x-if-delete-at']) != \
@@ -797,9 +837,18 @@ class ObjectController(object):
raise hashes
return Response(body=pickle.dumps(hashes))
+ def plugin(self, env):
+ if env.get('Gluster_enabled', False):
+ self.fs_object = env.get('fs_object')
+ self.devices = env.get('root')
+ self.mount_check = False
+ else:
+ self.fs_object = None
+
def __call__(self, env, start_response):
"""WSGI Application entry point for the Swift Object Server."""
start_time = time.time()
+ self.plugin(env)
req = Request(env)
self.logger.txn_id = req.headers.get('x-trans-id', None)
if not check_utf8(req.path_info):
diff --git a/swift/proxy/server.py b/swift/proxy/server.py
index 17613b8..d277d28 100644
--- a/swift/proxy/server.py
+++ b/swift/proxy/server.py
@@ -1,4 +1,5 @@
# Copyright (c) 2010-2012 OpenStack, LLC.
+# Copyright (c) 2011 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.
@@ -53,11 +54,20 @@ from webob import Request, Response
from swift.common.ring import Ring
from swift.common.utils import cache_from_env, ContextPool, get_logger, \
- get_remote_client, normalize_timestamp, split_path, TRUE_VALUES
+ get_remote_client, normalize_timestamp, split_path, TRUE_VALUES, \
+ plugin_enabled
from swift.common.bufferedhttp import http_connect
-from swift.common.constraints import check_metadata, check_object_creation, \
- check_utf8, CONTAINER_LISTING_LIMIT, MAX_ACCOUNT_NAME_LENGTH, \
- MAX_CONTAINER_NAME_LENGTH, MAX_FILE_SIZE
+
+if plugin_enabled():
+ from swift.plugins.constraints import check_object_creation, \
+ MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, MAX_FILE_SIZE
+else:
+ from swift.common.constraints import check_object_creation, \
+ MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, MAX_FILE_SIZE
+
+from swift.common.constraints import check_metadata, check_utf8, \
+ CONTAINER_LISTING_LIMIT
+
from swift.common.exceptions import ChunkReadTimeout, \
ChunkWriteTimeout, ConnectionTimeout
diff --git a/test/__init__.py b/test/__init__.py
index ef2ce31..363a051 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -6,8 +6,16 @@ import sys
import os
from ConfigParser import MissingSectionHeaderError
from StringIO import StringIO
-
from swift.common.utils import readconf
+from swift.common.utils import plugin_enabled
+if plugin_enabled():
+ from swift.plugins.constraints import MAX_OBJECT_NAME_LENGTH, \
+ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
+ MAX_FILE_SIZE
+else:
+ from swift.common.constraints import MAX_OBJECT_NAME_LENGTH, \
+ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
+ MAX_FILE_SIZE
setattr(__builtin__, '_', lambda x: x)
diff --git a/test/functional/tests.py b/test/functional/tests.py
index b25b4fd..8d12f58 100644
--- a/test/functional/tests.py
+++ b/test/functional/tests.py
@@ -31,6 +31,16 @@ import urllib
from test import get_config
from swift import Account, AuthenticationFailed, Connection, Container, \
File, ResponseError
+from test import plugin_enabled
+if plugin_enabled():
+ from test import MAX_OBJECT_NAME_LENGTH, \
+ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
+ MAX_FILE_SIZE
+else:
+ from test import MAX_OBJECT_NAME_LENGTH, \
+ MAX_CONTAINER_NAME_LENGTH, MAX_ACCOUNT_NAME_LENGTH, \
+ MAX_FILE_SIZE
+
config = get_config()
@@ -361,7 +371,7 @@ class TestContainer(Base):
set_up = False
def testContainerNameLimit(self):
- limit = 256
+ limit = MAX_CONTAINER_NAME_LENGTH
for l in (limit-100, limit-10, limit-1, limit,
limit+1, limit+10, limit+100):
@@ -949,7 +959,7 @@ class TestFile(Base):
self.assert_status(404)
def testNameLimit(self):
- limit = 1024
+ limit = MAX_OBJECT_NAME_LENGTH
for l in (1, 10, limit/2, limit-1, limit, limit+1, limit*2):
file = self.env.container.file('a'*l)
@@ -1093,7 +1103,7 @@ class TestFile(Base):
self.assert_(file.read(hdrs={'Range': r}) == data[0:1000])
def testFileSizeLimit(self):
- limit = 5*2**30 + 2
+ limit = MAX_FILE_SIZE
tsecs = 3
for i in (limit-100, limit-10, limit-1, limit, limit+1, limit+10,
diff --git a/test/unit/obj/test_server.py b/test/unit/obj/test_server.py
index 075700e..5b6f32d 100644
--- a/test/unit/obj/test_server.py
+++ b/test/unit/obj/test_server.py
@@ -1355,7 +1355,7 @@ class TestObjectController(unittest.TestCase):
def test_max_object_name_length(self):
timestamp = normalize_timestamp(time())
- req = Request.blank('/sda1/p/a/c/' + ('1' * 1024),
+ req = Request.blank('/sda1/p/a/c/' + ('1' * MAX_OBJECT_NAME_LENGTH),
environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Timestamp': timestamp,
'Content-Length': '4',
diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py
index 364370e..c17fe59 100644
--- a/test/unit/proxy/test_server.py
+++ b/test/unit/proxy/test_server.py
@@ -21,7 +21,6 @@ import os
import sys
import unittest
from nose import SkipTest
-from ConfigParser import ConfigParser
from contextlib import contextmanager
from cStringIO import StringIO
from gzip import GzipFile
@@ -44,8 +43,18 @@ from swift.account import server as account_server
from swift.container import server as container_server
from swift.obj import server as object_server
from swift.common import ring
-from swift.common.constraints import MAX_META_NAME_LENGTH, \
- MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, MAX_FILE_SIZE
+from swift.common.utils import plugin_enabled
+if plugin_enabled():
+ from swift.plugins.constraints import MAX_META_NAME_LENGTH, \
+ MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, \
+ MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, \
+ MAX_OBJECT_NAME_LENGTH
+else:
+ from swift.plugins.constraints import MAX_META_NAME_LENGTH, \
+ MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, \
+ MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, \
+ MAX_OBJECT_NAME_LENGTH
+
from swift.common.utils import mkdirs, normalize_timestamp, NullLogger
from swift.common.wsgi import monkey_patch_mimetools
@@ -3207,7 +3216,8 @@ class TestContainerController(unittest.TestCase):
def test_PUT_max_container_name_length(self):
with save_globals():
controller = proxy_server.ContainerController(self.app, 'account',
- '1' * 256)
+ '1' *
+ MAX_CONTAINER_NAME_LENGTH,)
self.assert_status_map(controller.PUT,
(200, 200, 200, 201, 201, 201), 201,
missing_container=True)
@@ -3813,7 +3823,8 @@ class TestAccountController(unittest.TestCase):
def test_PUT_max_account_name_length(self):
with save_globals():
self.app.allow_account_management = True
- controller = proxy_server.AccountController(self.app, '1' * 256)
+ controller = proxy_server.AccountController(self.app, '1' *
+ MAX_ACCOUNT_NAME_LENGTH)
self.assert_status_map(controller.PUT, (201, 201, 201), 201)
controller = proxy_server.AccountController(self.app, '2' * 257)
self.assert_status_map(controller.PUT, (201, 201, 201), 400)

View File

@ -21,11 +21,12 @@
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without georeplication
%{?_without_georeplication:%global _without_georeplication --disable-geo-replication}
%global SWIFTVER 1.4.8
Summary: Cluster File System
Name: glusterfs
Version: 3.3.0
Release: 3%{?dist}
Release: 4%{?dist}
License: GPLv3+ and (GPLv2 or LGPLv3+)
Group: System Environment/Base
Vendor: Red Hat
@ -196,11 +197,165 @@ is in user space and easily manageable.
This package provides the development libraries.
%package swift
Summary: GlusterFS OpenStack Object Storage
License: ASL 2.0
BuildArch: noarch
Source10: http://launchpad.net/swift/essex/%{SWIFTVER}/+download/swift-%{SWIFTVER}.tar.gz
Source11: gluster-swift-functions
Source12: gluster-swift-account.init
Source13: gluster-swift-container.init
Source14: gluster-swift-object.init
Source15: gluster-swift-proxy.init
Patch3: openstack-swift-newdeps.patch
Patch4: openstack-swift-docmod.patch
Patch5: openstack-swift-nonet.patch
Patch6: glusterfs-3.3.0.swift.patch
#BuildRoot: %(mktemp -ud %{_tmppath}/swift-%{SWIFTVER}-%{release}-XXXXXX)
BuildRequires: python-devel
BuildRequires: python-setuptools
BuildRequires: python-netifaces
%if ( 0%{?rhel} && 0%{?rhel} < 7 )
BuildRequires: python-webob1.0
%else
BuildRequires: python-webob
%endif
BuildRequires: python-paste-deploy
BuildRequires: dos2unix
Requires: python-configobj
Requires: python-eventlet >= 0.9.8
Requires: python-greenlet >= 0.3.1
Requires: python-paste-deploy
Requires: python-simplejson
Requires: pyxattr
Requires: python-setuptools
Requires: python-netifaces
Requires: python-netifaces
Conflicts: openstack-swift
%description swift
OpenStack Object Storage (swift) aggregates commodity servers to work together
in clusters for reliable, redundant, and large-scale storage of static objects.
Objects are written to multiple hardware devices in the data center, with the
OpenStack software responsible for ensuring data replication and integrity
across the cluster. Storage clusters can scale horizontally by adding new nodes,
which are automatically configured. Should a node fail, OpenStack works to
replicate its content from other active nodes. Because OpenStack uses software
logic to ensure data replication and distribution across different devices,
inexpensive commodity hard drives and servers can be used in lieu of more
expensive equipment.
%package swift-account
Summary: A swift account server
Group: Applications/System
License: ASL 2.0
BuildArch: noarch
Requires: %{name}-swift = %{version}-%{release}
%description swift-account
OpenStack Object Storage (swift) aggregates commodity servers to work together
in clusters for reliable, redundant, and large-scale storage of static objects.
This package contains the %{name}-swift account server.
%package swift-container
Summary: A swift container server
Group: Applications/System
License: ASL 2.0
BuildArch: noarch
Requires: %{name}-swift = %{version}-%{release}
%description swift-container
OpenStack Object Storage (swift) aggregates commodity servers to work together
in clusters for reliable, redundant, and large-scale storage of static objects.
This package contains the %{name}-swift container server.
%package swift-object
Summary: A swift object server
Group: Applications/System
License: ASL 2.0
BuildArch: noarch
Requires: %{name}-swift = %{version}-%{release}
Requires: rsync >= 3.0
%description swift-object
OpenStack Object Storage (swift) aggregates commodity servers to work together
in clusters for reliable, redundant, and large-scale storage of static objects.
This package contains the %{name}-swift object server.
%package swift-proxy
Summary: A swift proxy server
Group: Applications/System
License: ASL 2.0
BuildArch: noarch
Requires: %{name}-swift = %{version}-%{release}
%description swift-proxy
OpenStack Object Storage (swift) aggregates commodity servers to work together
in clusters for reliable, redundant, and large-scale storage of static objects.
This package contains the %{name}-swift proxy server.
%package swift-doc
Summary: Documentation for %{name}
Group: Documentation
BuildArch: noarch
# Required for generating docs
BuildRequires: python-eventlet
BuildRequires: python-simplejson
BuildRequires: python-webob
BuildRequires: python-sphinx
BuildRequires: pyxattr
%description swift-doc
OpenStack Object Storage (swift) aggregates commodity servers to work together
in clusters for reliable, redundant, and large-scale storage of static objects.
This package contains documentation files for %{name}-swift.
%package swift-plugin
Summary: GlusterFS Unified File and Object Storage.
Group: Applications/System
License: ASL 2.0
BuildArch: noarch
Requires: %{name}-swift = %{version}-%{release}
Requires: memcached
Requires: openssl
Requires: python
Source20: gluster-swift-plugins.tar.gz
%description swift-plugin
Gluster Unified File and Object Storage unifies NAS and object storage
technology. This provides a system for data storage that enables users to access
the same data as an object and as a file, simplifying management and controlling
storage costs.
%prep
%setup -q -n %{name}-%{version}
%setup -q -T -D -n %{name}-%{version} -a 10
%setup -q -T -D -n %{name}-%{version} -a 20
%patch0 -p0
%patch1 -p0
%patch2 -p0
cd swift-%{SWIFTVER}
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
dos2unix LICENSE
%build
./autogen.sh
@ -212,6 +367,12 @@ sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
%{__make} %{?_smp_mflags}
cd swift-%{SWIFTVER}
%{__python} setup.py build
%{__mkdir_p} doc/build
%{__python} setup.py build_sphinx
cd ..
%install
%{__rm} -rf %{buildroot}
%{__make} install DESTDIR=%{buildroot}
@ -309,6 +470,44 @@ touch %{buildroot}%{_sharedstatedir}/glusterd/glusterd.info
%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/nfs
%{__mkdir_p} %{buildroot}%{_sharedstatedir}/glusterd/peers
cd swift-%{SWIFTVER}
%{__python} setup.py install -O1 --skip-build --root %{buildroot}
# Init helper functions
%{__install} -p -D -m 644 %{SOURCE11} %{buildroot}%{_datarootdir}/gluster-swift/functions
# Init scripts
%{__install} -p -D -m 755 %{SOURCE12} %{buildroot}%{_initrddir}/gluster-swift-account
%{__install} -p -D -m 755 %{SOURCE13} %{buildroot}%{_initrddir}/gluster-swift-container
%{__install} -p -D -m 755 %{SOURCE14} %{buildroot}%{_initrddir}/gluster-swift-object
%{__install} -p -D -m 755 %{SOURCE15} %{buildroot}%{_initrddir}/gluster-swift-proxy
# Remove tests
%{__rm} -rf %{buildroot}/%{python_sitelib}/test
# Misc other
%{__install} -d -m 755 %{buildroot}%{_sysconfdir}/swift
%{__install} -d -m 755 %{buildroot}%{_sysconfdir}/swift/account-server
%{__install} -d -m 755 %{buildroot}%{_sysconfdir}/swift/container-server
%{__install} -d -m 755 %{buildroot}%{_sysconfdir}/swift/object-server
%{__install} -d -m 755 %{buildroot}%{_sysconfdir}/swift/proxy-server
# Install pid directory
%{__install} -d -m 755 %{buildroot}%{_localstatedir}/run/swift
%{__install} -d -m 755 %{buildroot}%{_localstatedir}/run/swift/account-server
%{__install} -d -m 755 %{buildroot}%{_localstatedir}/run/swift/container-server
%{__install} -d -m 755 %{buildroot}%{_localstatedir}/run/swift/object-server
%{__install} -d -m 755 %{buildroot}%{_localstatedir}/run/swift/proxy-server
cd ..
%{__mkdir -p} %{buildroot}%{python_sitelib}/swift/plugins
#%{__mkdir -p} %{buildroot}%{_sysconfdir}/swift
cd plugins
%{__install} -p -D -m 755 constraints.py %{buildroot}%{python_sitelib}/swift/plugins
%{__install} -p -D -m 755 DiskDir.py %{buildroot}%{python_sitelib}/swift/plugins
%{__install} -p -D -m 755 DiskFile.py %{buildroot}%{python_sitelib}/swift/plugins
%{__install} -p -D -m 755 Glusterfs.py %{buildroot}%{python_sitelib}/swift/plugins
%{__install} -p -D -m 755 __init__.py %{buildroot}%{python_sitelib}/swift/plugins
%{__install} -p -D -m 755 utils.py %{buildroot}%{python_sitelib}/swift/plugins
cp -r conf/* %{buildroot}%{_sysconfdir}/swift
cd ..
%clean
%{__rm} -rf %{buildroot}
@ -428,6 +627,96 @@ touch %{buildroot}%{_sharedstatedir}/glusterd/glusterd.info
%exclude %{_includedir}/glusterfs/y.tab.h
%{_libdir}/*.so
%files swift
%defattr(-,root,root,-)
%doc swift-%{SWIFTVER}/AUTHORS
%doc swift-%{SWIFTVER}/LICENSE
%doc swift-%{SWIFTVER}/README
%doc swift-%{SWIFTVER}/etc/dispersion.conf-sample
%doc swift-%{SWIFTVER}/etc/drive-audit.conf-sample
%doc swift-%{SWIFTVER}/etc/object-expirer.conf-sample
%doc swift-%{SWIFTVER}/etc/swift.conf-sample
%dir %{_datarootdir}/gluster-swift/functions
%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift
%dir %{_sysconfdir}/swift
%dir %{python_sitelib}/swift
%{_bindir}/swift
%{_bindir}/swift-account-audit
%{_bindir}/swift-bench
%{_bindir}/swift-drive-audit
%{_bindir}/swift-get-nodes
%{_bindir}/swift-init
%{_bindir}/swift-ring-builder
%{_bindir}/swift-dispersion-populate
%{_bindir}/swift-dispersion-report
%{_bindir}/swift-recon*
%{_bindir}/swift-object-expirer
%{_bindir}/swift-oldies
%{_bindir}/swift-orphans
%{_bindir}/swift-form-signature
%{_bindir}/swift-temp-url
%{python_sitelib}/swift/*.py*
%{python_sitelib}/swift/common
%{python_sitelib}/swift-%{SWIFTVER}-*.egg-info
%files swift-account
%defattr(-,root,root,-)
%doc swift-%{SWIFTVER}/etc/account-server.conf-sample
%dir %{_initrddir}/gluster-swift-account
%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/account-server
%dir %{_sysconfdir}/swift/account-server
%{_bindir}/swift-account-auditor
%{_bindir}/swift-account-reaper
%{_bindir}/swift-account-replicator
%{_bindir}/swift-account-server
%{python_sitelib}/swift/account
%files swift-container
%defattr(-,root,root,-)
%doc swift-%{SWIFTVER}/etc/container-server.conf-sample
%dir %{_initrddir}/gluster-swift-container
%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/container-server
%dir %{_sysconfdir}/swift/container-server
%{_bindir}/swift-container-auditor
%{_bindir}/swift-container-server
%{_bindir}/swift-container-replicator
%{_bindir}/swift-container-updater
%{_bindir}/swift-container-sync
%{python_sitelib}/swift/container
%files swift-object
%defattr(-,root,root,-)
%doc swift-%{SWIFTVER}/etc/object-server.conf-sample
%doc swift-%{SWIFTVER}/etc/rsyncd.conf-sample
%dir %{_initrddir}/gluster-swift-object
%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/object-server
%dir %{_sysconfdir}/swift/object-server
%{_bindir}/swift-object-auditor
%{_bindir}/swift-object-info
%{_bindir}/swift-object-replicator
%{_bindir}/swift-object-server
%{_bindir}/swift-object-updater
%{python_sitelib}/swift/obj
%files swift-proxy
%defattr(-,root,root,-)
%doc swift-%{SWIFTVER}/etc/proxy-server.conf-sample
%dir %{_initrddir}/gluster-swift-proxy
%dir %attr(0755, swift, swift) %{_localstatedir}/run/swift/proxy-server
%dir %{_sysconfdir}/swift/proxy-server
%{_bindir}/swift-proxy-server
%{python_sitelib}/swift/proxy
%files swift-doc
%defattr(-,root,root,-)
%doc swift-%{SWIFTVER}/LICENSE
%files swift-plugin
%defattr(-,root,root,-)
%{python_sitelib}/swift/plugins
%{_sysconfdir}/swift
%post server
# Legacy server
%_init_enable glusterd
@ -472,6 +761,70 @@ else
glusterd --xlator-option *.upgrade=on -N
fi
%pre swift
getent group swift >/dev/null || groupadd -r swift -g 160
getent passwd swift >/dev/null || \
useradd -r -g swift -u 160 -d %{_sharedstatedir}/swift -s /sbin/nologin \
-c "OpenStack Swift Daemons" swift
exit 0
%post swift-account
/sbin/chkconfig --add gluster-swift-account
%preun swift-account
if [ $1 = 0 ] ; then
/sbin/service gluster-swift-account stop >/dev/null 2>&1
/sbin/chkconfig --del gluster-swift-account
fi
%postun swift-account
if [ "$1" -ge "1" ] ; then
/sbin/service gluster-swift-account condrestart >/dev/null 2>&1 || :
fi
%post swift-container
/sbin/chkconfig --add gluster-swift-container
%preun swift-container
if [ $1 = 0 ] ; then
/sbin/service gluster-swift-container stop >/dev/null 2>&1
/sbin/chkconfig --del gluster-swift-container
fi
%postun swift-container
if [ "$1" -ge "1" ] ; then
/sbin/service gluster-swift-container condrestart >/dev/null 2>&1 || :
fi
%post swift-object
/sbin/chkconfig --add gluster-swift-object
%preun swift-object
if [ $1 = 0 ] ; then
/sbin/service gluster-swift-object stop >/dev/null 2>&1
/sbin/chkconfig --del gluster-swift-object
fi
%postun swift-object
if [ "$1" -ge "1" ] ; then
/sbin/service gluster-swift-object condrestart >/dev/null 2>&1 || :
fi
%post swift-proxy
/sbin/chkconfig --add gluster-swift-proxy
%preun swift-proxy
if [ $1 = 0 ] ; then
/sbin/service gluster-swift-proxy stop >/dev/null 2>&1
/sbin/chkconfig --del gluster-swift-proxy
fi
%postun swift-proxy
if [ "$1" -ge "1" ] ; then
/sbin/service gluster-swift-proxy condrestart >/dev/null 2>&1 || :
fi
%preun server
if [ $1 -eq 0 ]; then
%_init_stop glusterfsd
@ -484,7 +837,11 @@ if [ $1 -ge 1 ]; then
%_init_restart glusterfsd
fi
%changelog
* Fri Aug 10 2012 Kaleb S. KEITHLEY <kkeithle[at]redhat.com> - 3.3.0-4
- now with UFO (openstack-swift)
* Wed Jul 18 2012 Kaleb S. KEITHLEY <kkeithle[at]redhat.com> - 3.3.0-3
- fix segv in cmd_heal_volume_brick_out (RHEL seems particularly
sensitive to this bug.)

View File

@ -0,0 +1,14 @@
--- swift-1.4.4/doc/source/conf.py.orig 2011-11-24 08:59:50.000000000 -0500
+++ swift-1.4.4/doc/source/conf.py 2012-01-04 22:35:55.571492761 -0500
@@ -31,7 +31,10 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append([os.path.abspath('../swift'), os.path.abspath('..'), os.path.abspath('../bin')])
+sys.path = [os.path.abspath('../../swift'),
+ os.path.abspath('../..'),
+ os.path.abspath('../../bin')
+ ] + sys.path
# -- General configuration -----------------------------------------------------

View File

@ -0,0 +1,36 @@
diff -ru swift-1.4.4-ORIG/swift/__init__.py swift-1.4.4/swift/__init__.py
--- swift-1.4.4-ORIG/swift/__init__.py 2011-11-24 14:59:50.000000000 +0100
+++ swift-1.4.4/swift/__init__.py 2012-01-04 00:09:10.122030579 +0100
@@ -1,3 +1,32 @@
+import sys
+import pkg_resources
+
+# If there is a conflicting non egg module,
+# i.e. an older standard system module installed,
+# then replace it with this requirement
+def replace_dist(requirement):
+ try:
+ return pkg_resources.require(requirement)
+ except pkg_resources.VersionConflict:
+ e = sys.exc_info()[1]
+ dist=e.args[0]
+ req=e.args[1]
+ if dist.key == req.key and not dist.location.endswith('.egg'):
+ del pkg_resources.working_set.by_key[dist.key]
+ # We assume there is no need to adjust sys.path
+ # and the associated pkg_resources.working_set.entries
+ return pkg_resources.require(requirement)
+
+replace_dist("WebOb >= 1.0")
+
+replace_dist("PasteDeploy >= 1.5.0")
+# This hack is needed because replace_dist() results in
+# the standard paste module path being at the start of __path__.
+# TODO: See can we get pkg_resources to do the right thing directly
+import paste
+paste.__path__.insert(0, paste.__path__.pop(-1))
+
+
import gettext

View File

@ -0,0 +1,11 @@
--- swift-1.4.4/doc/source/conf.py.orig 2012-01-04 22:40:43.190300958 -0500
+++ swift-1.4.4/doc/source/conf.py 2012-01-04 22:41:26.980492712 -0500
@@ -40,7 +40,7 @@
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig']
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.ifconfig']
todo_include_todos = True
# Add any paths that contain templates here, relative to this directory.

View File

@ -1 +1,2 @@
3ddf782421f54c60b9da9607b0c32ec1 glusterfs-3.3.0.tar.gz
785ae9ba4e1f6fc256cd6a697bb2861f swift-1.4.8.tar.gz