Merge branch 'feature_type_stdin' of https://github.com/asteven/cdist

This commit is contained in:
Nico Schottelius 2012-06-04 15:48:25 +02:00
commit 3c1ab59b17
8 changed files with 90 additions and 2 deletions

View file

@ -30,6 +30,9 @@ exists="$(cat "$__object/explorer/exists")"
if [ "$state_should" = "present" ]; then if [ "$state_should" = "present" ]; then
if [ -f "$__object/parameter/source" ]; then if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")" source="$(cat "$__object/parameter/source")"
if [ "$source" = "-" ]; then
source="$__object/stdin"
fi
if [ -f "$source" ]; then if [ -f "$source" ]; then
local_cksum="$(cksum < "$source")" local_cksum="$(cksum < "$source")"

View file

@ -39,6 +39,7 @@ owner::
source:: source::
If supplied, copy this file from the host running cdist to the target. If supplied, copy this file from the host running cdist to the target.
If not supplied, an empty file or directory will be created. If not supplied, an empty file or directory will be created.
If source is '-' (dash), take what was written to stdin as the file content.
EXAMPLES EXAMPLES
@ -64,6 +65,12 @@ __file /etc/shadow --source "$__type/files/shadow" \
__file /home/frodo/.bashrc --source "/etc/skel/.bashrc" \ __file /home/frodo/.bashrc --source "/etc/skel/.bashrc" \
--state exists \ --state exists \
--owner frodo --mode 0600 --owner frodo --mode 0600
# Take file content from stdin
__file /tmp/whatever --owner root --group root --mode 644 --source - << DONE
Here goes the content for /tmp/whatever
DONE
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -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"""

View file

@ -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')))

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