From 3062421cf59bf2e7bf4a98e42deb7c7588c76c0d Mon Sep 17 00:00:00 2001
From: Darko Poljak <darko.poljak@gmail.com>
Date: Sat, 2 Apr 2016 22:44:02 +0200
Subject: [PATCH 1/2] Fix bug with parallel hosts operation and specified
 output path.

---
 cdist/exec/local.py                           | 31 ++++++++++++------
 .../conf/type/__cdist_test_type/gencode-local |  8 +++++
 .../type/__cdist_test_type/gencode-remote     |  1 +
 cdist/test/exec/local.py                      | 32 ++++++++++++-------
 docs/changelog                                |  1 +
 5 files changed, 52 insertions(+), 21 deletions(-)
 create mode 100755 cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-local
 create mode 120000 cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-remote

diff --git a/cdist/exec/local.py b/cdist/exec/local.py
index 0be803a9..c0554831 100644
--- a/cdist/exec/local.py
+++ b/cdist/exec/local.py
@@ -2,6 +2,7 @@
 #
 # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 # 2011-2015 Nico Schottelius (nico-cdist at schottelius.org)
+# 2016 Darko Poljak (darko.poljak at gmail.com)
 #
 # This file is part of cdist.
 #
@@ -51,9 +52,18 @@ class Local(object):
 
         # FIXME: stopped: create base that does not require moving later
         if base_path:
-            self.base_path = base_path
+            base_path_parent = base_path
         else:
-            self.base_path = tempfile.mkdtemp()
+            base_path_parent = tempfile.mkdtemp()
+            import atexit
+            atexit.register(lambda: shutil.rmtree(base_path_parent))
+        self.hostdir = self._hostdir()
+        self.base_path = os.path.join(base_path_parent, self.hostdir)
+
+        self._init_log()
+        self._init_permissions()
+
+        self.mkdir(self.base_path)
 
         # FIXME: as well
         self._init_cache_dir(None)
@@ -63,8 +73,6 @@ class Local(object):
 
         self._add_conf_dirs = add_conf_dirs
 
-        self._init_log()
-        self._init_permissions()
         self._init_paths()
         self._init_object_marker()
         self._init_conf_dirs()
@@ -80,6 +88,13 @@ class Local(object):
         else:
             return None
 
+    def _hostdir(self):
+        if os.path.isabs(self.target_host):
+            hostdir = self.target_host[1:]
+        else:
+            hostdir = self.target_host
+        return hostdir
+
     def _init_log(self):
         self.log = logging.getLogger(self.target_host)
 
@@ -210,13 +225,9 @@ class Local(object):
 
         return self.run(command=command, env=env, return_output=return_output, message_prefix=message_prefix)
 
-    def save_cache(self):
-        if os.path.isabs(self.target_host):
-            hostdir = self.target_host[1:]
-        else:
-            hostdir = self.target_host
 
-        destination = os.path.join(self.cache_path, hostdir)
+    def save_cache(self):
+        destination = os.path.join(self.cache_path, self.hostdir)
         self.log.debug("Saving " + self.base_path + " to " + destination)
 
         try:
diff --git a/cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-local b/cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-local
new file mode 100755
index 00000000..771894fb
--- /dev/null
+++ b/cdist/test/exec/fixtures/conf/type/__cdist_test_type/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_name: $__object_name"
diff --git a/cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-remote b/cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-remote
new file mode 120000
index 00000000..7b427cac
--- /dev/null
+++ b/cdist/test/exec/fixtures/conf/type/__cdist_test_type/gencode-remote
@@ -0,0 +1 @@
+gencode-local
\ No newline at end of file
diff --git a/cdist/test/exec/local.py b/cdist/test/exec/local.py
index 6cb0c605..6c201e91 100644
--- a/cdist/test/exec/local.py
+++ b/cdist/test/exec/local.py
@@ -2,6 +2,7 @@
 #
 # 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc)
 # 2012 Nico Schottelius (nico-cdist at schottelius.org)
+# 2016 Darko Poljak (darko.poljak at gmail.com)
 #
 # This file is part of cdist.
 #
@@ -35,17 +36,21 @@ my_dir = op.abspath(op.dirname(__file__))
 fixtures = op.join(my_dir, 'fixtures')
 conf_dir = op.join(fixtures, "conf")
 
+bin_true = "/usr/bin/true"
+bin_false = "/usr/bin/false"
+
 class LocalTestCase(test.CdistTestCase):
 
     def setUp(self):
 
         target_host = 'localhost'
         self.temp_dir = self.mkdtemp()
-        self.out_path = self.temp_dir
+        self.out_parent_path = self.temp_dir
+        self.out_path = op.join(self.out_parent_path, target_host)
 
         self.local = local.Local(
             target_host=target_host,
-            out_path=self.out_path,
+            base_path=self.out_parent_path,
             exec_path=test.cdist_exec_path
         )
 
