Browse Source

Removed local patches

These patches make assumptions that are a bit too liberal.
As these cookbooks are more widely used, these should be
moved into a wrapper cookbook.

Change-Id: I5348876712418a520659aab606065e5a5b288d99
tags/eol-grizzly
John Dewey 6 years ago
parent
commit
36e51d8963
10 changed files with 2 additions and 1846 deletions
  1. +0
    -79
      files/default/cinder-volume-usage-audit
  2. +0
    -35
      files/default/fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py
  3. +0
    -33
      files/default/gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py
  4. +0
    -233
      files/default/lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py
  5. +0
    -1294
      files/default/netapp_new-42cdc4d947a73ae6a3dbbaab36634e425b57c18c.py
  6. +0
    -24
      recipes/scheduler.rb
  7. +0
    -37
      recipes/volume.rb
  8. +0
    -23
      spec/scheduler_spec.rb
  9. +0
    -1
      spec/spec_helper.rb
  10. +2
    -87
      spec/volume_spec.rb

+ 0
- 79
files/default/cinder-volume-usage-audit View File

@@ -1,79 +0,0 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright (c) 2011 Openstack, LLC.
# All Rights Reserved.
#
# 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.

"""Cron script to generate usage notifications for volumes existing during
the audit period.

Together with the notifications generated by volumes
create/delete/resize, over that time period, this allows an external
system consuming usage notification feeds to calculate volume usage
for each tenant.

Time periods are specified as 'hour', 'month', 'day' or 'year'

hour = previous hour. If run at 9:07am, will generate usage for 8-9am.
month = previous month. If the script is run April 1, it will generate
usages for March 1 through March 31.
day = previous day. if run on July 4th, it generates usages for July 3rd.
year = previous year. If run on Jan 1, it generates usages for
Jan 1 through Dec 31 of the previous year.
"""

import gettext
import os
import sys
import traceback

# If ../cinder/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'cinder', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)

gettext.install('cinder', unicode=1)
from cinder import context
from cinder import db
from cinder import flags
from cinder.openstack.common import log as logging
from cinder.openstack.common import rpc
from cinder import utils
import cinder.volume.utils


FLAGS = flags.FLAGS

if __name__ == '__main__':
admin_context = context.get_admin_context()
flags.parse_args(sys.argv)
logging.setup("cinder")
begin, end = utils.last_completed_audit_period('day')
print "Starting volume usage audit"
print "Creating usages for %s until %s" % (str(begin), str(end))
volumes = db.volume_get_active_by_window(admin_context,
begin,
end)
print "Found %d volumes" % len(volumes)
for volume_ref in volumes:
try:
cinder.volume.utils.notify_usage_exists(
admin_context, volume_ref)
except Exception, e:
print traceback.format_exc(e)
print "Volume usage audit completed"

+ 0
- 35
files/default/fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py View File

@@ -1,35 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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 errno
import os


def ensure_tree(path):
"""Create a directory (and any ancestor directories required)

:param path: Directory to create
"""
try:
os.makedirs(path)
except OSError as exc:
if exc.errno == errno.EEXIST:
if not os.path.isdir(path):
raise
else:
raise

+ 0
- 33
files/default/gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py View File

@@ -1,33 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 Red Hat, Inc.
# All Rights Reserved.
#
# 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.

"""
gettext for openstack-common modules.

Usual usage in an openstack.common module:

from cinder.openstack.common.gettextutils import _
"""

import gettext


t = gettext.translation('openstack-common', 'locale', fallback=True)


def _(msg):
return t.ugettext(msg)

+ 0
- 233
files/default/lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py View File

@@ -1,233 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# 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 errno
import functools
import os
import shutil
import tempfile
import time
import weakref

from eventlet import semaphore

from cinder.openstack.common import cfg
from cinder.openstack.common import fileutils
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import log as logging


LOG = logging.getLogger(__name__)


util_opts = [
cfg.BoolOpt('disable_process_locking', default=False,
help='Whether to disable inter-process locks'),
cfg.StrOpt('lock_path',
default=os.path.abspath(os.path.join(os.path.dirname(__file__),
'../')),
help='Directory to use for lock files')
]


