forked from ungleich-public/cdist
Merge remote-tracking branch 'telmich/master'
This commit is contained in:
commit
b142435abd
13 changed files with 250 additions and 94 deletions
43
README
43
README
|
@ -15,7 +15,7 @@
|
||||||
"P' "" ""
|
"P' "" ""
|
||||||
|
|
||||||
|
|
||||||
[[!toc levels=2]]
|
[[!toc levels=3]]
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
@ -86,13 +86,46 @@ cdist was tested or is know to run on at least
|
||||||
* SSH-Server
|
* SSH-Server
|
||||||
|
|
||||||
|
|
||||||
## Getting cdist
|
## Installation
|
||||||
|
|
||||||
|
### Preperation
|
||||||
|
|
||||||
|
Ensure you have Python 3.x and the **argparse** module installed on
|
||||||
|
the machine you use to **deploy to the targets**.
|
||||||
|
|
||||||
|
#### Archlinux
|
||||||
|
|
||||||
|
Archlinux already has python >= 3.2, so you only need to do:
|
||||||
|
|
||||||
|
pacman -S python
|
||||||
|
|
||||||
|
#### Debian
|
||||||
|
|
||||||
|
aptitude install python3 python3-setuptools
|
||||||
|
easy_install3 argparse
|
||||||
|
|
||||||
|
|
||||||
|
#### Gentoo
|
||||||
|
|
||||||
|
Gentoo only provides python 3.2 in testing packages (http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=3&chap=3).
|
||||||
|
If you want to ensure nothing breaks you must set back the python version to what was default before.
|
||||||
|
|
||||||
|
emerge -av =python-3.2.2 --autounmask-write
|
||||||
|
emerge -av =python-3.2.2
|
||||||
|
eselect python list
|
||||||
|
eselect python list set python3.2
|
||||||
|
|
||||||
|
#### Max OS X
|
||||||
|
|
||||||
|
Ensure you have port installed and configured (http://www.macports.org/install.php).
|
||||||
|
|
||||||
|
port install python32
|
||||||
|
ln -s /opt/local/bin/python3.2 /opt/local/bin/python3
|
||||||
|
|
||||||
|
### Get cdist
|
||||||
|
|
||||||
You can clone cdist from git, which gives you the advantage of having
|
You can clone cdist from git, which gives you the advantage of having
|
||||||
a version control in place for development of your own stuff as well.
|
a version control in place for development of your own stuff as well.
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
To install cdist, execute the following commands:
|
To install cdist, execute the following commands:
|
||||||
|
|
||||||
git clone git://git.schottelius.org/cdist
|
git clone git://git.schottelius.org/cdist
|
||||||
|
|
30
bin/cdist
30
bin/cdist
|
@ -26,7 +26,7 @@ import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger("cdist")
|
||||||
|
|
||||||
# Ensure our /lib/ is included into PYTHON_PATH
|
# Ensure our /lib/ is included into PYTHON_PATH
|
||||||
sys.path.insert(0, os.path.abspath(
|
sys.path.insert(0, os.path.abspath(
|
||||||
|
@ -39,12 +39,17 @@ def commandline():
|
||||||
# Construct parser others can reuse
|
# Construct parser others can reuse
|
||||||
parser = {}
|
parser = {}
|
||||||
# Options _all_ parsers have in common
|
# Options _all_ parsers have in common
|
||||||
parser['most'] = argparse.ArgumentParser(add_help=False)
|
parser['loglevel'] = argparse.ArgumentParser(add_help=False)
|
||||||
parser['most'].add_argument('-d', '--debug',
|
parser['loglevel'].add_argument('-d', '--debug',
|
||||||
help='Set log level to debug', action='store_true')
|
help='Set log level to debug', action='store_true',
|
||||||
|
default=False)
|
||||||
|
parser['loglevel'].add_argument('-v', '--verbose',
|
||||||
|
help='Set log level to info, be more verbose',
|
||||||
|
action='store_true', default=False)
|
||||||
|
|
||||||
# Main subcommand parser
|
# Main subcommand parser
|
||||||
parser['main'] = argparse.ArgumentParser(description='cdist ' + cdist.VERSION)
|
parser['main'] = argparse.ArgumentParser(description='cdist ' + cdist.VERSION,
|
||||||
|
parents=[parser['loglevel']])
|
||||||
parser['main'].add_argument('-V', '--version',
|
parser['main'].add_argument('-V', '--version',
|
||||||
help='Show version', action='version',
|
help='Show version', action='version',
|
||||||
version='%(prog)s ' + cdist.VERSION)
|
version='%(prog)s ' + cdist.VERSION)
|
||||||
|
@ -52,7 +57,7 @@ def commandline():
|
||||||
|
|
||||||
# Banner
|
# Banner
|
||||||
parser['banner'] = parser['sub'].add_parser('banner',
|
parser['banner'] = parser['sub'].add_parser('banner',
|
||||||
add_help=False)
|
parents=[parser['loglevel']])
|
||||||
parser['banner'].set_defaults(func=cdist.banner.banner)
|
parser['banner'].set_defaults(func=cdist.banner.banner)
|
||||||
|
|
||||||
# Config and install (common stuff)
|
# Config and install (common stuff)
|
||||||
|
@ -74,12 +79,12 @@ def commandline():
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
parser['config'] = parser['sub'].add_parser('config',
|
parser['config'] = parser['sub'].add_parser('config',
|
||||||
parents=[parser['most'], parser['configinstall']])
|
parents=[parser['loglevel'], parser['configinstall']])
|
||||||
parser['config'].set_defaults(func=cdist.config.config)
|
parser['config'].set_defaults(func=cdist.config.config)
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
parser['install'] = parser['sub'].add_parser('install',
|
parser['install'] = parser['sub'].add_parser('install',
|
||||||
parents=[parser['most'], parser['configinstall']])
|
parents=[parser['loglevel'], parser['configinstall']])
|
||||||
parser['install'].set_defaults(func=cdist.install.install)
|
parser['install'].set_defaults(func=cdist.install.install)
|
||||||
|
|
||||||
for p in parser:
|
for p in parser:
|
||||||
|
@ -87,17 +92,18 @@ def commandline():
|
||||||
|
|
||||||
args = parser['main'].parse_args(sys.argv[1:])
|
args = parser['main'].parse_args(sys.argv[1:])
|
||||||
|
|
||||||
# Most subcommands have --debug, so handle it here
|
# Loglevels are handled globally in here and debug wins over verbose
|
||||||
if 'debug' in args:
|
if args.verbose:
|
||||||
|
logging.root.setLevel(logging.INFO)
|
||||||
if args.debug:
|
if args.debug:
|
||||||
logging.root.setLevel(logging.DEBUG)
|
logging.root.setLevel(logging.DEBUG)
|
||||||
log.debug(args)
|
|
||||||
|
|
||||||
|
log.debug(args)
|
||||||
args.func(args)
|
args.func(args)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
|
logging.basicConfig(format='%(levelname)s: %(message)s')
|
||||||
|
|
||||||
if re.match(TYPE_PREFIX, os.path.basename(sys.argv[0])):
|
if re.match(TYPE_PREFIX, os.path.basename(sys.argv[0])):
|
||||||
import cdist.emulator
|
import cdist.emulator
|
||||||
|
|
8
build.sh
8
build.sh
|
@ -126,6 +126,14 @@ case "$1" in
|
||||||
| xargs rm -f
|
| xargs rm -f
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
test)
|
||||||
|
python3 -m unittest discover test 'test_*.py'
|
||||||
|
;;
|
||||||
|
|
||||||
|
test-all)
|
||||||
|
python3 -m unittest discover test '*.py'
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo ''
|
echo ''
|
||||||
echo 'Welcome to cdist!'
|
echo 'Welcome to cdist!'
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
2.0.2:
|
2.0.3:
|
||||||
|
* Improved logging, added --verbose, by more quiet by default
|
||||||
|
|
||||||
|
2.0.2: 2011-09-27
|
||||||
* Add support for detection of OpenWall Linux (Matthias Teege)
|
* Add support for detection of OpenWall Linux (Matthias Teege)
|
||||||
|
* Add support for __debug variable in manifests
|
||||||
|
* Bugfix core: Various issues with type emulator
|
||||||
|
|
||||||
2.0.1: 2011-09-23
|
2.0.1: 2011-09-23
|
||||||
* Bugfix core: Always print source of error in case of exec errors
|
* Bugfix core: Always print source of error in case of exec errors
|
||||||
|
|
|
@ -34,6 +34,8 @@ USER INTERFACE
|
||||||
-> given after manifest run already!
|
-> given after manifest run already!
|
||||||
|
|
||||||
- use absent/present for state by default?
|
- use absent/present for state by default?
|
||||||
|
- buggy output with packages that don't exist in archlinux and fedora:
|
||||||
|
python3 vs. python
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
------
|
------
|
||||||
|
|
|
@ -311,15 +311,13 @@ eof
|
||||||
via __global/
|
via __global/
|
||||||
|
|
||||||
- Support parallel execution
|
- Support parallel execution
|
||||||
- and maximum number of parallel runs (-p X)
|
|
||||||
- error handling / report failed hosts
|
- error handling / report failed hosts
|
||||||
|
|
||||||
- Allow manifest to be read from stdin
|
|
||||||
- Create new video for cdist 2.0.0
|
- Create new video for cdist 2.0.0
|
||||||
http://www.youtube.com/watch?v=PRMjzy48eTI
|
http://www.youtube.com/watch?v=PRMjzy48eTI
|
||||||
|
|
||||||
- Setup __debug, if -d is given, so other tools can reuse it
|
- Setup __debug, if -d is given, so other tools can reuse it
|
||||||
(-> non core feature!
|
- implement everywhere to external!
|
||||||
|
|
||||||
- remote_prefix:
|
- remote_prefix:
|
||||||
scp vs. ssh issue
|
scp vs. ssh issue
|
||||||
|
|
|
@ -166,6 +166,11 @@ changed::
|
||||||
|
|
||||||
ENVIRONMENT VARIABLES
|
ENVIRONMENT VARIABLES
|
||||||
---------------------
|
---------------------
|
||||||
|
__debug::
|
||||||
|
If this variable is setup, cdist runs in debug mode.
|
||||||
|
You can use this information, to only output stuff in debug
|
||||||
|
mode as well.
|
||||||
|
Available for: initial manifest, type manifest
|
||||||
__explorer::
|
__explorer::
|
||||||
Directory that contains all global explorers.
|
Directory that contains all global explorers.
|
||||||
Available for: explorer
|
Available for: explorer
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
VERSION = "2.0.2"
|
VERSION = "2.0.3"
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
"""Base exception class for this project"""
|
"""Base exception class for this project"""
|
||||||
|
|
|
@ -65,6 +65,7 @@ class Config:
|
||||||
|
|
||||||
def run_global_explores(self):
|
def run_global_explores(self):
|
||||||
"""Run global explorers"""
|
"""Run global explorers"""
|
||||||
|
log.info("Running global explorers")
|
||||||
explorers = self.path.list_global_explorers()
|
explorers = self.path.list_global_explorers()
|
||||||
if(len(explorers) == 0):
|
if(len(explorers) == 0):
|
||||||
raise CdistError("No explorers found in", self.path.global_explorer_dir)
|
raise CdistError("No explorers found in", self.path.global_explorer_dir)
|
||||||
|
@ -107,18 +108,22 @@ class Config:
|
||||||
cdist.exec.run_or_fail(remote_cmd, stdout=output_fd, remote_prefix=self.remote_prefix)
|
cdist.exec.run_or_fail(remote_cmd, stdout=output_fd, remote_prefix=self.remote_prefix)
|
||||||
output_fd.close()
|
output_fd.close()
|
||||||
|
|
||||||
|
def link_emulator(self):
|
||||||
|
"""Link emulator to types"""
|
||||||
|
cdist.emulator.link(self.exec_path,
|
||||||
|
self.path.bin_dir, self.path.list_types())
|
||||||
|
|
||||||
def init_deploy(self):
|
def init_deploy(self):
|
||||||
"""Ensure the base directories are cleaned up"""
|
"""Ensure the base directories are cleaned up"""
|
||||||
log.debug("Creating clean directory structure")
|
log.debug("Creating clean directory structure")
|
||||||
|
|
||||||
self.path.remove_remote_dir(cdist.path.REMOTE_BASE_DIR)
|
self.path.remove_remote_dir(cdist.path.REMOTE_BASE_DIR)
|
||||||
self.path.remote_mkdir(cdist.path.REMOTE_BASE_DIR)
|
self.path.remote_mkdir(cdist.path.REMOTE_BASE_DIR)
|
||||||
|
self.link_emulator()
|
||||||
cdist.emulator.link(self.exec_path,
|
|
||||||
self.path.bin_dir, self.path.list_types())
|
|
||||||
|
|
||||||
def run_initial_manifest(self):
|
def run_initial_manifest(self):
|
||||||
"""Run the initial manifest"""
|
"""Run the initial manifest"""
|
||||||
|
log.info("Running initial manifest %s", self.path.initial_manifest)
|
||||||
env = { "__manifest" : self.path.manifest_dir }
|
env = { "__manifest" : self.path.manifest_dir }
|
||||||
self.run_manifest(self.path.initial_manifest, extra_env=env)
|
self.run_manifest(self.path.initial_manifest, extra_env=env)
|
||||||
|
|
||||||
|
@ -146,6 +151,10 @@ class Config:
|
||||||
env['__target_host'] = self.target_host
|
env['__target_host'] = self.target_host
|
||||||
env['__global'] = self.path.out_dir
|
env['__global'] = self.path.out_dir
|
||||||
|
|
||||||
|
# Submit debug flag to manifest, can be used by emulator and types
|
||||||
|
if self.debug:
|
||||||
|
env['__debug'] = "yes"
|
||||||
|
|
||||||
# Required for recording source
|
# Required for recording source
|
||||||
env['__cdist_manifest'] = manifest
|
env['__cdist_manifest'] = manifest
|
||||||
|
|
||||||
|
@ -235,12 +244,13 @@ class Config:
|
||||||
self.run_global_explores()
|
self.run_global_explores()
|
||||||
self.run_initial_manifest()
|
self.run_initial_manifest()
|
||||||
|
|
||||||
|
log.info("Running object manifests and type explorers")
|
||||||
|
|
||||||
old_objects = []
|
old_objects = []
|
||||||
objects = self.path.list_objects()
|
objects = self.path.list_objects()
|
||||||
|
|
||||||
# Continue process until no new objects are created anymore
|
# Continue process until no new objects are created anymore
|
||||||
while old_objects != objects:
|
while old_objects != objects:
|
||||||
log.debug("Prepare stage")
|
|
||||||
old_objects = list(objects)
|
old_objects = list(objects)
|
||||||
for cdist_object in objects:
|
for cdist_object in objects:
|
||||||
if cdist_object in self.objects_prepared:
|
if cdist_object in self.objects_prepared:
|
||||||
|
@ -255,7 +265,7 @@ class Config:
|
||||||
|
|
||||||
def stage_run(self):
|
def stage_run(self):
|
||||||
"""The final (and real) step of deployment"""
|
"""The final (and real) step of deployment"""
|
||||||
log.debug("Actual run objects")
|
log.info("Generating and executing code")
|
||||||
# Now do the final steps over the existing objects
|
# Now do the final steps over the existing objects
|
||||||
for cdist_object in self.path.list_objects():
|
for cdist_object in self.path.list_objects():
|
||||||
log.debug("Run object: %s", cdist_object)
|
log.debug("Run object: %s", cdist_object)
|
||||||
|
@ -298,7 +308,7 @@ def config(args):
|
||||||
|
|
||||||
if args.parallel:
|
if args.parallel:
|
||||||
for p in process.keys():
|
for p in process.keys():
|
||||||
log.debug("Joining %s", p)
|
log.debug("Joining process %s", p)
|
||||||
process[p].join()
|
process[p].join()
|
||||||
|
|
||||||
time_end = datetime.datetime.now()
|
time_end = datetime.datetime.now()
|
||||||
|
|
|
@ -36,20 +36,21 @@ def run(argv):
|
||||||
global_dir = os.environ['__global']
|
global_dir = os.environ['__global']
|
||||||
object_source = os.environ['__cdist_manifest']
|
object_source = os.environ['__cdist_manifest']
|
||||||
|
|
||||||
|
if '__debug' in os.environ:
|
||||||
|
logging.root.setLevel(logging.DEBUG)
|
||||||
|
else:
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(add_help=False)
|
parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
|
||||||
# Setup optional parameters
|
|
||||||
for parameter in cdist.path.file_to_list(os.path.join(param_dir, "optional")):
|
for parameter in cdist.path.file_to_list(os.path.join(param_dir, "optional")):
|
||||||
argument = "--" + parameter
|
argument = "--" + parameter
|
||||||
parser.add_argument(argument, action='store', required=False)
|
parser.add_argument(argument, action='store', required=False)
|
||||||
|
|
||||||
# Setup required parameters
|
|
||||||
for parameter in cdist.path.file_to_list(os.path.join(param_dir, "required")):
|
for parameter in cdist.path.file_to_list(os.path.join(param_dir, "required")):
|
||||||
argument = "--" + parameter
|
argument = "--" + parameter
|
||||||
parser.add_argument(argument, action='store', required=True)
|
parser.add_argument(argument, action='store', required=True)
|
||||||
|
|
||||||
# Setup positional parameter, if not singleton
|
# If not singleton support one positional parameter
|
||||||
|
|
||||||
if not os.path.isfile(os.path.join(type_dir, "singleton")):
|
if not os.path.isfile(os.path.join(type_dir, "singleton")):
|
||||||
parser.add_argument("object_id", nargs=1)
|
parser.add_argument("object_id", nargs=1)
|
||||||
|
|
||||||
|
@ -67,6 +68,10 @@ def run(argv):
|
||||||
if object_id[0] == '/':
|
if object_id[0] == '/':
|
||||||
object_id = object_id[1:]
|
object_id = object_id[1:]
|
||||||
|
|
||||||
|
# Prefix output by object_self
|
||||||
|
logformat = '%(levelname)s: ' + type + '/' + object_id + ': %(message)s'
|
||||||
|
logging.basicConfig(format=logformat)
|
||||||
|
|
||||||
# FIXME: verify object id
|
# FIXME: verify object id
|
||||||
log.debug(args)
|
log.debug(args)
|
||||||
|
|
||||||
|
@ -110,12 +115,12 @@ def run(argv):
|
||||||
value_old = param_fd.readlines()
|
value_old = param_fd.readlines()
|
||||||
param_fd.close()
|
param_fd.close()
|
||||||
|
|
||||||
if(value_old != value):
|
if(value_old[0] != value):
|
||||||
raise cdist.Error("Parameter + \"" + param +
|
raise cdist.Error("Parameter\"" + param +
|
||||||
"\" differs: " + " ".join(value_old) + " vs. " +
|
"\" differs: " + " ".join(value_old) + " vs. " +
|
||||||
value +
|
value +
|
||||||
"\nSource = " + " ".join(old_object_source)
|
"\nSource = " + " ".join(old_object_source)
|
||||||
+ " new =" + object_source)
|
+ " new = " + object_source)
|
||||||
else:
|
else:
|
||||||
param_fd = open(file, "w")
|
param_fd = open(file, "w")
|
||||||
param_fd.writelines(value)
|
param_fd.writelines(value)
|
||||||
|
@ -124,7 +129,7 @@ def run(argv):
|
||||||
# Record requirements
|
# Record requirements
|
||||||
if "__require" in os.environ:
|
if "__require" in os.environ:
|
||||||
requirements = os.environ['__require']
|
requirements = os.environ['__require']
|
||||||
print(object_id + ":Writing requirements: " + requirements)
|
log.debug(object_id + ":Writing requirements: " + requirements)
|
||||||
require_fd = open(os.path.join(object_dir, "require"), "a")
|
require_fd = open(os.path.join(object_dir, "require"), "a")
|
||||||
require_fd.writelines(requirements.split(" "))
|
require_fd.writelines(requirements.split(" "))
|
||||||
require_fd.close()
|
require_fd.close()
|
||||||
|
@ -134,7 +139,7 @@ def run(argv):
|
||||||
source_fd.writelines(object_source)
|
source_fd.writelines(object_source)
|
||||||
source_fd.close()
|
source_fd.close()
|
||||||
|
|
||||||
print("Finished " + type + "/" + object_id + repr(params))
|
log.debug("Finished " + type + "/" + object_id + repr(params))
|
||||||
|
|
||||||
|
|
||||||
def link(exec_path, bin_dir, type_list):
|
def link(exec_path, bin_dir, type_list):
|
||||||
|
|
45
test/nico_ui.py
Executable file
45
test/nico_ui.py
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
|
||||||
|
#
|
||||||
|
# This file is part of cdist.
|
||||||
|
#
|
||||||
|
# cdist is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# cdist is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
cdist_commands=["banner", "config", "install"]
|
||||||
|
|
||||||
|
cdist_exec_path = os.path.abspath(
|
||||||
|
os.path.join(os.path.dirname(os.path.realpath(__file__)), "../bin/cdist"))
|
||||||
|
|
||||||
|
class UI(unittest.TestCase):
|
||||||
|
def test_banner(self):
|
||||||
|
self.assertEqual(subprocess.call([cdist_exec_path, "banner"]), 0)
|
||||||
|
|
||||||
|
def test_help(self):
|
||||||
|
for cmd in cdist_commands:
|
||||||
|
self.assertEqual(subprocess.call([cdist_exec_path, cmd, "-h"]), 0)
|
||||||
|
|
||||||
|
# FIXME: mockup needed
|
||||||
|
def test_config_localhost(self):
|
||||||
|
for cmd in cdist_commands:
|
||||||
|
self.assertEqual(subprocess.call([cdist_exec_path, "config", "localhost"]), 0)
|
||||||
|
|
67
test.py → test/test_config.py
Executable file → Normal file
67
test.py → test/test_config.py
Executable file → Normal file
|
@ -20,68 +20,19 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
sys.path.insert(0, os.path.abspath(
|
sys.path.insert(0, os.path.abspath(
|
||||||
os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib')))
|
os.path.join(os.path.dirname(os.path.realpath(__file__)), '../lib')))
|
||||||
|
|
||||||
|
import cdist.config
|
||||||
|
|
||||||
cdist_exec_path = os.path.abspath(
|
cdist_exec_path = os.path.abspath(
|
||||||
os.path.join(os.path.dirname(os.path.realpath(__file__)), "bin/cdist"))
|
os.path.join(os.path.dirname(os.path.realpath(__file__)), "bin/cdist"))
|
||||||
|
|
||||||
import cdist
|
|
||||||
import cdist.config
|
|
||||||
import cdist.exec
|
|
||||||
|
|
||||||
class Exec(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
"""Create shell code and co."""
|
|
||||||
|
|
||||||
self.temp_dir = tempfile.mkdtemp()
|
|
||||||
self.shell_false = os.path.join(self.temp_dir, "shell_false")
|
|
||||||
self.shell_true = os.path.join(self.temp_dir, "shell_true")
|
|
||||||
|
|
||||||
true_fd = open(self.shell_true, "w")
|
|
||||||
true_fd.writelines(["#!/bin/sh\n", "/bin/true"])
|
|
||||||
true_fd.close()
|
|
||||||
|
|
||||||
false_fd = open(self.shell_false, "w")
|
|
||||||
false_fd.writelines(["#!/bin/sh\n", "/bin/false"])
|
|
||||||
false_fd.close()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
shutil.rmtree(self.temp_dir)
|
|
||||||
|
|
||||||
def test_local_success_shell(self):
|
|
||||||
try:
|
|
||||||
cdist.exec.shell_run_or_debug_fail(self.shell_true, [self.shell_true])
|
|
||||||
except cdist.Error:
|
|
||||||
failed = True
|
|
||||||
else:
|
|
||||||
failed = False
|
|
||||||
|
|
||||||
self.assertFalse(failed)
|
|
||||||
|
|
||||||
def test_local_fail_shell(self):
|
|
||||||
self.assertRaises(cdist.Error, cdist.exec.shell_run_or_debug_fail,
|
|
||||||
self.shell_false, [self.shell_false])
|
|
||||||
|
|
||||||
def test_local_success(self):
|
|
||||||
try:
|
|
||||||
cdist.exec.run_or_fail(["/bin/true"])
|
|
||||||
except cdist.Error:
|
|
||||||
failed = True
|
|
||||||
else:
|
|
||||||
failed = False
|
|
||||||
|
|
||||||
self.assertFalse(failed)
|
|
||||||
|
|
||||||
def test_local_fail(self):
|
|
||||||
self.assertRaises(cdist.Error, cdist.exec.run_or_fail, ["/bin/false"])
|
|
||||||
|
|
||||||
class Config(unittest.TestCase):
|
class Config(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -90,6 +41,7 @@ class Config(unittest.TestCase):
|
||||||
self.config = cdist.config.Config("localhost",
|
self.config = cdist.config.Config("localhost",
|
||||||
initial_manifest=self.init_manifest,
|
initial_manifest=self.init_manifest,
|
||||||
exec_path=cdist_exec_path)
|
exec_path=cdist_exec_path)
|
||||||
|
self.config.link_emulator()
|
||||||
|
|
||||||
def test_initial_manifest_different_parameter(self):
|
def test_initial_manifest_different_parameter(self):
|
||||||
manifest_fd = open(self.init_manifest, "w")
|
manifest_fd = open(self.init_manifest, "w")
|
||||||
|
@ -121,6 +73,14 @@ class Config(unittest.TestCase):
|
||||||
|
|
||||||
self.assertRaises(cdist.Error, self.config.run_initial_manifest)
|
self.assertRaises(cdist.Error, self.config.run_initial_manifest)
|
||||||
|
|
||||||
|
def test_initial_manifest_non_existent_command(self):
|
||||||
|
manifest_fd = open(self.init_manifest, "w")
|
||||||
|
manifest_fd.writelines(["#!/bin/sh\n",
|
||||||
|
"thereisdefinitelynosuchcommend"])
|
||||||
|
manifest_fd.close()
|
||||||
|
|
||||||
|
self.assertRaises(cdist.Error, self.config.run_initial_manifest)
|
||||||
|
|
||||||
def test_initial_manifest_parameter_twice(self):
|
def test_initial_manifest_parameter_twice(self):
|
||||||
manifest_fd = open(self.init_manifest, "w")
|
manifest_fd = open(self.init_manifest, "w")
|
||||||
manifest_fd.writelines(["#!/bin/sh\n",
|
manifest_fd.writelines(["#!/bin/sh\n",
|
||||||
|
@ -138,5 +98,4 @@ class Config(unittest.TestCase):
|
||||||
|
|
||||||
self.assertFalse(failed)
|
self.assertFalse(failed)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
80
test/test_exec.py
Executable file
80
test/test_exec.py
Executable file
|
@ -0,0 +1,80 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
|
||||||
|
#
|
||||||
|
# This file is part of cdist.
|
||||||
|
#
|
||||||
|
# cdist is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# cdist is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.abspath(
|
||||||
|
os.path.join(os.path.dirname(os.path.realpath(__file__)), '../lib')))
|
||||||
|
|
||||||
|
import cdist.exec
|
||||||
|
|
||||||
|
class Exec(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
"""Create shell code and co."""
|
||||||
|
|
||||||
|
self.temp_dir = tempfile.mkdtemp()
|
||||||
|
self.shell_false = os.path.join(self.temp_dir, "shell_false")
|
||||||
|
self.shell_true = os.path.join(self.temp_dir, "shell_true")
|
||||||
|
|
||||||
|
true_fd = open(self.shell_true, "w")
|
||||||
|
true_fd.writelines(["#!/bin/sh\n", "/bin/true"])
|
||||||
|
true_fd.close()
|
||||||
|
|
||||||
|
false_fd = open(self.shell_false, "w")
|
||||||
|
false_fd.writelines(["#!/bin/sh\n", "/bin/false"])
|
||||||
|
false_fd.close()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.temp_dir)
|
||||||
|
|
||||||
|
def test_local_success_shell(self):
|
||||||
|
try:
|
||||||
|
cdist.exec.shell_run_or_debug_fail(self.shell_true, [self.shell_true])
|
||||||
|
except cdist.Error:
|
||||||
|
failed = True
|
||||||
|
else:
|
||||||
|
failed = False
|
||||||
|
|
||||||
|
self.assertFalse(failed)
|
||||||
|
|
||||||
|
def test_local_fail_shell(self):
|
||||||
|
self.assertRaises(cdist.Error, cdist.exec.shell_run_or_debug_fail,
|
||||||
|
self.shell_false, [self.shell_false])
|
||||||
|
|
||||||
|
def test_local_success(self):
|
||||||
|
try:
|
||||||
|
cdist.exec.run_or_fail(["/bin/true"])
|
||||||
|
except cdist.Error:
|
||||||
|
failed = True
|
||||||
|
else:
|
||||||
|
failed = False
|
||||||
|
|
||||||
|
self.assertFalse(failed)
|
||||||
|
|
||||||
|
def test_local_fail(self):
|
||||||
|
self.assertRaises(cdist.Error, cdist.exec.run_or_fail, ["/bin/false"])
|
Loading…
Reference in a new issue