Fix binary name

Before an upgrade, we have these type of entries in the db.

MariaDB [nova]> SELECT id, host, `binary`, deleted, version FROM services;
+----+--------------+--------------------+---------+---------+
| id | host         | binary             | deleted | version |
+----+--------------+--------------------+---------+---------+
|  5 | r1-n-os-api  | nova-osapi_compute | 0       |      16 |
| 21 | r1-n-m-api   | nova-metadata      | 0       |      16 |

The wsgi files we run basically boil down to something like

  NAME=metadata
  return wsgi_app.init_application(NAME)

In the wsgi_app.py we see this function

  service_ref = objects.Service.get_by_host_and_binary(ctxt, host, name)

Which results in a really big query, which again comes down to

  SELECT host, `binary` FROM services
    WHERE host = 'r1-n-m-api' AND `binary` == 'metadata'

No results. service_ref is set to None. Carry on.

  if service_ref:
    #Nope.
  else:
    try:
      ...
      service_obj.host = host
      service_obj.binary = 'nova-%s' % name
      service_obj.create()

Which results in a INSERT statement something like this;

  INSERT INTO services(host, `binary`, report_count, disabled, deleted, version)
    VALUES ('r1-n-m-api', 'nova-metadata', 0, 0, 0, 22)

  ERROR 1062 (23000): Duplicate entry 'r1-n-m-api-nova-metadata-0' for key 'uniq_services0host0binary0deleted'

So the first suggested fix is to prepend 'nova-' to the name, and make both
queries ask for 'nova-metadata'.  There's also a check that it doesn't start
with 'nova-', incase someone decides to prepend 'nova-' to the NAME= in the
wsgi-file. Which migth be a litte overkill, but just a safeguard none the less.

Change-Id: I58cf9a0115a98c78e5d2fb57c41c13ba6fac0fad
Closes-bug: 1715463
This commit is contained in:
Erik Berg 2017-09-06 18:38:29 +00:00
parent 6dd6eddd46
commit 0b4a021e42
1 changed files with 4 additions and 2 deletions

View File

@ -41,16 +41,18 @@ def _get_config_files(env=None):
def _setup_service(host, name):
binary = name if name.startswith('nova-') else "nova-%s" % name
ctxt = context.get_admin_context()
service_ref = objects.Service.get_by_host_and_binary(
ctxt, host, name)
ctxt, host, binary)
if service_ref:
service._update_service_ref(service_ref)
else:
try:
service_obj = objects.Service(ctxt)
service_obj.host = host
service_obj.binary = 'nova-%s' % name
service_obj.binary = binary
service_obj.topic = None
service_obj.report_count = 0
service_obj.create()