CONF = cfg.CONF
CONF.register_opts(util_opts)


class _InterProcessLock(object):
"""Lock implementation which allows multiple locks, working around
issues like bugs.debian.org/cgi-bin/bugreport.cgi?bug=632857 and does
not require any cleanup. Since the lock is always held on a file
descriptor rather than outside of the process, the lock gets dropped
automatically if the process crashes, even if __exit__ is not executed.

There are no guarantees regarding usage by multiple green threads in a
single process here. This lock works only between processes. Exclusive
access between local threads should be achieved using the semaphores
in the @synchronized decorator.

Note these locks are released when the descriptor is closed, so it's not
safe to close the file descriptor while another green thread holds the
lock. Just opening and closing the lock file can break synchronisation,
so lock files must be accessed only using this abstraction.
"""

def __init__(self, name):
self.lockfile = None
self.fname = name

def __enter__(self):
self.lockfile = open(self.fname, 'w')

while True:
try:
# Using non-blocking locks since green threads are not
# patched to deal with blocking locking calls.
# Also upon reading the MSDN docs for locking(), it seems
# to have a laughable 10 attempts "blocking" mechanism.
self.trylock()
return self
except IOError, e:
if e.errno in (errno.EACCES, errno.EAGAIN):
# external locks synchronise things like iptables
# updates - give it some time to prevent busy spinning
time.sleep(0.01)
else:
raise

def __exit__(self, exc_type, exc_val, exc_tb):
try:
self.unlock()
self.lockfile.close()
except IOError:
LOG.exception(_("Could not release the acquired lock `%s`"),
self.fname)

def trylock(self):
raise NotImplementedError()

def unlock(self):
raise NotImplementedError()


class _WindowsLock(_InterProcessLock):
def trylock(self):
msvcrt.locking(self.lockfile, msvcrt.LK_NBLCK, 1)

def unlock(self):
msvcrt.locking(self.lockfile, msvcrt.LK_UNLCK, 1)


class _PosixLock(_InterProcessLock):
def trylock(self):
fcntl.lockf(self.lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)

def unlock(self):
fcntl.lockf(self.lockfile, fcntl.LOCK_UN)


if os.name == 'nt':
import msvcrt
InterProcessLock = _WindowsLock
else:
import fcntl
InterProcessLock = _PosixLock

_semaphores = weakref.WeakValueDictionary()


def synchronized(name, lock_file_prefix, external=False, lock_path=None):
"""Synchronization decorator.

Decorating a method like so::

@synchronized('mylock')
def foo(self, *args):
...

ensures that only one thread will execute the bar method at a time.

Different methods can share the same lock::

@synchronized('mylock')
def foo(self, *args):
...

@synchronized('mylock')
def bar(self, *args):
...

This way only one of either foo or bar can be executing at a time.

The lock_file_prefix argument is used to provide lock files on disk with a
meaningful prefix. The prefix should end with a hyphen ('-') if specified.

The external keyword argument denotes whether this lock should work across
multiple processes. This means that if two different workers both run a
a method decorated with @synchronized('mylock', external=True), only one
of them will execute at a time.

The lock_path keyword argument is used to specify a special location for
external lock files to live. If nothing is set, then CONF.lock_path is
used as a default.
"""

def wrap(f):
@functools.wraps(f)
def inner(*args, **kwargs):
# NOTE(soren): If we ever go natively threaded, this will be racy.
# See http://stackoverflow.com/questions/5390569/dyn
# amically-allocating-and-destroying-mutexes
sem = _semaphores.get(name, semaphore.Semaphore())
if name not in _semaphores:
# this check is not racy - we're already holding ref locally
# so GC won't remove the item and there was no IO switch
# (only valid in greenthreads)
_semaphores[name] = sem

with sem:
LOG.debug(_('Got semaphore "%(lock)s" for method '
'"%(method)s"...'), {'lock': name,
'method': f.__name__})
if external and not CONF.disable_process_locking:
LOG.debug(_('Attempting to grab file lock "%(lock)s" for '
'method "%(method)s"...'),
{'lock': name, 'method': f.__name__})
cleanup_dir = False

