summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralop <alopgeek@gmail.com>2013-03-12 15:05:46 -0700
committeralop <alopgeek@gmail.com>2013-03-12 15:05:46 -0700
commitcd3b8cde6030f5ff6e6bf073f028d86942413177 (patch)
treec2e7c1122772dedd016b2d0cdb317b153691b137
parent177673e084f3d060c15521efeac07a01c919e835 (diff)
added dependencies for netapp patch
-rw-r--r--files/default/fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py35
-rw-r--r--files/default/gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py33
-rw-r--r--files/default/lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py233
-rw-r--r--recipes/volume.rb21
4 files changed, 322 insertions, 0 deletions
diff --git a/files/default/fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py b/files/default/fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py
new file mode 100644
index 0000000..4746ad4
--- /dev/null
+++ b/files/default/fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py
@@ -0,0 +1,35 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011 OpenStack LLC.
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18
19import errno
20import os
21
22
23def ensure_tree(path):
24 """Create a directory (and any ancestor directories required)
25
26 :param path: Directory to create
27 """
28 try:
29 os.makedirs(path)
30 except OSError as exc:
31 if exc.errno == errno.EEXIST:
32 if not os.path.isdir(path):
33 raise
34 else:
35 raise
diff --git a/files/default/gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py b/files/default/gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py
new file mode 100644
index 0000000..87e3520
--- /dev/null
+++ b/files/default/gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py
@@ -0,0 +1,33 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 Red Hat, Inc.
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18"""
19gettext for openstack-common modules.
20
21Usual usage in an openstack.common module:
22
23 from cinder.openstack.common.gettextutils import _
24"""
25
26import gettext
27
28
29t = gettext.translation('openstack-common', 'locale', fallback=True)
30
31
32def _(msg):
33 return t.ugettext(msg)
diff --git a/files/default/lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py b/files/default/lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py
new file mode 100644
index 0000000..418bc3a
--- /dev/null
+++ b/files/default/lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py
@@ -0,0 +1,233 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2011 OpenStack LLC.
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18
19import errno
20import functools
21import os
22import shutil
23import tempfile
24import time
25import weakref
26
27from eventlet import semaphore
28
29from cinder.openstack.common import cfg
30from cinder.openstack.common import fileutils
31from cinder.openstack.common.gettextutils import _
32from cinder.openstack.common import log as logging
33
34
35LOG = logging.getLogger(__name__)
36
37
38util_opts = [
39 cfg.BoolOpt('disable_process_locking', default=False,
40 help='Whether to disable inter-process locks'),
41 cfg.StrOpt('lock_path',
42 default=os.path.abspath(os.path.join(os.path.dirname(__file__),
43 '../')),
44 help='Directory to use for lock files')
45]
46
47
48CONF = cfg.CONF
49CONF.register_opts(util_opts)
50
51
52class _InterProcessLock(object):
53 """Lock implementation which allows multiple locks, working around
54 issues like bugs.debian.org/cgi-bin/bugreport.cgi?bug=632857 and does
55 not require any cleanup. Since the lock is always held on a file
56 descriptor rather than outside of the process, the lock gets dropped
57 automatically if the process crashes, even if __exit__ is not executed.
58
59 There are no guarantees regarding usage by multiple green threads in a
60 single process here. This lock works only between processes. Exclusive
61 access between local threads should be achieved using the semaphores
62 in the @synchronized decorator.
63
64 Note these locks are released when the descriptor is closed, so it's not
65 safe to close the file descriptor while another green thread holds the
66 lock. Just opening and closing the lock file can break synchronisation,
67 so lock files must be accessed only using this abstraction.
68 """
69
70 def __init__(self, name):
71 self.lockfile = None
72 self.fname = name
73
74 def __enter__(self):
75 self.lockfile = open(self.fname, 'w')
76
77 while True:
78 try:
79 # Using non-blocking locks since green threads are not
80 # patched to deal with blocking locking calls.
81 # Also upon reading the MSDN docs for locking(), it seems
82 # to have a laughable 10 attempts "blocking" mechanism.
83 self.trylock()
84 return self
85 except IOError, e:
86 if e.errno in (errno.EACCES, errno.EAGAIN):
87 # external locks synchronise things like iptables
88 # updates - give it some time to prevent busy spinning
89 time.sleep(0.01)
90 else:
91 raise
92
93 def __exit__(self, exc_type, exc_val, exc_tb):
94 try:
95 self.unlock()
96 self.lockfile.close()
97 except IOError:
98 LOG.exception(_("Could not release the acquired lock `%s`"),
99 self.fname)
100
101 def trylock(self):
102 raise NotImplementedError()
103
104 def unlock(self):
105 raise NotImplementedError()
106
107
108class _WindowsLock(_InterProcessLock):
109 def trylock(self):
110 msvcrt.locking(self.lockfile, msvcrt.LK_NBLCK, 1)
111
112 def unlock(self):
113 msvcrt.locking(self.lockfile, msvcrt.LK_UNLCK, 1)
114
115
116class _PosixLock(_InterProcessLock):
117 def trylock(self):
118 fcntl.lockf(self.lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
119
120 def unlock(self):
121 fcntl.lockf(self.lockfile, fcntl.LOCK_UN)
122
123
124if os.name == 'nt':
125 import msvcrt
126 InterProcessLock = _WindowsLock
127else:
128 import fcntl
129 InterProcessLock = _PosixLock
130
131_semaphores = weakref.WeakValueDictionary()
132
133
134def synchronized(name, lock_file_prefix, external=False, lock_path=None):
135 """Synchronization decorator.
136
137 Decorating a method like so::
138
139 @synchronized('mylock')
140 def foo(self, *args):
141 ...
142
143 ensures that only one thread will execute the bar method at a time.
144
145 Different methods can share the same lock::
146
147 @synchronized('mylock')
148 def foo(self, *args):
149 ...
150
151 @synchronized('mylock')
152 def bar(self, *args):
153 ...
154
155 This way only one of either foo or bar can be executing at a time.
156
157 The lock_file_prefix argument is used to provide lock files on disk with a
158 meaningful prefix. The prefix should end with a hyphen ('-') if specified.
159
160 The external keyword argument denotes whether this lock should work across
161 multiple processes. This means that if two different workers both run a
162 a method decorated with @synchronized('mylock', external=True), only one
163 of them will execute at a time.
164
165 The lock_path keyword argument is used to specify a special location for
166 external lock files to live. If nothing is set, then CONF.lock_path is
167 used as a default.
168 """
169
170 def wrap(f):
171 @functools.wraps(f)
172 def inner(*args, **kwargs):
173 # NOTE(soren): If we ever go natively threaded, this will be racy.
174 # See http://stackoverflow.com/questions/5390569/dyn
175 # amically-allocating-and-destroying-mutexes
176 sem = _semaphores.get(name, semaphore.Semaphore())
177 if name not in _semaphores:
178 # this check is not racy - we're already holding ref locally
179 # so GC won't remove the item and there was no IO switch
180 # (only valid in greenthreads)
181 _semaphores[name] = sem
182
183 with sem:
184 LOG.debug(_('Got semaphore "%(lock)s" for method '
185 '"%(method)s"...'), {'lock': name,
186 'method': f.__name__})
187 if external and not CONF.disable_process_locking:
188 LOG.debug(_('Attempting to grab file lock "%(lock)s" for '
189 'method "%(method)s"...'),
190 {'lock': name, 'method': f.__name__})
191 cleanup_dir = False
192
193 # We need a copy of lock_path because it is non-local
194 local_lock_path = lock_path
195 if not local_lock_path:
196 local_lock_path = CONF.lock_path
197
198 if not local_lock_path:
199 cleanup_dir = True
200 local_lock_path = tempfile.mkdtemp()
201
202 if not os.path.exists(local_lock_path):
203 cleanup_dir = True
204 fileutils.ensure_tree(local_lock_path)
205
206 # NOTE(mikal): the lock name cannot contain directory
207 # separators
208 safe_name = name.replace(os.sep, '_')
209 lock_file_name = '%s%s' % (lock_file_prefix, safe_name)
210 lock_file_path = os.path.join(local_lock_path,
211 lock_file_name)
212
213 try:
214 lock = InterProcessLock(lock_file_path)
215 with lock:
216 LOG.debug(_('Got file lock "%(lock)s" at %(path)s '
217 'for method "%(method)s"...'),
218 {'lock': name,
219 'path': lock_file_path,
220 'method': f.__name__})
221 retval = f(*args, **kwargs)
222 finally:
223 # NOTE(vish): This removes the tempdir if we needed
224 # to create one. This is used to cleanup
225 # the locks left behind by unit tests.
226 if cleanup_dir:
227 shutil.rmtree(local_lock_path)
228 else:
229 retval = f(*args, **kwargs)
230
231 return retval
232 return inner
233 return wrap
diff --git a/recipes/volume.rb b/recipes/volume.rb
index 15022d0..07c2399 100644
--- a/recipes/volume.rb
+++ b/recipes/volume.rb
@@ -97,6 +97,27 @@ template "/etc/tgt/targets.conf" do
97 notifies :restart, "service[iscsitarget]", :immediately 97 notifies :restart, "service[iscsitarget]", :immediately
98end 98end
99 99
100cookbook_file "/usr/share/pyshared/cinder/openstack/common/fileutils.py" do
101 source "fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py"
102 mode 00644
103 owner "root"
104 group "root"
105end
106
107cookbook_file "/usr/share/pyshared/cinder/openstack/common/gettextutils.py" do
108 source "gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py"
109 mode 00644
110 owner "root"
111 group "root"
112end
113
114cookbook_file "/usr/share/pyshared/cinder/openstack/common/lockutils.py" do
115 source "lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py"
116 mode 00644
117 owner "root"
118 group "root"
119end
120
100cookbook_file node["cinder"]["netapp"]["driver"] do 121cookbook_file node["cinder"]["netapp"]["driver"] do
101 source "netapp_new-42cdc4d947a73ae6a3dbbaab36634e425b57c18c.py" 122 source "netapp_new-42cdc4d947a73ae6a3dbbaab36634e425b57c18c.py"
102 mode 00644 123 mode 00644