new feature: capture and forward stdin to types

Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
This commit is contained in:
Steven Armstrong 2012-06-04 14:11:34 +02:00
parent f087057c98
commit 06649d3478
6 changed files with 80 additions and 2 deletions

View file

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
@ -22,6 +23,7 @@
import argparse
import logging
import os
import sys
import cdist
from cdist import core
@ -67,6 +69,7 @@ class Emulator(object):
self.commandline()
self.setup_object()
self.save_stdin()
self.record_requirements()
self.record_auto_requirements()
self.log.debug("Finished %s %s" % (self.cdist_object.path, self.parameters))
@ -137,6 +140,27 @@ class Emulator(object):
# Record / Append 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):
"""record requirements"""

View file

@ -21,12 +21,17 @@
import os
import shutil
import string
import filecmp
import random
import cdist
from cdist import test
from cdist.exec import local
from cdist import emulator
from cdist import core
from cdist import config
import cdist.context
local_base_path = test.cdist_base_path
@ -114,8 +119,7 @@ class AutoRequireEmulatorTestCase(test.CdistTestCase):
self.manifest = core.Manifest(self.target_host, self.local)
def tearDown(self):
pass
#shutil.rmtree(self.temp_dir)
shutil.rmtree(self.temp_dir)
def test_autorequire(self):
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.assertFalse('optional2' in cdist_object.parameters)
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')))

View file

@ -0,0 +1 @@
../../../../../../../conf/type/__file

View file

@ -0,0 +1,4 @@
#!/bin/sh
source="$(cat "$__object/parameter/source")"
cat "$source" | __file "/$__object_id" --source /dev/null