# We need a copy of lock_path because it is non-local
local_lock_path = lock_path
if not local_lock_path:
local_lock_path = CONF.lock_path

if not local_lock_path:
cleanup_dir = True
local_lock_path = tempfile.mkdtemp()

if not os.path.exists(local_lock_path):
cleanup_dir = True
fileutils.ensure_tree(local_lock_path)

# NOTE(mikal): the lock name cannot contain directory
# separators
safe_name = name.replace(os.sep, '_')
lock_file_name = '%s%s' % (lock_file_prefix, safe_name)
lock_file_path = os.path.join(local_lock_path,
lock_file_name)

try:
lock = InterProcessLock(lock_file_path)
with lock:
LOG.debug(_('Got file lock "%(lock)s" at %(path)s '
'for method "%(method)s"...'),
{'lock': name,
'path': lock_file_path,
'method': f.__name__})
retval = f(*args, **kwargs)
finally:
# NOTE(vish): This removes the tempdir if we needed
# to create one. This is used to cleanup
# the locks left behind by unit tests.
if cleanup_dir:
shutil.rmtree(local_lock_path)
else:
retval = f(*args, **kwargs)

return retval
return inner
return wrap

+ 0
- 1294
files/default/netapp_new-42cdc4d947a73ae6a3dbbaab36634e425b57c18c.py
File diff suppressed because it is too large
View File


+ 0
- 24
recipes/scheduler.rb View File

@@ -54,30 +54,6 @@ service "cinder-scheduler" do
action [ :enable, :start ]
end

cookbook_file "/usr/local/bin/cinder-volume-usage-audit" do
source "cinder-volume-usage-audit"
mode 00755
owner "root"
group "root"
end

# run cronjob only on one node
cron_cmd = "/usr/local/bin/cinder-volume-usage-audit > /var/log/cinder/audit.log 2>&1"
node_search = search(:node, "roles:openstack-volume-scheduler AND chef_environment:#{node.chef_environment}")
cron_node = node_search.collect{|a| a.name}.sort[0]
if node.name == cron_node
cron "cinder-volume-usage-audit" do
action :create
minute node["cinder"]["cron"]["minute"]
command cron_cmd
end
else
cron "cinder-volume-usage-audit" do
action :delete
command cron_cmd
end
end

template "/etc/cinder/cinder.conf" do
source "cinder.conf.erb"
group node["cinder"]["group"]

+ 0
- 37
recipes/volume.rb View File

@@ -100,40 +100,3 @@ template "/etc/tgt/targets.conf" do

notifies :restart, "service[iscsitarget]", :immediately
end

cookbook_file "/usr/share/pyshared/cinder/openstack/common/fileutils.py" do
source "fileutils_new-b322585613c21067571442aaf9e4e6feb167832b.py"
mode 00644
owner "root"
group "root"
end

link "/usr/lib/python2.7/dist-packages/cinder/openstack/common/fileutils.py" do
to "/usr/share/pyshared/cinder/openstack/common/fileutils.py"
end

cookbook_file "/usr/share/pyshared/cinder/openstack/common/gettextutils.py" do
source "gettextutils_new-8e450aaa6ba1a2a88f6326c2e8d285d00fd28691.py"
mode 00644
owner "root"
group "root"
end

cookbook_file "/usr/share/pyshared/cinder/openstack/common/lockutils.py" do
source "lockutils_new-6dda4af1dd50582a0271fd6c96044ae61af9df7e.py"
mode 00644
owner "root"
group "root"
end

link "/usr/lib/python2.7/dist-packages/cinder/openstack/common/lockutils.py" do
to "/usr/share/pyshared/cinder/openstack/common/lockutils.py"
end

cookbook_file node["cinder"]["netapp"]["driver"] do
source "netapp_new-42cdc4d947a73ae6a3dbbaab36634e425b57c18c.py"
mode 00644
owner "root"
group "root"
notifies :restart, "service[cinder-volume]"
end

+ 0
- 23
spec/scheduler_spec.rb View File

