try new object orientated (hrrr) code instead of stage based

Signed-off-by: Nico Schottelius <nico@bento.schottelius.org>
This commit is contained in:
Nico Schottelius 2013-04-30 10:58:23 +02:00
parent d8630dc6d4
commit a064cc19b3
3 changed files with 122 additions and 3 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# 2010-2012 Nico Schottelius (nico-cdist at schottelius.org) # 2010-2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -65,8 +65,13 @@ class ConfigInstall(object):
def deploy_to(self): def deploy_to(self):
"""Mimic the old deploy to: Deploy to one host""" """Mimic the old deploy to: Deploy to one host"""
self.stage_prepare()
self.stage_run() # Old Code
# self.stage_prepare()
# self.stage_run()
# New Code
self.run()
def deploy_and_cleanup(self): def deploy_and_cleanup(self):
"""Do what is most often done: deploy & cleanup""" """Do what is most often done: deploy & cleanup"""
@ -76,6 +81,62 @@ class ConfigInstall(object):
self.log.info("Finished successful run in %s seconds", self.log.info("Finished successful run in %s seconds",
time.time() - start_time) time.time() - start_time)
######################################################################
# New code for running on object priority (not stage priority)
#
def run(self):
"""The main runner"""
self.explorer.run_global_explorers(self.context.local.global_explorer_out_path)
self.manifest.run_initial_manifest(self.context.initial_manifest)
self.iterate_until_finished()
def object_list(self):
"""Short name for object list retrieval"""
for cdist_object in core.CdistObject.list_objects(self.context.local.object_path,
self.context.local.type_path):
yield cdist_object
def iterate_until_finished(self):
# Continue process until no new objects are created anymore
objects_changed = True
while objects_changed:
objects_changed = False
for cdist_object in self.object_list():
if not cdist_object.requirements_satisfied(cdist_object.requirements):
"""We cannot do anything for this poor object"""
continue
if cdist_object.state == core.CdistObject.STATE_UNDEF:
"""Prepare the virgin object"""
self.object_prepare(cdist_object)
objects_changed = True
if not cdist_object.requirements_satisfied(cdist_object.autorequire):
"""The previous step created objects we depend on - wait for them"""
continue
if cdist_object.state == core.CdistObject.STATE_PREPARED:
self.object_run(cdist_object)
# Check whether all objects have been finished
unfinished_object_names = []
for cdist_object in self.object_list():
if not cdist_object.state == cdist_object.STATE_DONE:
unfinished_object_names.append(cdist_object.name)
if unfinished_object_names:
raise cdist.Error("The following objects could not be resolved: %s" %
(" ".join(unfinished_object_names))
######################################################################
# Stages based code
#
def stage_prepare(self): def stage_prepare(self):
"""Do everything for a deploy, minus the actual code stage""" """Do everything for a deploy, minus the actual code stage"""
self.explorer.run_global_explorers(self.context.local.global_explorer_out_path) self.explorer.run_global_explorers(self.context.local.global_explorer_out_path)
@ -89,6 +150,7 @@ class ConfigInstall(object):
new_objects_created = False new_objects_created = False
for cdist_object in core.CdistObject.list_objects(self.context.local.object_path, for cdist_object in core.CdistObject.list_objects(self.context.local.object_path,
self.context.local.type_path): self.context.local.type_path):
if cdist_object.state == core.CdistObject.STATE_PREPARED: if cdist_object.state == core.CdistObject.STATE_PREPARED:
self.log.debug("Skipping re-prepare of object %s", cdist_object) self.log.debug("Skipping re-prepare of object %s", cdist_object)
continue continue

View file

@ -61,6 +61,7 @@ class CdistObject(object):
""" """
# Constants for use with Object.state # Constants for use with Object.state
STATE_UNDEF = ""
STATE_PREPARED = "prepared" STATE_PREPARED = "prepared"
STATE_RUNNING = "running" STATE_RUNNING = "running"
STATE_DONE = "done" STATE_DONE = "done"
@ -223,6 +224,23 @@ class CdistObject(object):
except EnvironmentError as error: except EnvironmentError as error:
raise cdist.Error('Error creating directories for cdist object: %s: %s' % (self, error)) raise cdist.Error('Error creating directories for cdist object: %s: %s' % (self, error))
@property
def requirements_satisfied(self):
"""Return state whether normal depedencies are satisfied"""
satisfied = True
for requirement in self.requirements:
cdist_object = self.object_from_name(requirement)
if not cdist_object.state == self.STATE_DONE:
satisfied = False
break
log.debug("%s is satisfied: %s" % (self.name, satisfied))
return satisfied
@property @property
def satisfied_requirements(self): def satisfied_requirements(self):
"""Return state whether all of our dependencies have been resolved already""" """Return state whether all of our dependencies have been resolved already"""

View file

@ -0,0 +1,39 @@
Old:
- global explores (all)
- initial manifest
- for each object
execute type explorers
execute manifest
continue until all objects (including newly created)
have their type explorers/manifests run
- build dependency tree
- for each object
execute gencode-*
execute code-*
New:
- run all global explorers
- run initial manifest
creates zero or more cdist_objects
- for each cdist_object
if not cdist_object.has_unfullfilled_requirements:
execute type explorers
execute manifest
may create new objects, resulting in autorequirements
# Gained requirements during manifest run
if object.has_auto_requirements():
continue
cdist_object.execute gencode-*
cdist_object.execute code-*
Requirements / Test cases for requirments / resolver:
- omnipotence
-
Test