@@ -63,7 +68,7 @@ class LocalTestCase(test.CdistTestCase):
         self.assertEqual(self.local.conf_path, os.path.join(self.out_path, "conf"))
 
     def test_out_path(self):
-        self.assertEqual(self.local.out_path, self.out_path)
+        self.assertEqual(self.local.base_path, self.out_path)
 
     def test_bin_path(self):
         self.assertEqual(self.local.bin_path, os.path.join(self.out_path, "bin"))
@@ -94,7 +99,7 @@ class LocalTestCase(test.CdistTestCase):
 
         link_test_local = local.Local(
             target_host='localhost',
-            out_path=self.out_path,
+            base_path=self.out_parent_path,
             exec_path=test.cdist_exec_path,
         )
 
@@ -111,7 +116,7 @@ class LocalTestCase(test.CdistTestCase):
 
         link_test_local = local.Local(
             target_host='localhost',
-            out_path=self.out_path,
+            base_path=self.out_parent_path,
             exec_path=test.cdist_exec_path,
             add_conf_dirs=[conf_dir]
         )
@@ -131,7 +136,7 @@ class LocalTestCase(test.CdistTestCase):
 
         link_test_local = local.Local(
             target_host='localhost',
-            out_path=self.out_path,
+            base_path=self.out_parent_path,
             exec_path=test.cdist_exec_path,
         )
 
@@ -144,21 +149,21 @@ class LocalTestCase(test.CdistTestCase):
     ### other tests
 
     def test_run_success(self):
-        self.local.run(['/bin/true'])
+        self.local.run([bin_true])
 
     def test_run_fail(self):
-        self.assertRaises(cdist.Error, self.local.run, ['/bin/false'])
+        self.assertRaises(cdist.Error, self.local.run, [bin_false])
 
     def test_run_script_success(self):
         handle, script = self.mkstemp(dir=self.temp_dir)
         with os.fdopen(handle, "w") as fd:
-            fd.writelines(["#!/bin/sh\n", "/bin/true"])
+            fd.writelines(["#!/bin/sh\n", bin_true])
         self.local.run_script(script)
 
     def test_run_script_fail(self):
         handle, script = self.mkstemp(dir=self.temp_dir)
         with os.fdopen(handle, "w") as fd:
-            fd.writelines(["#!/bin/sh\n", "/bin/false"])
+            fd.writelines(["#!/bin/sh\n", bin_false])
         self.assertRaises(cdist.Error, self.local.run_script, script)
 
     def test_run_script_get_output(self):
@@ -180,6 +185,11 @@ class LocalTestCase(test.CdistTestCase):
 
     def test_create_files_dirs(self):
         self.local.create_files_dirs()
-        self.assertTrue(os.path.isdir(self.local.out_path))
+        self.assertTrue(os.path.isdir(self.local.base_path))
         self.assertTrue(os.path.isdir(self.local.bin_path))
         self.assertTrue(os.path.isdir(self.local.conf_path))
+
+if __name__ == "__main__":
+    import unittest
+
+    unittest.main()
diff --git a/docs/changelog b/docs/changelog
index b1acf329..8584eb95 100644
--- a/docs/changelog
+++ b/docs/changelog
@@ -2,6 +2,7 @@ Changelog
 ---------
 
 next:
+	* Core: Fix bug with parallel hosts operation when output path is specifed (Darko Poljak)
 	* Core: Add CDIST_REMOTE_COPY/EXEC env variables and multiplexing options for default scp/ssh (Darko Poljak)
 	* Types: Remove bashisms in scripts (Darko Poljak)
 	* Core: Fix bug in remote command with environment (Darko Poljak)

From e4cbb382abafd3891faef17c98bc9ed9259a5b28 Mon Sep 17 00:00:00 2001
From: Darko Poljak <darko.poljak@gmail.com>
Date: Tue, 5 Apr 2016 20:23:13 +0200
Subject: [PATCH 2/2] PATH resolution for true/false.

---
 cdist/test/exec/local.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cdist/test/exec/local.py b/cdist/test/exec/local.py
index 6c201e91..12a0d47b 100644
--- a/cdist/test/exec/local.py
+++ b/cdist/test/exec/local.py
@@ -36,8 +36,8 @@ my_dir = op.abspath(op.dirname(__file__))
 fixtures = op.join(my_dir, 'fixtures')
 conf_dir = op.join(fixtures, "conf")
 
-bin_true = "/usr/bin/true"
-bin_false = "/usr/bin/false"
+bin_true = "true"
+bin_false = "false"
 
 class LocalTestCase(test.CdistTestCase):