Cleanup action for service-list after deploying HA.

This is a workaround for LP: #1493931 in order to keep the
output of cinder service-list clean after deploying a HA.

The rationale behind this is to expose a way to cleanup the
services table on the database from unused ones ,
those services were
created by cinder before the storage relation is joined (particularly
for stateless ones).

This action also exposes the host option to specify
the host to be removed.

By default if no host is provided, this action will
cleanup all the entries different to the ones
specified on the DEFAULT_SERVICES constant.

An example of execution can be found on the comment
section of this proposal.

Change-Id: I4a5e682e44206f7b77d873cb1fc63e3eae86aad5
Related-Bug: 1493931
Signed-off-by: Jorge Niedbalski <jorge.niedbalski@canonical.com>
This commit is contained in:
Jorge Niedbalski 2016-03-08 15:19:08 -03:00
parent f8a165f79f
commit b299cc84be
3 changed files with 90 additions and 0 deletions

View File

@ -2,3 +2,10 @@ git-reinstall:
description: Reinstall cinder from the openstack-origin-git repositories.
openstack-upgrade:
description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True.
remove-services:
description: Remove unused services entities from the database after enabling HA with a stateless backend such as cinder-ceph.
params:
host:
type: string
default: unused
description: Hostname of the service to be removed.

1
actions/remove-services Symbolic link
View File

@ -0,0 +1 @@
remove_services.py

82
actions/remove_services.py Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/env python
import os
import sys
import traceback
import subprocess
sys.path.append('hooks/')
from cinder import context
from cinder import db
from cinder.db.sqlalchemy.api import model_query, get_session
from cinder.db.sqlalchemy import models
from charmhelpers.contrib.openstack.utils import os_release
from sqlalchemy import and_
from charmhelpers.core.hookenv import (
action_set,
action_fail,
action_get,
log,
)
DEFAULT_SERVICES = (
"cinder",
"cinder@cinder-ceph",
)
try:
from cinder import flags
cfg = flags.FLAGS
except ImportError:
from cinder.common.config import CONF
cfg = CONF
def load_config_file(conf):
cfg(args=[], project='cinder', default_config_files=[conf])
def cinder_manage_remove(binary, hostname):
return subprocess.check_call(["cinder-manage", "service", "remove", binary,
hostname])
def remove_services():
load_config_file(os.path.join(os.path.sep, "etc", "cinder", "cinder.conf"))
host = action_get(key="host")
services = model_query({}, models.Service, read_deleted="no",
session=get_session())
if host not in ("unused", "",):
services = services.filter(models.Service.host == host)
else:
ands = []
for service in DEFAULT_SERVICES:
ands.append(and_(models.Service.host != service))
services = services.filter(*ands)
removed_services = []
ctxt = context.get_admin_context()
for service in services.all():
log("Removing service:%d, hostname:%s" % (service.id, service.host))
try:
if os_release("cinder") >= "liberty":
cinder_manage_remove(service.binary, service.host)
else:
db.service_destroy(ctxt, service.id)
except:
action_set({'traceback': traceback.format_exc()})
action_fail("Cannot remove service: %s" % service.host)
else:
removed_services.append(service.host)
action_set({'removed': ",".join(removed_services)})
if __name__ == "__main__":
remove_services()