Skip to content

Commit

Permalink
services: insert service data early in the object template
Browse files Browse the repository at this point in the history
This change allows service data to be available early in the object
template, before archetype/base is included. This makes possible to use
the service data for configuring any aspect of the host, cluster or
metacluster.

- Includes a renaming of PlenaryServicexxxTopLevel classes into
PlenaryServicexxxData

Fixes quattor#109 (quattor#109)

Change-Id: Ife689ce3f59f057422e6c0f7f2098a5d1d44b9c6
  • Loading branch information
jouvin authored and Aquilon main user committed Jul 17, 2018
1 parent c804624 commit 0952758
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 21 deletions.
4 changes: 2 additions & 2 deletions lib/aquilon/worker/commands/cat_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from aquilon.aqdb.model import Service, ServiceInstance
from aquilon.worker.broker import BrokerCommand
from aquilon.worker.templates.service import (PlenaryServiceInstanceToplevel,
from aquilon.worker.templates.service import (PlenaryServiceInstanceData,
PlenaryServiceInstanceClientDefault,
PlenaryServiceInstanceServer,
PlenaryServiceInstanceServerDefault)
Expand All @@ -45,7 +45,7 @@ def render(self, session, logger, service, instance, default, server,
if server:
cls = PlenaryServiceInstanceServer
else:
cls = PlenaryServiceInstanceToplevel
cls = PlenaryServiceInstanceData

plenary_info = cls.get_plenary(dbsi, logger=logger)

Expand Down
4 changes: 2 additions & 2 deletions lib/aquilon/worker/commands/cat_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from aquilon.aqdb.model import Service
from aquilon.worker.broker import BrokerCommand
from aquilon.worker.templates.service import (PlenaryServiceToplevel,
from aquilon.worker.templates.service import (PlenaryServiceData,
PlenaryServiceClientDefault,
PlenaryServiceServerDefault)

Expand All @@ -38,7 +38,7 @@ def render(self, session, logger, service, server, default, generate, **_):
else:
cls = PlenaryServiceClientDefault
else:
cls = PlenaryServiceToplevel
cls = PlenaryServiceData

plenary_info = cls.get_plenary(dbservice, logger=logger)

Expand Down
4 changes: 2 additions & 2 deletions lib/aquilon/worker/commands/update_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from aquilon.worker.dbwrappers.resources import (find_resource,
get_resource_holder)
from aquilon.worker.templates import (PlenaryHostData,
PlenaryServiceInstanceToplevel)
PlenaryServiceInstanceData)
from aquilon.worker.processes import DSDBRunner
from aquilon.worker.dbwrappers.change_management import ChangeManagement

Expand Down Expand Up @@ -325,7 +325,7 @@ def render(self, session, logger, plenaries, machine, model, vendor, serial, uui
if dbmachine.host:
for srv in dbmachine.host.services_provided:
si = srv.service_instance
plenaries.add(si, cls=PlenaryServiceInstanceToplevel)
plenaries.add(si, cls=PlenaryServiceInstanceData)
update_primary_ip(session, logger, dbmachine, ip)

if dbmachine.location != old_location and dbmachine.host:
Expand Down
4 changes: 2 additions & 2 deletions lib/aquilon/worker/templates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
from aquilon.worker.templates.network import PlenaryNetwork
from aquilon.worker.templates.resource import PlenaryResource
from aquilon.worker.templates.service import (PlenaryService,
PlenaryServiceToplevel,
PlenaryServiceData,
PlenaryServiceClientDefault,
PlenaryServiceServerDefault,
PlenaryServiceInstance,
PlenaryServiceInstanceToplevel,
PlenaryServiceInstanceData,
PlenaryServiceInstanceClientDefault,
PlenaryServiceInstanceServer,
PlenaryServiceInstanceServerDefault)
Expand Down
15 changes: 15 additions & 0 deletions lib/aquilon/worker/templates/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from aquilon.worker.templates import (Plenary, ObjectPlenary, StructurePlenary,
PlenaryCollection, PlenaryResource,
PlenaryServiceInstanceClientDefault,
PlenaryServiceInstanceData,
PlenaryServiceInstanceServerDefault,
PlenaryPersonalityBase, add_location_info)
from aquilon.worker.templates.panutils import (StructureTemplate, PanValue,
Expand Down Expand Up @@ -188,6 +189,14 @@ def get_key(self, exclusive=True):
return CompileKey.merge(keylist)

def body(self, lines):
# Collect configuration of used services
services = []
services_data = {}
for si in self.dbobj.services_used:
services.append(PlenaryServiceInstanceClientDefault.template_name(si))
services_data[si.service.name] = PlenaryServiceInstanceData.template_name(si)
services.sort()

# Allow settings such as loadpath to be modified by the archetype before anything else happens
# Included only if object_declarations_template option is true
# It the option is true, the template MUST exist
Expand All @@ -203,6 +212,12 @@ def body(self, lines):
pan_assign(lines, "/",
StructureTemplate(path,
{"metadata": PanValue("/metadata")}))

# Include service data
for service_name in sorted(services_data.keys()):
pan_assign(lines, "/system/services/%s" % service_name,
StructureTemplate(services_data[service_name]))

pan_include(lines, "archetype/base")

for servinst in sorted(self.dbobj.services_used,
Expand Down
9 changes: 9 additions & 0 deletions lib/aquilon/worker/templates/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
PlenaryCollection, PlenaryClusterClient,
PlenaryResource, PlenaryPersonalityBase,
PlenaryServiceInstanceClientDefault,
PlenaryServiceInstanceData,
PlenaryServiceInstanceServerDefault)
from aquilon.worker.templates.personality import get_parameters_by_feature
from aquilon.worker.templates.panutils import (StructureTemplate, PanValue,
Expand Down Expand Up @@ -355,11 +356,13 @@ def body(self, lines):
continue

services = []
services_data = {}
required_services = self.dbobj.required_services

for si in self.dbobj.services_used:
required_services.pop(si.service, None)
services.append(PlenaryServiceInstanceClientDefault.template_name(si))
services_data[si.service.name] = PlenaryServiceInstanceData.template_name(si)
if required_services:
missing = ", ".join(sorted(srv.name for srv in required_services))
raise IncompleteError("{0} is missing the following required "
Expand Down Expand Up @@ -390,6 +393,12 @@ def body(self, lines):
pan_assign(lines, "/",
StructureTemplate(path,
{"metadata": PanValue("/metadata")}))

# Include service data
for service_name in sorted(services_data.keys()):
pan_assign(lines, "/system/services/%s" % service_name,
StructureTemplate(services_data[service_name]))

pan_include(lines, "archetype/base")

dbos = self.dbobj.operating_system
Expand Down
15 changes: 15 additions & 0 deletions lib/aquilon/worker/templates/metacluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
PlenaryCollection, PlenaryPersonalityBase,
PlenaryResource,
PlenaryServiceInstanceClientDefault,
PlenaryServiceInstanceData,
add_location_info)
from aquilon.worker.templates.panutils import (StructureTemplate, PanValue,
pan_assign, pan_include,
Expand Down Expand Up @@ -117,6 +118,14 @@ def get_key(self, exclusive=True):
return CompileKey.merge(keylist)

def body(self, lines):
# Collect configuration of used services
services = []
services_data = {}
for si in self.dbobj.services_used:
services.append(PlenaryServiceInstanceClientDefault.template_name(si))
services_data[si.service.name] = PlenaryServiceInstanceData.template_name(si)
services.sort()

# Allow settings such as loadpath to be modified by the archetype before anything else happens
# Included only if object_declarations_template option is true
# It the option is true, the template MUST exist
Expand All @@ -131,6 +140,12 @@ def body(self, lines):
pan_assign(lines, "/",
StructureTemplate("clusterdata/%s" % self.dbobj.name,
{"metadata": PanValue("/metadata")}))

# Include service data
for service_name in sorted(services_data.keys()):
pan_assign(lines, "/system/services/%s" % service_name,
StructureTemplate(services_data[service_name]))

pan_include(lines, "archetype/base")

for servinst in sorted(self.dbobj.services_used):
Expand Down
23 changes: 10 additions & 13 deletions lib/aquilon/worker/templates/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def __init__(self, dbservice, logger=LOGGER, allow_incomplete=True):
super(PlenaryService, self).__init__(logger=logger,
allow_incomplete=allow_incomplete)

self.append(PlenaryServiceToplevel.get_plenary(dbservice,
allow_incomplete=allow_incomplete))
self.append(PlenaryServiceData.get_plenary(dbservice,
allow_incomplete=allow_incomplete))
self.append(PlenaryServiceClientDefault.get_plenary(dbservice,
allow_incomplete=allow_incomplete))
self.append(PlenaryServiceServerDefault.get_plenary(dbservice,
Expand All @@ -48,7 +48,7 @@ def __init__(self, dbservice, logger=LOGGER, allow_incomplete=True):
Plenary.handlers[Service] = PlenaryService


class PlenaryServiceToplevel(StructurePlenary):
class PlenaryServiceData(StructurePlenary):
"""
The top-level service template does nothing. It is really
a placeholder which can be overridden by the library
Expand Down Expand Up @@ -128,8 +128,8 @@ def __init__(self, dbinstance, logger=LOGGER, allow_incomplete=True):
allow_incomplete=allow_incomplete)
self.dbobj = dbinstance

self.append(PlenaryServiceInstanceToplevel.get_plenary(dbinstance,
allow_incomplete=allow_incomplete))
self.append(PlenaryServiceInstanceData.get_plenary(dbinstance,
allow_incomplete=allow_incomplete))
self.append(PlenaryServiceInstanceClientDefault.get_plenary(dbinstance,
allow_incomplete=allow_incomplete))
self.append(PlenaryServiceInstanceServer.get_plenary(dbinstance,
Expand All @@ -140,7 +140,7 @@ def __init__(self, dbinstance, logger=LOGGER, allow_incomplete=True):
Plenary.handlers[ServiceInstance] = PlenaryServiceInstance


class PlenaryServiceInstanceToplevel(SIHelperMixin, StructurePlenary):
class PlenaryServiceInstanceData(SIHelperMixin, StructurePlenary):
"""
This structure template provides information for the template
specific to the service instance and for use by the client.
Expand All @@ -159,7 +159,7 @@ def template_name(cls, dbinstance):

def body(self, lines):
pan_include(lines,
PlenaryServiceToplevel.template_name(self.dbobj.service))
PlenaryServiceData.template_name(self.dbobj.service))
lines.append("")
pan_assign(lines, "instance", self.dbobj.name)

Expand Down Expand Up @@ -201,8 +201,9 @@ class PlenaryServiceInstanceClientDefault(SIHelperMixin, Plenary):
included from within the host.tpl. This may
be overridden within the template library, but this plenary
should typically be sufficient without override.
This template defines configuration for clients only, and
is specific to the instance.
This template defines configuration specific to the instance
for clients only but the instance data has to be loaded before
(the broker does it earlier in host object template).
"""

prefix = "service"
Expand All @@ -213,10 +214,6 @@ def template_name(cls, dbinstance):
dbinstance.name)

def body(self, lines):
path = PlenaryServiceInstanceToplevel.template_name(self.dbobj)
pan_assign(lines, "/system/services/%s" % self.dbobj.service,
StructureTemplate(path))

path = PlenaryServiceClientDefault.template_name(self.dbobj.service)
pan_include(lines, path)

Expand Down

0 comments on commit 0952758

Please sign in to comment.