From 48ae37e832d921ecd0fd32bb250723b1d56429db Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:04:23 +0200 Subject: [PATCH 01/29] implement transfer_object_parameters Signed-off-by: Steven Armstrong --- lib/cdist/core/explorer.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/cdist/core/explorer.py b/lib/cdist/core/explorer.py index c79124b3..ad19db20 100644 --- a/lib/cdist/core/explorer.py +++ b/lib/cdist/core/explorer.py @@ -74,7 +74,8 @@ class Explorer(object): '__explorer': self.remote.global_explorer_path, } - # FIXME: should i do this? + ### global + def transfer_global_explorers(self): """Transfer the global explorers to the remote side.""" self.remote.mkdir(self.remote.global_explorer_path) @@ -85,7 +86,8 @@ class Explorer(object): script = os.path.join(self.remote.global_explorer_path, explorer) return self.remote.run_script(script, env=self.env) - # FIXME: should i do this? + ### type + def transfer_type_explorers(self, cdist_type): """Transfer the type explorers for the given type to the remote side.""" source = os.path.join(self.local.type_path, cdist_type.explorer_path) @@ -93,9 +95,12 @@ class Explorer(object): self.remote.mkdir(destination) self.remote.transfer(source, destination) - # FIXME: should i do this? probably not def transfer_object_parameters(self, cdist_object): - pass + """Transfer the parameters for the given object to the remote side.""" + source = os.path.join(self.local.object_path, cdist_object.parameter_path) + destination = os.path.join(self.remotei.object_path, cdist_object.parameter_path) + self.remote.mkdir(destination) + self.remote.transfer(source, destination) def run_type_explorer(self, explorer, cdist_object): """Run the given type explorer for the given object and return it's output.""" From d136a6dee340b76ca883826301f03e266f75b887 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:14:01 +0200 Subject: [PATCH 02/29] DirectoryDictProperty: create directory before writing Signed-off-by: Steven Armstrong --- lib/cdist/util/fsproperty.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/cdist/util/fsproperty.py b/lib/cdist/util/fsproperty.py index 68d5edaa..50b95ea2 100644 --- a/lib/cdist/util/fsproperty.py +++ b/lib/cdist/util/fsproperty.py @@ -221,6 +221,8 @@ class DirectoryDictProperty(DirectoryDict): def __set__(self, obj, value): self._set_path(obj) if value is not None: + # create directory if it doesn't exist + os.makedirs(self.path, exist_ok=True) for name in self.keys(): del self[name] self.update(value) From dc6218c3e1fb182f899c7dff0de9e52726d06803 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:14:46 +0200 Subject: [PATCH 03/29] initial test for test_transfer_object_parameters Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index 6fad157b..8139431b 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -79,6 +79,13 @@ class ExplorerClassTestCase(unittest.TestCase): cdist_type = core.Type(self.local.type_path, '__test_type') self.explorer.transfer_type_explorers(cdist_type) + def test_transfer_object_parameters(self): + # FIXME: test result + cdist_type = core.Type(self.local.type_path, '__test_type') + cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') + cdist_object.parameters = {'first': 'first value', 'second': 'second value'} + self.explorer.transfer_object_parameters(cdist_object) + def test_run_type_explorer(self): cdist_type = core.Type(self.local.type_path, '__test_type') cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') From 20fae8b52b2751b891cd041df98c88b73f07e0b1 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:14:56 +0200 Subject: [PATCH 04/29] fix typo Signed-off-by: Steven Armstrong --- lib/cdist/core/explorer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cdist/core/explorer.py b/lib/cdist/core/explorer.py index ad19db20..b86054c7 100644 --- a/lib/cdist/core/explorer.py +++ b/lib/cdist/core/explorer.py @@ -98,7 +98,7 @@ class Explorer(object): def transfer_object_parameters(self, cdist_object): """Transfer the parameters for the given object to the remote side.""" source = os.path.join(self.local.object_path, cdist_object.parameter_path) - destination = os.path.join(self.remotei.object_path, cdist_object.parameter_path) + destination = os.path.join(self.remote.object_path, cdist_object.parameter_path) self.remote.mkdir(destination) self.remote.transfer(source, destination) From 910de0579cc62fb0ba9bf34c4b76b4d6a70fcabb Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:17:22 +0200 Subject: [PATCH 05/29] add assertion for test_transfer_object_parameters Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index 8139431b..eb45778b 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -80,11 +80,13 @@ class ExplorerClassTestCase(unittest.TestCase): self.explorer.transfer_type_explorers(cdist_type) def test_transfer_object_parameters(self): - # FIXME: test result cdist_type = core.Type(self.local.type_path, '__test_type') cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') cdist_object.parameters = {'first': 'first value', 'second': 'second value'} self.explorer.transfer_object_parameters(cdist_object) + source = os.path.join(self.local.object_path, cdist_object.parameter_path) + destination = os.path.join(self.remote.object_path, cdist_object.parameter_path) + self.assertEqual(os.listdir(source), os.listdir(destination)) def test_run_type_explorer(self): cdist_type = core.Type(self.local.type_path, '__test_type') From 2eb37367a18ba6168d06f61f0c98a21597df5b60 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:18:34 +0200 Subject: [PATCH 06/29] add assertion for test_transfer_type_explorers Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index eb45778b..e6b36f1b 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -75,9 +75,11 @@ class ExplorerClassTestCase(unittest.TestCase): self.explorer.run_global_explorer('global') def test_transfer_type_explorers(self): - # FIXME: test result cdist_type = core.Type(self.local.type_path, '__test_type') self.explorer.transfer_type_explorers(cdist_type) + source = os.path.join(self.local.type_path, cdist_type.explorer_path) + destination = os.path.join(self.remote.type_path, cdist_type.explorer_path) + self.assertEqual(os.listdir(source), os.listdir(destination)) def test_transfer_object_parameters(self): cdist_type = core.Type(self.local.type_path, '__test_type') From f846fdd961501d4133042d49123e4ca8b57d10b3 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:20:07 +0200 Subject: [PATCH 07/29] add assertion for test_transfer_global_explorers Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index e6b36f1b..bc1ef820 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -66,8 +66,10 @@ class ExplorerClassTestCase(unittest.TestCase): shutil.rmtree(self.remote_base_path) def test_transfer_global_explorers(self): - # FIXME: test result self.explorer.transfer_global_explorers() + source = self.local.global_explorer_path + destination = self.remote.global_explorer_path + self.assertEqual(os.listdir(source), os.listdir(destination)) def test_run_global_explorer(self): # FIXME: test result From f1fdf0f13c4c92564acb55b232137f6953e90378 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:21:15 +0200 Subject: [PATCH 08/29] add assertion for test_run_global_explorer Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index bc1ef820..5974b43a 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -72,9 +72,9 @@ class ExplorerClassTestCase(unittest.TestCase): self.assertEqual(os.listdir(source), os.listdir(destination)) def test_run_global_explorer(self): - # FIXME: test result self.explorer.transfer_global_explorers() - self.explorer.run_global_explorer('global') + output = self.explorer.run_global_explorer('global') + self.assertEqual(output, 'global\n') def test_transfer_type_explorers(self): cdist_type = core.Type(self.local.type_path, '__test_type') From ac79ec101fd678fdb706ed919fa98f0b0110fa23 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:22:52 +0200 Subject: [PATCH 09/29] +consistency Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index 5974b43a..a4ad4f7f 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -96,5 +96,6 @@ class ExplorerClassTestCase(unittest.TestCase): cdist_type = core.Type(self.local.type_path, '__test_type') cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') self.explorer.transfer_type_explorers(cdist_type) - self.assertEqual(self.explorer.run_type_explorer('world', cdist_object), 'hello\n') + output = self.explorer.run_type_explorer('world', cdist_object) + self.assertEqual(output, 'hello\n') From f02bdf3e6196285d23a7fd3ff26577ce5840f421 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:30:41 +0200 Subject: [PATCH 10/29] test for test_list_global_explorer_names Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index a4ad4f7f..67c05913 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -65,6 +65,10 @@ class ExplorerClassTestCase(unittest.TestCase): shutil.rmtree(self.out_path) shutil.rmtree(self.remote_base_path) + def test_list_global_explorer_names(self): + expected = ['global'] + self.assertEqual(self.explorer.list_global_explorer_names(), expected) + def test_transfer_global_explorers(self): self.explorer.transfer_global_explorers() source = self.local.global_explorer_path From 86fcce928c562dd7f14ccf4d6833db8736120dba Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:31:42 +0200 Subject: [PATCH 11/29] implement list_global_explorer_names Signed-off-by: Steven Armstrong --- lib/cdist/core/explorer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cdist/core/explorer.py b/lib/cdist/core/explorer.py index b86054c7..562683f4 100644 --- a/lib/cdist/core/explorer.py +++ b/lib/cdist/core/explorer.py @@ -76,6 +76,10 @@ class Explorer(object): ### global + def list_global_explorer_names(self): + """Return a list of global explorer names.""" + return os.listdir(self.local.global_explorer_path) + def transfer_global_explorers(self): """Transfer the global explorers to the remote side.""" self.remote.mkdir(self.remote.global_explorer_path) From fb4d20e7e853f8f15cbd4f5b6aae238741478531 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:33:24 +0200 Subject: [PATCH 12/29] test for test_list_type_explorer_names Signed-off-by: Steven Armstrong --- lib/cdist/test/explorer/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/cdist/test/explorer/__init__.py b/lib/cdist/test/explorer/__init__.py index 67c05913..96206ae0 100644 --- a/lib/cdist/test/explorer/__init__.py +++ b/lib/cdist/test/explorer/__init__.py @@ -80,6 +80,11 @@ class ExplorerClassTestCase(unittest.TestCase): output = self.explorer.run_global_explorer('global') self.assertEqual(output, 'global\n') + def test_list_type_explorer_names(self): + cdist_type = core.Type(self.local.type_path, '__test_type') + expected = cdist_type.explorers + self.assertEqual(self.explorer.list_type_explorer_names(cdist_type), expected) + def test_transfer_type_explorers(self): cdist_type = core.Type(self.local.type_path, '__test_type') self.explorer.transfer_type_explorers(cdist_type) From 8fb51a396a640066c99083df69521bd8b1a9148a Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:34:06 +0200 Subject: [PATCH 13/29] implement list_type_explorer_names Signed-off-by: Steven Armstrong --- lib/cdist/core/explorer.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/cdist/core/explorer.py b/lib/cdist/core/explorer.py index 562683f4..7e61639e 100644 --- a/lib/cdist/core/explorer.py +++ b/lib/cdist/core/explorer.py @@ -92,6 +92,11 @@ class Explorer(object): ### type + def list_type_explorer_names(self, cdist_type): + """Return a list of explorer names for the given type.""" + source = os.path.join(self.local.type_path, cdist_type.explorer_path) + return os.listdir(source) + def transfer_type_explorers(self, cdist_type): """Transfer the type explorers for the given type to the remote side.""" source = os.path.join(self.local.type_path, cdist_type.explorer_path) From 8e55e74bc274914b3e2e6c09405f5114a52bfcfd Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:40:20 +0200 Subject: [PATCH 14/29] test for code_local Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index 6f26fd19..8cffe053 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -136,3 +136,10 @@ class ObjectTestCase(unittest.TestCase): def test_source_after_changing(self): self.cdist_object.source = ['/path/to/manifest'] self.assertEqual(list(self.cdist_object.source), ['/path/to/manifest']) + + def test_code_local(self): + self.assertEqual(self.cdist_object.code_local, '') + + def test_code_local_after_changing(self): + self.cdist_object.code_local = 'Hello World' + self.assertEqual(self.cdist_object.code_local, 'Hello World') From 93ede2a3bedbc6d4e86bb470e4eb690cfae0054a Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:40:50 +0200 Subject: [PATCH 15/29] implement code_local Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index b7890eeb..8cea077c 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -99,6 +99,7 @@ class Object(object): prepared = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "prepared")) ran = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "ran")) source = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, "source")) + code_local = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.absolute_path, "code-local")) @property def exists(self): From 6f7528c4114bc09c067c1a9b689cd82ba35c354e Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:42:45 +0200 Subject: [PATCH 16/29] test for code_remote Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index 8cffe053..0953027b 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -63,6 +63,8 @@ class ObjectTestCase(unittest.TestCase): self.cdist_object.prepared = False self.cdist_object.ran = False self.cdist_object.source = [] + self.cdist_object.code_local = '' + self.cdist_object.code_remote = '' def test_name(self): self.assertEqual(self.cdist_object.name, '__third/moon') @@ -143,3 +145,10 @@ class ObjectTestCase(unittest.TestCase): def test_code_local_after_changing(self): self.cdist_object.code_local = 'Hello World' self.assertEqual(self.cdist_object.code_local, 'Hello World') + + def test_code_remote(self): + self.assertEqual(self.cdist_object.code_remote, '') + + def test_code_remote_after_changing(self): + self.cdist_object.code_remote = 'Hello World' + self.assertEqual(self.cdist_object.code_remote, 'Hello World') From 939962b583f741f5f24ce57ab2534389bbffa9f9 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 13:42:58 +0200 Subject: [PATCH 17/29] implement code_remote Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 8cea077c..242b094a 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -100,6 +100,7 @@ class Object(object): ran = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "ran")) source = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, "source")) code_local = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.absolute_path, "code-local")) + code_remote = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.absolute_path, "code-remote")) @property def exists(self): From df57b5188b3604a06bd5564d261110636505c84c Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:26:36 +0200 Subject: [PATCH 18/29] tests for code Signed-off-by: Steven Armstrong --- lib/cdist/test/code/__init__.py | 132 ++++++++++++++++++ .../type/__dump_environment/gencode-local | 8 ++ .../type/__dump_environment/gencode-remote | 1 + 3 files changed, 141 insertions(+) create mode 100644 lib/cdist/test/code/__init__.py create mode 100755 lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-local create mode 120000 lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-remote diff --git a/lib/cdist/test/code/__init__.py b/lib/cdist/test/code/__init__.py new file mode 100644 index 00000000..397922e8 --- /dev/null +++ b/lib/cdist/test/code/__init__.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import os +import tempfile +import unittest +import shutil +import getpass + +import cdist +from cdist import core +from cdist import test +from cdist.exec import local +from cdist.exec import remote +from cdist.core import code + +import os.path as op +my_dir = op.abspath(op.dirname(__file__)) +fixtures = op.join(my_dir, 'fixtures') +local_base_path = fixtures + +class ExplorerClassTestCase(unittest.TestCase): + + def mkdtemp(self, **kwargs): + return tempfile.mkdtemp(prefix='tmp.cdist.test.', **kwargs) + + def mkstemp(self, **kwargs): + return tempfile.mkstemp(prefix='tmp.cdist.test.', **kwargs) + + def setUp(self): + target_host = 'localhost' + + self.local_base_path = local_base_path + self.out_path = self.mkdtemp() + self.local = local.Local(target_host, self.local_base_path, self.out_path) + self.local.create_directories() + + self.remote_base_path = self.mkdtemp() + self.user = getpass.getuser() + remote_exec = "ssh -o User=%s -q" % self.user + remote_copy = "scp -o User=%s -q" % self.user + self.remote = remote.Remote(target_host, self.remote_base_path, remote_exec, remote_copy) + + self.code = code.Code(target_host, self.local, self.remote) + + def tearDown(self): + shutil.rmtree(self.out_path) + shutil.rmtree(self.remote_base_path) + + def test_run_gencode_local_environment(self): + cdist_type = core.Type(self.local.type_path, '__dump_environment') + cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') + output_string = self.code.run_gencode_local(cdist_object) + output_dict = {} + for line in output_string.split('\n'): + if line: + junk,value = line.split(': ') + key = junk.split(' ')[1] + output_dict[key] = value + self.assertEqual(output_dict['__target_host'], self.local.target_host) + self.assertEqual(output_dict['__global'], self.local.out_path) + self.assertEqual(output_dict['__type'], cdist_type.absolute_path) + self.assertEqual(output_dict['__object'], cdist_object.absolute_path) + self.assertEqual(output_dict['__object_id'], cdist_object.object_id) + self.assertEqual(output_dict['__object_fq'], cdist_object.path) + + def test_run_gencode_remote_environment(self): + cdist_type = core.Type(self.local.type_path, '__dump_environment') + cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') + output_string = self.code.run_gencode_remote(cdist_object) + output_dict = {} + for line in output_string.split('\n'): + if line: + junk,value = line.split(': ') + key = junk.split(' ')[1] + output_dict[key] = value + self.assertEqual(output_dict['__target_host'], self.local.target_host) + self.assertEqual(output_dict['__global'], self.local.out_path) + self.assertEqual(output_dict['__type'], cdist_type.absolute_path) + self.assertEqual(output_dict['__object'], cdist_object.absolute_path) + self.assertEqual(output_dict['__object_id'], cdist_object.object_id) + self.assertEqual(output_dict['__object_fq'], cdist_object.path) + + + +''' + def test_list_type_explorer_names(self): + cdist_type = core.Type(self.local.type_path, '__test_type') + expected = cdist_type.explorers + self.assertEqual(self.explorer.list_type_explorer_names(cdist_type), expected) + + def test_transfer_type_explorers(self): + cdist_type = core.Type(self.local.type_path, '__test_type') + self.explorer.transfer_type_explorers(cdist_type) + source = os.path.join(self.local.type_path, cdist_type.explorer_path) + destination = os.path.join(self.remote.type_path, cdist_type.explorer_path) + self.assertEqual(os.listdir(source), os.listdir(destination)) + + def test_transfer_object_parameters(self): + cdist_type = core.Type(self.local.type_path, '__test_type') + cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') + cdist_object.parameters = {'first': 'first value', 'second': 'second value'} + self.explorer.transfer_object_parameters(cdist_object) + source = os.path.join(self.local.object_path, cdist_object.parameter_path) + destination = os.path.join(self.remote.object_path, cdist_object.parameter_path) + self.assertEqual(os.listdir(source), os.listdir(destination)) + + def test_run_type_explorer(self): + cdist_type = core.Type(self.local.type_path, '__test_type') + cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') + self.explorer.transfer_type_explorers(cdist_type) + output = self.explorer.run_type_explorer('world', cdist_object) + self.assertEqual(output, 'hello\n') +''' diff --git a/lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-local b/lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-local new file mode 100755 index 00000000..ac292546 --- /dev/null +++ b/lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-local @@ -0,0 +1,8 @@ +#!/bin/sh + +echo "echo __target_host: $__target_host" +echo "echo __global: $__global" +echo "echo __type: $__type" +echo "echo __object: $__object" +echo "echo __object_id: $__object_id" +echo "echo __object_fq: $__object_fq" diff --git a/lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-remote b/lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-remote new file mode 120000 index 00000000..7b427cac --- /dev/null +++ b/lib/cdist/test/code/fixtures/conf/type/__dump_environment/gencode-remote @@ -0,0 +1 @@ +gencode-local \ No newline at end of file From 6d438d4ec5cbb738283fa37c1f96e61834287412 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:29:20 +0200 Subject: [PATCH 19/29] implement run_gencode_local Signed-off-by: Steven Armstrong --- lib/cdist/core/code.py | 110 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 lib/cdist/core/code.py diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py new file mode 100644 index 00000000..de735cb4 --- /dev/null +++ b/lib/cdist/core/code.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# +# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# 2011 Nico Schottelius (nico-cdist at schottelius.org) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import logging +import os + +import cdist + +log = logging.getLogger(__name__) + + +''' +common: + runs only locally, does not need remote + + env: + PATH: prepend directory with type emulator symlinks == local.bin_path + __target_host: the target host we are working on + __cdist_manifest: full qualified path of the manifest == script + __cdist_type_base_path: full qualified path to the directory where types are defined for use in type emulator + == local.type_path + +gencode-local + script: full qualified path to a types gencode-local + + env: + __target_host: the target host we are working on + __global: full qualified path to the global output dir == local.out_path + __object: full qualified path to the object's dir + __object_id: the objects id + __object_fq: full qualified object id, iow: $type.name + / + object_id + __type: full qualified path to the type's dir + + returns: string containing the generated code or None + +gencode-remote + script: full qualified path to a types gencode-remote + + env: + __target_host: the target host we are working on + __global: full qualified path to the global output dir == local.out_path + __object: full qualified path to the object's dir + __object_id: the objects id + __object_fq: full qualified object id, iow: $type.name + / + object_id + __type: full qualified path to the type's dir + + returns: string containing the generated code or None + + +code-local + script: full qualified path to object's code-local + - run script localy + returns: string containing the output + +code-remote + script: full qualified path to object's code-remote + - copy script to remote + - run script remotely + returns: string containing the output +''' + + +class Code(object): + """Generates and executes cdist code scripts. + + """ + def __init__(self, target_host, local, remote): + self.target_host = target_host + self.local = local + self.remote = remote + self.env = { + '__target_host': self.target_host, + '__global': self.local.out_path, + } + + def _get_env_for_object(self, cdist_object): + return { + '__type': cdist_object.type.absolute_path, + '__object': cdist_object.absolute_path, + '__object_id': cdist_object.object_id, + '__object_fq': cdist_object.path, + } + + def run_gencode_local(self, cdist_object): + cdist_type = cdist_object.type + script = os.path.join(self.local.type_path, cdist_type.gencode_local_path) + env = os.environ.copy() + env.update(self.env) + env.update(self._get_env_for_object(cdist_object)) + return self.local.run_script(script, env=env) + From 1665b4b5e651b392b91c1a946180117a9cd61eca Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:32:52 +0200 Subject: [PATCH 20/29] implement run_gencode_remote Signed-off-by: Steven Armstrong --- lib/cdist/core/code.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py index de735cb4..a6804c0b 100644 --- a/lib/cdist/core/code.py +++ b/lib/cdist/core/code.py @@ -100,11 +100,18 @@ class Code(object): '__object_fq': cdist_object.path, } - def run_gencode_local(self, cdist_object): + def _run_gencode(self, cdist_object, which): cdist_type = cdist_object.type - script = os.path.join(self.local.type_path, cdist_type.gencode_local_path) + script = os.path.join(self.local.type_path, getattr(cdist_type, 'gencode_%s_path' % which)) env = os.environ.copy() env.update(self.env) env.update(self._get_env_for_object(cdist_object)) return self.local.run_script(script, env=env) + def run_gencode_local(self, cdist_object): + """Run the gencode-local script for the given cdist object.""" + return self._run_gencode(cdist_object, 'local') + + def run_gencode_remote(self, cdist_object): + """Run the gencode-remote script for the given cdist object.""" + return self._run_gencode(cdist_object, 'remote') From 5edcc0537b4671d5888a43a8b2113ff8fa7aabeb Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:37:50 +0200 Subject: [PATCH 21/29] use api internally instead of constructing the same paths again Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 242b094a..a170dd30 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -93,14 +93,14 @@ class Object(object): return os.path.join(self.path, "explorer") requirements = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'require')) - parameters = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.absolute_path, 'parameter')) + parameters = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.parameter_path)) explorers = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.explorer_path)) changed = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "changed")) prepared = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "prepared")) ran = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "ran")) source = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, "source")) - code_local = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.absolute_path, "code-local")) - code_remote = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.absolute_path, "code-remote")) + code_local = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.base_path, obj.code_local_path)) + code_remote = fsproperty.FileStringProperty(lambda obj: os.path.join(obj.base_path, obj.code_remote_path)) @property def exists(self): From 01ab81a4469d58f2fb421ea3141c6cae228954df Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:50:50 +0200 Subject: [PATCH 22/29] -- duplicate code Signed-off-by: Steven Armstrong --- lib/cdist/test/code/__init__.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/cdist/test/code/__init__.py b/lib/cdist/test/code/__init__.py index 397922e8..0c35e09a 100644 --- a/lib/cdist/test/code/__init__.py +++ b/lib/cdist/test/code/__init__.py @@ -61,14 +61,15 @@ class ExplorerClassTestCase(unittest.TestCase): self.code = code.Code(target_host, self.local, self.remote) + self.cdist_type = core.Type(self.local.type_path, '__dump_environment') + self.cdist_object = core.Object(self.cdist_type, self.local.object_path, 'whatever') + def tearDown(self): shutil.rmtree(self.out_path) shutil.rmtree(self.remote_base_path) def test_run_gencode_local_environment(self): - cdist_type = core.Type(self.local.type_path, '__dump_environment') - cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') - output_string = self.code.run_gencode_local(cdist_object) + output_string = self.code.run_gencode_local(self.cdist_object) output_dict = {} for line in output_string.split('\n'): if line: @@ -77,15 +78,13 @@ class ExplorerClassTestCase(unittest.TestCase): output_dict[key] = value self.assertEqual(output_dict['__target_host'], self.local.target_host) self.assertEqual(output_dict['__global'], self.local.out_path) - self.assertEqual(output_dict['__type'], cdist_type.absolute_path) - self.assertEqual(output_dict['__object'], cdist_object.absolute_path) - self.assertEqual(output_dict['__object_id'], cdist_object.object_id) - self.assertEqual(output_dict['__object_fq'], cdist_object.path) + self.assertEqual(output_dict['__type'], self.cdist_type.absolute_path) + self.assertEqual(output_dict['__object'], self.cdist_object.absolute_path) + self.assertEqual(output_dict['__object_id'], self.cdist_object.object_id) + self.assertEqual(output_dict['__object_fq'], self.cdist_object.path) def test_run_gencode_remote_environment(self): - cdist_type = core.Type(self.local.type_path, '__dump_environment') - cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever') - output_string = self.code.run_gencode_remote(cdist_object) + output_string = self.code.run_gencode_remote(self.cdist_object) output_dict = {} for line in output_string.split('\n'): if line: @@ -94,12 +93,12 @@ class ExplorerClassTestCase(unittest.TestCase): output_dict[key] = value self.assertEqual(output_dict['__target_host'], self.local.target_host) self.assertEqual(output_dict['__global'], self.local.out_path) - self.assertEqual(output_dict['__type'], cdist_type.absolute_path) - self.assertEqual(output_dict['__object'], cdist_object.absolute_path) - self.assertEqual(output_dict['__object_id'], cdist_object.object_id) - self.assertEqual(output_dict['__object_fq'], cdist_object.path) - + self.assertEqual(output_dict['__type'], self.cdist_type.absolute_path) + self.assertEqual(output_dict['__object'], self.cdist_object.absolute_path) + self.assertEqual(output_dict['__object_id'], self.cdist_object.object_id) + self.assertEqual(output_dict['__object_fq'], self.cdist_object.path) + ''' def test_list_type_explorer_names(self): From 5055afe0c08f67cf1bf484016b2c4a415a6b87bb Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:57:09 +0200 Subject: [PATCH 23/29] test for test_transfer_code_remote Signed-off-by: Steven Armstrong --- lib/cdist/test/code/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/cdist/test/code/__init__.py b/lib/cdist/test/code/__init__.py index 0c35e09a..be4530d8 100644 --- a/lib/cdist/test/code/__init__.py +++ b/lib/cdist/test/code/__init__.py @@ -63,6 +63,7 @@ class ExplorerClassTestCase(unittest.TestCase): self.cdist_type = core.Type(self.local.type_path, '__dump_environment') self.cdist_object = core.Object(self.cdist_type, self.local.object_path, 'whatever') + self.cdist_object.create() def tearDown(self): shutil.rmtree(self.out_path) @@ -98,6 +99,12 @@ class ExplorerClassTestCase(unittest.TestCase): self.assertEqual(output_dict['__object_id'], self.cdist_object.object_id) self.assertEqual(output_dict['__object_fq'], self.cdist_object.path) + def test_transfer_code_remote(self): + self.cdist_object.code_remote = self.code.run_gencode_remote(self.cdist_object) + self.code.transfer_code_remote(self.cdist_object) + destination = os.path.join(self.remote.object_path, self.cdist_object.code_remote_path) + self.assertTrue(os.path.isfile(destination)) + ''' From 31ce938593ca53c32a7c7756eadd8a373676f42e Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 14:57:49 +0200 Subject: [PATCH 24/29] implement transfer_code_remote Signed-off-by: Steven Armstrong --- lib/cdist/core/code.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py index a6804c0b..c42c360b 100644 --- a/lib/cdist/core/code.py +++ b/lib/cdist/core/code.py @@ -115,3 +115,10 @@ class Code(object): def run_gencode_remote(self, cdist_object): """Run the gencode-remote script for the given cdist object.""" return self._run_gencode(cdist_object, 'remote') + + def transfer_code_remote(self, cdist_object): + """Transfer the code_remote script for the given object to the remote side.""" + source = os.path.join(self.local.object_path, cdist_object.code_remote_path) + destination = os.path.join(self.remote.object_path, cdist_object.code_remote_path) + self.remote.mkdir(destination) + self.remote.transfer(source, destination) From 12e5b3e8dc2c480c3359499a9bef8c49222c93b7 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 15:00:07 +0200 Subject: [PATCH 25/29] test for run_code_local Signed-off-by: Steven Armstrong --- lib/cdist/test/code/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/cdist/test/code/__init__.py b/lib/cdist/test/code/__init__.py index be4530d8..a6e12e06 100644 --- a/lib/cdist/test/code/__init__.py +++ b/lib/cdist/test/code/__init__.py @@ -105,6 +105,20 @@ class ExplorerClassTestCase(unittest.TestCase): destination = os.path.join(self.remote.object_path, self.cdist_object.code_remote_path) self.assertTrue(os.path.isfile(destination)) + def test_run_code_local_environment(self): + self.cdist_object.code_local = self.code.run_gencode_local(self.cdist_object) + output_string = self.code.run_code_local(self.cdist_object) + output_dict = {} + for line in output_string.split('\n'): + if line: + key,value = line.split(': ') + output_dict[key] = value + self.assertEqual(output_dict['__target_host'], self.local.target_host) + self.assertEqual(output_dict['__global'], self.local.out_path) + self.assertEqual(output_dict['__type'], self.cdist_type.absolute_path) + self.assertEqual(output_dict['__object'], self.cdist_object.absolute_path) + self.assertEqual(output_dict['__object_id'], self.cdist_object.object_id) + self.assertEqual(output_dict['__object_fq'], self.cdist_object.path) ''' From e60510228132f426019389659947cfeef020844c Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 15:02:10 +0200 Subject: [PATCH 26/29] implement run_code_local Signed-off-by: Steven Armstrong --- lib/cdist/core/code.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py index c42c360b..22a8ad34 100644 --- a/lib/cdist/core/code.py +++ b/lib/cdist/core/code.py @@ -116,6 +116,10 @@ class Code(object): """Run the gencode-remote script for the given cdist object.""" return self._run_gencode(cdist_object, 'remote') + def run_code_local(self, cdist_object): + script = os.path.join(self.local.object_path, cdist_object.code_local_path) + return self.local.run_script(script) + def transfer_code_remote(self, cdist_object): """Transfer the code_remote script for the given object to the remote side.""" source = os.path.join(self.local.object_path, cdist_object.code_remote_path) From 7bc68476a1d879747ae39c96fda20e05ef024172 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 15:09:05 +0200 Subject: [PATCH 27/29] test for run_code_remote Signed-off-by: Steven Armstrong --- lib/cdist/test/code/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/cdist/test/code/__init__.py b/lib/cdist/test/code/__init__.py index a6e12e06..970d7692 100644 --- a/lib/cdist/test/code/__init__.py +++ b/lib/cdist/test/code/__init__.py @@ -120,6 +120,20 @@ class ExplorerClassTestCase(unittest.TestCase): self.assertEqual(output_dict['__object_id'], self.cdist_object.object_id) self.assertEqual(output_dict['__object_fq'], self.cdist_object.path) + def test_run_code_remote_environment(self): + self.cdist_object.code_remote = self.code.run_gencode_remote(self.cdist_object) + output_string = self.code.run_code_remote(self.cdist_object) + output_dict = {} + for line in output_string.split('\n'): + if line: + key,value = line.split(': ') + output_dict[key] = value + self.assertEqual(output_dict['__target_host'], self.local.target_host) + self.assertEqual(output_dict['__global'], self.local.out_path) + self.assertEqual(output_dict['__type'], self.cdist_type.absolute_path) + self.assertEqual(output_dict['__object'], self.cdist_object.absolute_path) + self.assertEqual(output_dict['__object_id'], self.cdist_object.object_id) + self.assertEqual(output_dict['__object_fq'], self.cdist_object.path) ''' def test_list_type_explorer_names(self): From 1c3902f3db6dc05240c7ef1c84d825e9e7a3822c Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 15:09:47 +0200 Subject: [PATCH 28/29] implement run_code_remote Signed-off-by: Steven Armstrong --- lib/cdist/core/code.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py index 22a8ad34..b2cc033c 100644 --- a/lib/cdist/core/code.py +++ b/lib/cdist/core/code.py @@ -116,13 +116,22 @@ class Code(object): """Run the gencode-remote script for the given cdist object.""" return self._run_gencode(cdist_object, 'remote') - def run_code_local(self, cdist_object): - script = os.path.join(self.local.object_path, cdist_object.code_local_path) - return self.local.run_script(script) - def transfer_code_remote(self, cdist_object): """Transfer the code_remote script for the given object to the remote side.""" source = os.path.join(self.local.object_path, cdist_object.code_remote_path) destination = os.path.join(self.remote.object_path, cdist_object.code_remote_path) self.remote.mkdir(destination) self.remote.transfer(source, destination) + + def _run_code(self, cdist_object, which): + which_exec = getattr(self, which) + script = os.path.join(self.local.object_path, getattr(cdist_object, 'code_%s_path' % which)) + return which_exec.run_script(script) + + def run_code_local(self, cdist_object): + """Run the code-local script for the given cdist object.""" + return self._run_code(cdist_object, 'local') + + def run_code_remote(self, cdist_object): + """Run the code-remote script for the given cdist object on the remote side.""" + return self._run_code(cdist_object, 'remote') From 6c7e280eac188051fb0a6bca0fb33a6d91f492b6 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Thu, 13 Oct 2011 15:11:50 +0200 Subject: [PATCH 29/29] remove obsolete method, merge code Signed-off-by: Steven Armstrong --- lib/cdist/core/code.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/cdist/core/code.py b/lib/cdist/core/code.py index b2cc033c..6dfa2da4 100644 --- a/lib/cdist/core/code.py +++ b/lib/cdist/core/code.py @@ -92,20 +92,17 @@ class Code(object): '__global': self.local.out_path, } - def _get_env_for_object(self, cdist_object): - return { - '__type': cdist_object.type.absolute_path, - '__object': cdist_object.absolute_path, - '__object_id': cdist_object.object_id, - '__object_fq': cdist_object.path, - } - def _run_gencode(self, cdist_object, which): cdist_type = cdist_object.type script = os.path.join(self.local.type_path, getattr(cdist_type, 'gencode_%s_path' % which)) env = os.environ.copy() env.update(self.env) - env.update(self._get_env_for_object(cdist_object)) + env.update({ + '__type': cdist_object.type.absolute_path, + '__object': cdist_object.absolute_path, + '__object_id': cdist_object.object_id, + '__object_fq': cdist_object.path, + }) return self.local.run_script(script, env=env) def run_gencode_local(self, cdist_object):