Rework nova_cell_v2_discover_host.py to use nova.conf and python novaclient

Previously nova_cell_v2_discover_host.py used environment variables passed
to the script and it got deleted right after usage. This changed to:
- read auth information from nova.conf
- read host information from nova.conf
- use python novaclient to check new services instead of subprocess
calls

Change-Id: Id08be90d6be89af66d94bc779f311702526eb788
This commit is contained in:
Martin Schuppert 2019-01-23 21:33:27 +01:00
parent a7c230e4c4
commit df7f43974e

View File

@ -14,82 +14,96 @@
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import logging
from optparse import OptionParser
import os
import pwd
import socket
import subprocess
import sys
import time
# Delete this immediataly as it contains auth info
os.unlink(__file__)
# Only need root to read this script, drop to nova user
nova_uid, nova_gid = pwd.getpwnam('nova')[2:4]
os.setgid(nova_gid)
os.setuid(nova_uid)
from keystoneauth1 import loading
from keystoneauth1 import session
from novaclient import client
os.environ.update(
OS_PROJECT_DOMAIN_NAME='__OS_PROJECT_DOMAIN_NAME',
OS_USER_DOMAIN_NAME='__OS_PROJECT_USER_NAME',
OS_PROJECT_NAME='__OS_PROJECT_NAME',
OS_USERNAME='__OS_USERNAME',
OS_PASSWORD='__OS_PASSWORD',
OS_AUTH_URL='__OS_AUTH_URL',
OS_AUTH_TYPE='password',
OS_IDENTITY_API_VERSION='3'
)
from six.moves.configparser import SafeConfigParser
try:
my_host = subprocess.check_output([
'crudini',
'--get',
'/etc/nova/nova.conf',
'DEFAULT',
'host'
], universal_newlines=True).rstrip()
except subprocess.CalledProcessError:
# If host isn't set nova defaults to this
my_host = socket.gethostname()
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
LOG = logging.getLogger('nova_cell_v2_discover_host')
# Wait until this host is listed in the service list then
# run cellv2 host discovery
retries = 10
for i in range(retries):
try:
service_output = subprocess.check_output([
'openstack',
'-q',
'--os-interface',
'internal',
'compute',
'service',
'list',
'-c',
'Host',
'-c',
'Zone',
'-f',
'value'
], universal_newlines=True)
service_list = service_output.split('\n')
for entry in service_list:
# skip any empty lines
if not entry:
continue
host, zone = entry.split()
if host == my_host and zone != 'internal':
print('(cellv2) Service registered, running discovery')
sys.exit(subprocess.call([
'/usr/bin/nova-manage',
'cell_v2',
'discover_hosts',
'--by-service',
'--verbose'
]))
print('(cellv2) Waiting for service to register')
except subprocess.CalledProcessError:
print('(cellv2) Retrying')
time.sleep(30)
nova_cfg = '/etc/nova/nova.conf'
if __name__ == '__main__':
parser = OptionParser(usage="usage: %prog [options]")
parser.add_option('-k', '--insecure',
action="store_false",
dest='insecure',
default=True,
help='Allow insecure connection when using SSL')
(options, args) = parser.parse_args()
LOG.debug('Running with parameter insecure = %s',
options.insecure)
if os.path.isfile(nova_cfg):
config = SafeConfigParser()
config.read(nova_cfg)
else:
LOG.error('Nova configuration file %s does not exist', nova_cfg)
sys.exit(1)
my_host = config.get('DEFAULT', 'host')
if not my_host:
# If host isn't set nova defaults to this
my_host = socket.gethostname()
loader = loading.get_plugin_loader('password')
auth = loader.load_from_options(
auth_url=config.get('neutron',
'auth_url'),
username=config.get('neutron',
'username'),
password=config.get('neutron',
'password'),
project_name=config.get('neutron',
'project_name'),
project_domain_name=config.get('neutron',
'project_domain_name'),
user_domain_name=config.get('neutron',
'user_domain_name'))
sess = session.Session(auth=auth, verify=options.insecure)
nova = client.Client('2.11', session=sess, endpoint_type='internal')
# Wait until this host is listed in the service list then
# run cellv2 host discovery
retries = 10
for i in range(retries):
try:
service_list = nova.services.list(binary='nova-compute')
for entry in service_list:
host = getattr(entry, 'host', '')
zone = getattr(entry, 'zone', '')
if host == my_host and zone != 'internal':
LOG.info('(cellv2) Service registered, running discovery')
sys.exit(subprocess.call([
'/usr/bin/nova-manage',
'cell_v2',
'discover_hosts',
'--by-service',
'--verbose'
]))
if len(service_list) == 0:
LOG.warning('(cellv2) no nova-compute service registered' +
' after %i checks', i)
LOG.info('(cellv2) Waiting for service to register')
except subprocess.CalledProcessError:
LOG.info('(cellv2) Retrying')
except Exception as e:
LOG.exception('Error during host discovery:')
time.sleep(30)
sys.exit(1)
# vim: set et ts=4 sw=4 :