forked from ungleich-public/cdist
Merge branch 'master' into autorequire
Conflicts: lib/cdist/test/emulator/__init__.py Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
This commit is contained in:
commit
f36d09289d
17 changed files with 445 additions and 21 deletions
|
|
@ -71,7 +71,7 @@ class ConfigInstall(object):
|
|||
start_time = time.time()
|
||||
self.deploy_to()
|
||||
self.cleanup()
|
||||
self.log.info("Finished run in %s seconds",
|
||||
self.log.info("Finished successful run in %s seconds",
|
||||
time.time() - start_time)
|
||||
|
||||
def stage_prepare(self):
|
||||
|
|
@ -106,7 +106,7 @@ class ConfigInstall(object):
|
|||
"""Run gencode and code for an object"""
|
||||
self.log.debug("Trying to run object " + cdist_object.name)
|
||||
if cdist_object.state == core.Object.STATE_RUNNING:
|
||||
# FIXME: resolve dependency circle
|
||||
# FIXME: resolve dependency circle / show problem source
|
||||
raise cdist.Error("Detected circular dependency in " + cdist_object.name)
|
||||
elif cdist_object.state == core.Object.STATE_DONE:
|
||||
self.log.debug("Ignoring run of already finished object %s", cdist_object)
|
||||
|
|
@ -119,6 +119,13 @@ class ConfigInstall(object):
|
|||
for requirement in cdist_object.requirements:
|
||||
self.log.debug("Object %s requires %s", cdist_object, requirement)
|
||||
required_object = cdist_object.object_from_name(requirement)
|
||||
|
||||
# The user may have created dependencies without satisfying them
|
||||
if not required_object.exists:
|
||||
raise cdist.Error(cdist_object.name + " requires non-existing " + required_object.name)
|
||||
else:
|
||||
self.log.debug("Required object %s exists", required_object.name)
|
||||
|
||||
self.object_run(required_object)
|
||||
|
||||
# Generate
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from cdist.core.type import Type
|
|||
from cdist.core.type import NoSuchTypeError
|
||||
from cdist.core.object import Object
|
||||
from cdist.core.object import IllegalObjectIdError
|
||||
from cdist.core.object import OBJECT_MARKER
|
||||
from cdist.core.explorer import Explorer
|
||||
from cdist.core.manifest import Manifest
|
||||
from cdist.core.code import Code
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ from cdist.util import fsproperty
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
DOT_CDIST = '.cdist'
|
||||
OBJECT_MARKER = '.cdist'
|
||||
|
||||
|
||||
class IllegalObjectIdError(cdist.Error):
|
||||
|
|
@ -72,7 +72,7 @@ class Object(object):
|
|||
def list_object_names(cls, object_base_path):
|
||||
"""Return a list of object names"""
|
||||
for path, dirs, files in os.walk(object_base_path):
|
||||
if DOT_CDIST in dirs:
|
||||
if OBJECT_MARKER in dirs:
|
||||
yield os.path.relpath(path, object_base_path)
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -100,13 +100,13 @@ class Object(object):
|
|||
if object_id:
|
||||
if object_id.startswith('/'):
|
||||
raise IllegalObjectIdError(object_id, 'object_id may not start with /')
|
||||
if '.cdist' in object_id:
|
||||
raise IllegalObjectIdError(object_id, 'object_id may not contain \'.cdist\'')
|
||||
if OBJECT_MARKER in object_id.split(os.sep):
|
||||
raise IllegalObjectIdError(object_id, 'object_id may not contain \'%s\'' % OBJECT_MARKER)
|
||||
self.type = cdist_type # instance of Type
|
||||
self.base_path = base_path
|
||||
self.object_id = object_id
|
||||
self.name = self.join_name(self.type.name, self.object_id)
|
||||
self.path = os.path.join(self.type.path, self.object_id, DOT_CDIST)
|
||||
self.path = os.path.join(self.type.path, self.object_id, OBJECT_MARKER)
|
||||
self.absolute_path = os.path.join(self.base_path, self.path)
|
||||
self.code_local_path = os.path.join(self.path, "code-local")
|
||||
self.code_remote_path = os.path.join(self.path, "code-remote")
|
||||
|
|
@ -132,9 +132,9 @@ class Object(object):
|
|||
|
||||
"""
|
||||
type_path = self.type.base_path
|
||||
object_path = self.base_path
|
||||
base_path = self.base_path
|
||||
type_name, object_id = self.split_name(object_name)
|
||||
return self.__class__(self.type.__class__(type_path, type_name), object_path, object_id=object_id)
|
||||
return self.__class__(self.type.__class__(type_path, type_name), base_path, object_id=object_id)
|
||||
|
||||
# FIXME: still needed?
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -157,19 +157,22 @@ class Emulator(object):
|
|||
self.log.debug("Recording requirement: " + requirement)
|
||||
requirement_parts = requirement.split(os.sep, 1)
|
||||
requirement_type_name = requirement_parts[0]
|
||||
requirement_object_id = requirement_parts[1]
|
||||
|
||||
# FIXME: Add support for omitted object id == singleton
|
||||
#if len(requirement_parts) == 1:
|
||||
#except IndexError:
|
||||
# # no object id, must be singleton
|
||||
# requirement_object_id = 'singleton'
|
||||
|
||||
# Remove / if existent in object id
|
||||
try:
|
||||
requirement_object_id = requirement_parts[1]
|
||||
except IndexError:
|
||||
# no object id, assume singleton
|
||||
requirement_object_id = 'singleton'
|
||||
|
||||
# Remove leading / from object id
|
||||
requirement_object_id = requirement_object_id.lstrip('/')
|
||||
|
||||
# Instantiate type which fails if type does not exist
|
||||
requirement_type = core.Type(self.type_base_path, requirement_type_name)
|
||||
|
||||
if requirement_object_id == 'singleton' \
|
||||
and not requirement_type.is_singleton:
|
||||
raise IllegalRequirementError(requirement, "Missing object_id and type is not a singleton.")
|
||||
|
||||
# Instantiate object which fails if the object_id is illegal
|
||||
requirement_object = core.Object(requirement_type, self.object_base_path, requirement_object_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,21 @@ class EmulatorTestCase(test.CdistTestCase):
|
|||
emu = emulator.Emulator(argv)
|
||||
self.assertRaises(core.IllegalObjectIdError, emu.run)
|
||||
|
||||
def test_missing_object_id_requirement(self):
|
||||
argv = ['__file', '/tmp/foobar']
|
||||
os.environ.update(self.env)
|
||||
os.environ['require'] = '__file'
|
||||
emu = emulator.Emulator(argv)
|
||||
self.assertRaises(emulator.IllegalRequirementError, emu.run)
|
||||
|
||||
def test_singleton_object_requirement(self):
|
||||
argv = ['__file', '/tmp/foobar']
|
||||
os.environ.update(self.env)
|
||||
os.environ['require'] = '__issue'
|
||||
emu = emulator.Emulator(argv)
|
||||
emu.run()
|
||||
# if we get here all is fine
|
||||
|
||||
|
||||
import os.path as op
|
||||
my_dir = op.abspath(op.dirname(__file__))
|
||||
|
|
|
|||
|
|
@ -58,12 +58,18 @@ class ObjectIdTestCase(test.CdistTestCase):
|
|||
with self.assertRaises(core.IllegalObjectIdError):
|
||||
core.Object(cdist_type, object_base_path, illegal_object_id)
|
||||
|
||||
def test_object_id_contains_dotcdist(self):
|
||||
def test_object_id_contains_object_marker(self):
|
||||
cdist_type = core.Type(type_base_path, '__third')
|
||||
illegal_object_id = 'object_id/may/not/contain/.cdist/anywhere'
|
||||
illegal_object_id = 'object_id/may/not/contain/%s/anywhere' % core.OBJECT_MARKER
|
||||
with self.assertRaises(core.IllegalObjectIdError):
|
||||
core.Object(cdist_type, object_base_path, illegal_object_id)
|
||||
|
||||
def test_object_id_contains_object_marker_string(self):
|
||||
cdist_type = core.Type(type_base_path, '__third')
|
||||
illegal_object_id = 'object_id/may/contain_%s_in_filename' % core.OBJECT_MARKER
|
||||
core.Object(cdist_type, object_base_path, illegal_object_id)
|
||||
# if we get here, the test passed
|
||||
|
||||
|
||||
class ObjectTestCase(test.CdistTestCase):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue