new feature: capture and forward stdin to types
Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
This commit is contained in:
		
					parent
					
						
							
								f087057c98
							
						
					
				
			
			
				commit
				
					
						06649d3478
					
				
			
		
					 6 changed files with 80 additions and 2 deletions
				
			
		| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
					# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
 | 
					# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# This file is part of cdist.
 | 
					# This file is part of cdist.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -22,6 +23,7 @@
 | 
				
			||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cdist
 | 
					import cdist
 | 
				
			||||||
from cdist import core
 | 
					from cdist import core
 | 
				
			||||||
| 
						 | 
					@ -67,6 +69,7 @@ class Emulator(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.commandline()
 | 
					        self.commandline()
 | 
				
			||||||
        self.setup_object()
 | 
					        self.setup_object()
 | 
				
			||||||
 | 
					        self.save_stdin()
 | 
				
			||||||
        self.record_requirements()
 | 
					        self.record_requirements()
 | 
				
			||||||
        self.record_auto_requirements()
 | 
					        self.record_auto_requirements()
 | 
				
			||||||
        self.log.debug("Finished %s %s" % (self.cdist_object.path, self.parameters))
 | 
					        self.log.debug("Finished %s %s" % (self.cdist_object.path, self.parameters))
 | 
				
			||||||
| 
						 | 
					@ -137,6 +140,27 @@ class Emulator(object):
 | 
				
			||||||
        # Record / Append source
 | 
					        # Record / Append source
 | 
				
			||||||
        self.cdist_object.source.append(self.object_source)
 | 
					        self.cdist_object.source.append(self.object_source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    chunk_size = 8192
 | 
				
			||||||
 | 
					    def _read_stdin(self):
 | 
				
			||||||
 | 
					        return sys.stdin.buffer.read(self.chunk_size)
 | 
				
			||||||
 | 
					    def save_stdin(self):
 | 
				
			||||||
 | 
					        """If something is written to stdin, save it in the object as
 | 
				
			||||||
 | 
					        $__object/stdin so it can be accessed in manifest and gencode-*
 | 
				
			||||||
 | 
					        scripts.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if not sys.stdin.isatty():
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                # go directly to file instead of using CdistObject's api
 | 
				
			||||||
 | 
					                # as that does not support streaming
 | 
				
			||||||
 | 
					                path = os.path.join(self.cdist_object.absolute_path, 'stdin')
 | 
				
			||||||
 | 
					                with open(path, 'wb') as fd:
 | 
				
			||||||
 | 
					                    chunk = self._read_stdin()
 | 
				
			||||||
 | 
					                    while chunk:
 | 
				
			||||||
 | 
					                        fd.write(chunk)
 | 
				
			||||||
 | 
					                        chunk = self._read_stdin()
 | 
				
			||||||
 | 
					            except EnvironmentError as e:
 | 
				
			||||||
 | 
					                raise cdist.Error('Failed to read from stdin: %s' % e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def record_requirements(self):
 | 
					    def record_requirements(self):
 | 
				
			||||||
        """record requirements"""
 | 
					        """record requirements"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,12 +21,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
 | 
					import string
 | 
				
			||||||
 | 
					import filecmp
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cdist
 | 
					import cdist
 | 
				
			||||||
from cdist import test
 | 
					from cdist import test
 | 
				
			||||||
from cdist.exec import local
 | 
					from cdist.exec import local
 | 
				
			||||||
from cdist import emulator
 | 
					from cdist import emulator
 | 
				
			||||||
from cdist import core
 | 
					from cdist import core
 | 
				
			||||||
 | 
					from cdist import config
 | 
				
			||||||
 | 
					import cdist.context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local_base_path = test.cdist_base_path
 | 
					local_base_path = test.cdist_base_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,8 +119,7 @@ class AutoRequireEmulatorTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.manifest = core.Manifest(self.target_host, self.local)
 | 
					        self.manifest = core.Manifest(self.target_host, self.local)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tearDown(self):
 | 
					    def tearDown(self):
 | 
				
			||||||
        pass
 | 
					        shutil.rmtree(self.temp_dir)
 | 
				
			||||||
        #shutil.rmtree(self.temp_dir)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_autorequire(self):
 | 
					    def test_autorequire(self):
 | 
				
			||||||
        initial_manifest = os.path.join(self.local.manifest_path, "init")
 | 
					        initial_manifest = os.path.join(self.local.manifest_path, "init")
 | 
				
			||||||
| 
						 | 
					@ -216,3 +220,47 @@ class ArgumentsTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.assertTrue('optional1' in cdist_object.parameters)
 | 
					        self.assertTrue('optional1' in cdist_object.parameters)
 | 
				
			||||||
        self.assertFalse('optional2' in cdist_object.parameters)
 | 
					        self.assertFalse('optional2' in cdist_object.parameters)
 | 
				
			||||||
        self.assertEqual(cdist_object.parameters['optional1'], value)
 | 
					        self.assertEqual(cdist_object.parameters['optional1'], value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StdinTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self.orig_environ = os.environ
 | 
				
			||||||
 | 
					        os.environ = os.environ.copy()
 | 
				
			||||||
 | 
					        self.target_host = 'localhost'
 | 
				
			||||||
 | 
					        self.temp_dir = self.mkdtemp()
 | 
				
			||||||
 | 
					        os.environ['__cdist_out_dir'] = self.temp_dir
 | 
				
			||||||
 | 
					        local_base_path = fixtures
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.context = cdist.context.Context(
 | 
				
			||||||
 | 
					            target_host=self.target_host,
 | 
				
			||||||
 | 
					            remote_copy='scp -o User=root -q',
 | 
				
			||||||
 | 
					            remote_exec='ssh -o User=root -q',
 | 
				
			||||||
 | 
					            base_path=local_base_path,
 | 
				
			||||||
 | 
					            exec_path=test.cdist_exec_path,
 | 
				
			||||||
 | 
					            debug=False)
 | 
				
			||||||
 | 
					        self.config = config.Config(self.context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def tearDown(self):
 | 
				
			||||||
 | 
					        os.environ = self.orig_environ
 | 
				
			||||||
 | 
					        shutil.rmtree(self.temp_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_file_from_stdin(self):
 | 
				
			||||||
 | 
					        handle, destination = self.mkstemp(dir=self.temp_dir)
 | 
				
			||||||
 | 
					        os.close(handle)
 | 
				
			||||||
 | 
					        source_handle, source = self.mkstemp(dir=self.temp_dir)
 | 
				
			||||||
 | 
					        candidates = string.ascii_letters+string.digits
 | 
				
			||||||
 | 
					        with os.fdopen(source_handle, 'w') as fd:
 | 
				
			||||||
 | 
					            for x in range(100):
 | 
				
			||||||
 | 
					                fd.write(''.join(random.sample(candidates, len(candidates))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        handle, initial_manifest = self.mkstemp(dir=self.temp_dir)
 | 
				
			||||||
 | 
					        with os.fdopen(handle, 'w') as fd:
 | 
				
			||||||
 | 
					            fd.write('__file_from_stdin %s --source %s\n' % (destination, source))
 | 
				
			||||||
 | 
					        self.context.initial_manifest = initial_manifest
 | 
				
			||||||
 | 
					        self.config.stage_prepare()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cdist_type = core.CdistType(self.config.local.type_path, '__file')
 | 
				
			||||||
 | 
					        cdist_object = core.CdistObject(cdist_type, self.config.local.object_path, destination)
 | 
				
			||||||
 | 
					        # Test weither stdin has been stored correctly
 | 
				
			||||||
 | 
					        self.assertTrue(filecmp.cmp(source, os.path.join(cdist_object.absolute_path, 'stdin')))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										0
									
								
								lib/cdist/test/emulator/fixtures/conf/explorer/.keep
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								lib/cdist/test/emulator/fixtures/conf/explorer/.keep
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								lib/cdist/test/emulator/fixtures/conf/type/__file
									
										
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								lib/cdist/test/emulator/fixtures/conf/type/__file
									
										
									
									
									
										Symbolic link
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					../../../../../../../conf/type/__file
 | 
				
			||||||
							
								
								
									
										4
									
								
								lib/cdist/test/emulator/fixtures/conf/type/__file_from_stdin/manifest
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								lib/cdist/test/emulator/fixtures/conf/type/__file_from_stdin/manifest
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source="$(cat "$__object/parameter/source")"
 | 
				
			||||||
 | 
					cat "$source" | __file "/$__object_id" --source /dev/null
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					source
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue