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…
Reference in a new issue