Add purge content functionality to poppy

Change-Id: I2fc5cd741047ad4ad0322d2d9b6b19a8f0411437
This commit is contained in:
tonytan4ever
2014-10-17 15:51:43 -04:00
parent 181a0216ec
commit b6ab3b6211
15 changed files with 392 additions and 28 deletions

View File

@@ -56,3 +56,15 @@ class ProviderWrapper(object):
"Perhaps service has not been created")
provider_service_id = provider_detail.provider_service_id
return ext.obj.service_controller.delete(provider_service_id)
def purge(self, ext, provider_details, purge_url=None):
try:
provider_detail = provider_details[ext.obj.provider_name]
except KeyError:
raise errors.BadProviderDetail(
"No provider detail information."
"Perhaps service has not been created")
provider_service_id = provider_detail.provider_service_id
return ext.obj.service_controller.purge(
provider_service_id,
purge_url)

View File

@@ -81,3 +81,8 @@ class ServicesControllerBase(controller.ManagerControllerBase):
:raises: NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def purge(self, project_id, service_name, purge_url=None):
'''If purge_url is none, all content of this service will be purge.'''
raise NotImplementedError

View File

@@ -0,0 +1,71 @@
# Copyright (c) 2014 Rackspace, 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 poppy.openstack.common import log
LOG = log.getLogger(__name__)
def service_purge_worker(provider_details, service_controller,
project_id, service_name, purge_url):
responders = []
# try to purge all service from each provider presented
# in provider_details
for provider in provider_details:
# NOTE(tonytan4ever): if the purge_url is None, it means to purge
# all content, else only purge a specific purge url
LOG.info('Starting to purge service from %s, purge_url: %s' %
(provider,
'all' if purge_url is None else purge_url))
responder = service_controller.provider_wrapper.purge(
service_controller._driver.providers[provider.lower()],
provider_details,
purge_url)
responders.append(responder)
LOG.info('Purge service %s on %s complete...' %
(provider,
'all' if purge_url is None else purge_url))
# Find any failed attempt of purging, and stores it in provider
# detail for future debugging purpose
changed_provider_details_dict = {}
for responder in responders:
# this is the item of responder, if there's "error"
# key in it, it means the purging for this provider failed.
# in that case we will need to update the provider detail
# info for the service from poppy storage.
provider_name = list(responder.items())[0][0]
if 'error' in responder[provider_name]:
LOG.info('Purging content from %s failed' % provider_name)
LOG.info('Updating provider detail status of %s for %s' %
(provider_name, service_name))
# stores the error info for debugging purposes.
changed_provider_details_dict[provider_name] = (
provider_details[provider_name]
)
changed_provider_details_dict[provider_name].error_info = (
responder[provider_name].get('error_info')
)
# if there is an error for any puring attempts on a provider
# record it in storage for further debugging purpose
if not changed_provider_details_dict == {}:
service_controller.storage_controller._driver.connect()
provider_details.update(changed_provider_details_dict)
service_controller.storage_controller.update_provider_details(
project_id,
service_name,
provider_details)

View File

@@ -18,6 +18,7 @@ import multiprocessing
from poppy.manager import base
from poppy.manager.default.service_async_workers import create_service_worker
from poppy.manager.default.service_async_workers import delete_service_worker
from poppy.manager.default.service_async_workers import purge_service_worker
class DefaultServicesController(base.ServicesController):
@@ -147,3 +148,31 @@ class DefaultServicesController(base.ServicesController):
service_name))
p.start()
return
def purge(self, project_id, service_name, purge_url=None):
'''If purge_url is none, all content of this service will be purge.'''
try:
provider_details = self.storage_controller.get_provider_details(
project_id,
service_name)
except Exception:
raise LookupError('Service %s does not exist' % service_name)
# possible validation of purge url here...
self.storage_controller._driver.close_connection()
p = multiprocessing.Process(
name='Process: Purge poppy service %s for'
' project id: %s'
' on %s' %
(service_name,
project_id,
'all' if purge_url is None else purge_url),
target=purge_service_worker.service_purge_worker,
args=(
provider_details,
self,
project_id,
service_name,
purge_url))
p.start()
return