@@ -32,29 +32,6 @@ describe "cinder::scheduler" do
expect(@chef_run).to set_service_to_start_on_boot "cinder-scheduler"
end

describe "cinder-volume-usage-audit" do
before do
f = "/usr/local/bin/cinder-volume-usage-audit"
@file = @chef_run.cookbook_file f
end

it "has proper owner" do
expect(@file).to be_owned_by "root", "root"
end

it "has proper modes" do
expect(sprintf("%o", @file.mode)).to eq "755"
end
end

it "has cinder-volume-usage-audit cronjob" do
cron = @chef_run.cron "cinder-volume-usage-audit"
cmd = "/usr/local/bin/cinder-volume-usage-audit > " \
"/var/log/cinder/audit.log 2>&1"
expect(cron.command).to eq cmd
expect(cron.minute).to eq '00'
end

expect_creates_cinder_conf "service[cinder-scheduler]"
end
end

+ 0
- 1
spec/spec_helper.rb View File

@@ -22,7 +22,6 @@ def cinder_stubs
::Chef::Recipe.any_instance.stub(:db_password).and_return String.new
::Chef::Recipe.any_instance.stub(:user_password).and_return String.new
::Chef::Recipe.any_instance.stub(:service_password).and_return String.new
::Chef::Recipe.any_instance.stub(:search).and_return([OpenStruct.new(:name => 'fauxhai.local')])
end

def expect_runs_openstack_common_logging_recipe

+ 2
- 87
spec/volume_spec.rb View File

@@ -45,11 +45,11 @@ describe "cinder::volume" do
describe "targets.conf" do
before do
@file = @chef_run.template "/etc/tgt/targets.conf"
end
end

it "has proper modes" do
expect(sprintf("%o", @file.mode)).to eq "600"
end
end

it "notifies iscsi restart" do
expect(@file).to notify "service[iscsitarget]", :restart
@@ -61,91 +61,6 @@ describe "cinder::volume" do
expect(@chef_run).not_to create_file_with_content @file.name,
"include /var/lib/cinder/volumes/*"
end
end

describe "patches" do
before do
@os_dir = "/usr/share/pyshared/cinder/openstack/common"
@dist_dir = "/usr/lib/python2.7/dist-packages/cinder/openstack/common"
end

describe "fileutils.py" do
before do
@source = ::File.join @os_dir, "fileutils.py"
@file = @chef_run.cookbook_file @source
end

it "has proper owner" do
expect(@file).to be_owned_by "root", "root"
end

it "has proper modes" do
expect(sprintf("%o", @file.mode)).to eq "644"
end

it "symlinks fileutils.py" do
ln = ::File.join @dist_dir, "fileutils.py"
expect(@chef_run.link(ln)).to link_to @source
end
end

describe "gettextutils.py" do
before do
@source = ::File.join @os_dir, "gettextutils.py"
@file = @chef_run.cookbook_file @source
end

it "has proper owner" do
expect(@file).to be_owned_by "root", "root"
end

it "has proper modes" do
expect(sprintf("%o", @file.mode)).to eq "644"
end

it "symlinks gettextutils.py" do
pending "TODO: should there be a gettextutils symlink?"
end
end

describe "lockutils.py" do
before do
@source = ::File.join @os_dir, "lockutils.py"
@file = @chef_run.cookbook_file @source
end

it "has proper owner" do
expect(@file).to be_owned_by "root", "root"
end

it "has proper modes" do
expect(sprintf("%o", @file.mode)).to eq "644"
end

it "symlinks gettextutils.py" do
ln = ::File.join @dist_dir, "lockutils.py"
expect(@chef_run.link(ln)).to link_to @source
end
end

describe "netapp.py" do
before do
f = "/usr/share/pyshared/cinder/volume/netapp.py"
@file = @chef_run.cookbook_file f
end

it "has proper owner" do
expect(@file).to be_owned_by "root", "root"
end

it "has proper modes" do
expect(sprintf("%o", @file.mode)).to eq "644"
end

it "notifies nova-api-ec2 restart" do
expect(@file).to notify "service[cinder-volume]", :restart
end
end
end
end
end

Loading…
Cancel
Save