forked from ungleich-public/cdist
implement cdist install
Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
This commit is contained in:
parent
2c30704ba7
commit
54815e2b29
7 changed files with 58 additions and 120 deletions
|
@ -158,7 +158,6 @@ class Config(object):
|
||||||
self.local.save_cache()
|
self.local.save_cache()
|
||||||
self.log.info("Finished successful run in %s seconds", time.time() - start_time)
|
self.log.info("Finished successful run in %s seconds", time.time() - start_time)
|
||||||
|
|
||||||
|
|
||||||
def object_list(self):
|
def object_list(self):
|
||||||
"""Short name for object list retrieval"""
|
"""Short name for object list retrieval"""
|
||||||
for cdist_object in core.CdistObject.list_objects(self.local.object_path,
|
for cdist_object in core.CdistObject.list_objects(self.local.object_path,
|
||||||
|
|
|
@ -101,6 +101,11 @@ class CdistType(object):
|
||||||
"""Check whether a type is a singleton."""
|
"""Check whether a type is a singleton."""
|
||||||
return os.path.isfile(os.path.join(self.absolute_path, "singleton"))
|
return os.path.isfile(os.path.join(self.absolute_path, "singleton"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_install(self):
|
||||||
|
"""Check whether a type is used for installation (if not: for configuration)"""
|
||||||
|
return os.path.isfile(os.path.join(self.absolute_path, "install"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def explorers(self):
|
def explorers(self):
|
||||||
"""Return a list of available explorers"""
|
"""Return a list of available explorers"""
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
||||||
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
|
# 2012-2013 Steven Armstrong (steven-cdist at armstrong.cc)
|
||||||
#
|
#
|
||||||
# This file is part of cdist.
|
# This file is part of cdist.
|
||||||
#
|
#
|
||||||
|
|
37
cdist/install.py
Normal file
37
cdist/install.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# 2013 Steven Armstrong (steven-cdist at armstrong.cc)
|
||||||
|
#
|
||||||
|
# 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 cdist.config
|
||||||
|
import cdist.core
|
||||||
|
|
||||||
|
|
||||||
|
class Install(cdist.config.Config):
|
||||||
|
def object_list(self):
|
||||||
|
"""Short name for object list retrieval.
|
||||||
|
In install mode, we only care about install objects.
|
||||||
|
"""
|
||||||
|
for cdist_object in cdist.core.CdistObject.list_objects(self.local.object_path,
|
||||||
|
self.local.type_path):
|
||||||
|
if cdist_object.cdist_type.is_install:
|
||||||
|
yield cdist_object
|
||||||
|
else:
|
||||||
|
self.log.debug("Running in install mode, ignoring non install object: {0}".format(cdist_object))
|
|
@ -106,6 +106,16 @@ class TypeTestCase(test.CdistTestCase):
|
||||||
cdist_type = core.CdistType(base_path, '__not_singleton')
|
cdist_type = core.CdistType(base_path, '__not_singleton')
|
||||||
self.assertFalse(cdist_type.is_singleton)
|
self.assertFalse(cdist_type.is_singleton)
|
||||||
|
|
||||||
|
def test_install_is_install(self):
|
||||||
|
base_path = fixtures
|
||||||
|
cdist_type = core.CdistType(base_path, '__install')
|
||||||
|
self.assertTrue(cdist_type.is_install)
|
||||||
|
|
||||||
|
def test_not_install_is_install(self):
|
||||||
|
base_path = fixtures
|
||||||
|
cdist_type = core.CdistType(base_path, '__not_install')
|
||||||
|
self.assertFalse(cdist_type.is_install)
|
||||||
|
|
||||||
def test_with_explorers(self):
|
def test_with_explorers(self):
|
||||||
base_path = fixtures
|
base_path = fixtures
|
||||||
cdist_type = core.CdistType(base_path, '__with_explorers')
|
cdist_type = core.CdistType(base_path, '__with_explorers')
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
autorequire:
|
|
||||||
- objects defined in type manifests should be automatically prerequisites of the current object
|
|
||||||
- __foo/some-id
|
|
||||||
__other other-id --state present
|
|
||||||
=> require="__other/other-id" __foo/some-id
|
|
||||||
|
|
||||||
|
|
||||||
metaparameters:
|
|
||||||
- steal the metaparameters from puppet:
|
|
||||||
|
|
||||||
# I have to be there before the other one
|
|
||||||
__directory /etc/ssh \
|
|
||||||
--before __file/etc/ssh/sshd_config
|
|
||||||
|
|
||||||
# the other one has to be there before me
|
|
||||||
__file /etc/ssh/sshd_config \
|
|
||||||
--after __directory/etc/ssh
|
|
||||||
|
|
||||||
# if I change, tell the other one about it
|
|
||||||
__file /etc/ssh/sshd_config \
|
|
||||||
--notify __init_script/etc/rc.d/sshd
|
|
||||||
|
|
||||||
# whenever the other one changes, I want to know
|
|
||||||
__init_script /etc/rc.d/sshd \
|
|
||||||
--subscribe __file/etc/ssh/sshd_config
|
|
||||||
|
|
||||||
- how does a type react to a received 'event'?
|
|
||||||
- maybe something like:
|
|
||||||
__some_type/
|
|
||||||
manifest
|
|
||||||
...
|
|
||||||
gencode-refresh
|
|
||||||
...
|
|
||||||
- gencode-refresh -> code-refresh -> ssh $target sh -e code-refresh
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logging:
|
|
||||||
- logging from type emulator without clobbering stdout
|
|
||||||
maybe implement logging server as described here [1]
|
|
||||||
[1] http://docs.python.org/py3k/howto/logging-cookbook.html#configuration-server-example
|
|
||||||
|
|
||||||
- use different logger to limit output to current area of interest,
|
|
||||||
e.g.
|
|
||||||
explorer.$target_host: explorer related messages for the run for $target_host
|
|
||||||
manifest.$target_host: manifest related messages for the run for $target_host
|
|
||||||
...
|
|
||||||
then one could filter e.g. on explorer.*
|
|
||||||
|
|
||||||
- more granular debug output,
|
|
||||||
[2] http://blog.ooz.ie/2011/03/python-logging-extending-standard.html
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tests:
|
|
||||||
|
|
||||||
__init__():
|
|
||||||
- sets up env: __target_host
|
|
||||||
|
|
||||||
run_initial_manifest():
|
|
||||||
- parameter is actually used (from __init__)
|
|
||||||
- ensure changing the manifest actually runs a different manifest
|
|
||||||
-> give ConfigInstall Constructor different manifest
|
|
||||||
-> different manifest is executed.
|
|
||||||
- test all submitted (from core to type manifest) variables:
|
|
||||||
- ENVIRONMENT
|
|
||||||
- they are set
|
|
||||||
- they contain the correct values
|
|
||||||
|
|
||||||
run_type_manifest():
|
|
||||||
- test all submitted (from core to type manifest) variables:
|
|
||||||
- ENVIRONMENT
|
|
||||||
- they are set
|
|
||||||
- they contain the correct values
|
|
||||||
- same tests as for test_initial_manifest_*?
|
|
||||||
|
|
||||||
run_manifest():
|
|
||||||
- test all submitted variables:
|
|
||||||
- ENVIRONMENT
|
|
||||||
- including __debug, if debug
|
|
||||||
- they are set
|
|
||||||
- they contain the correct values
|
|
||||||
- does $require work?
|
|
||||||
- check that exception raised, if manifest is not existent
|
|
||||||
|
|
||||||
object_run():
|
|
||||||
- ensure no object is run twice
|
|
||||||
- ensure requirements are taken into account?
|
|
||||||
- and order of run is adjusted
|
|
||||||
- check (from extern?) that all needed variables are setup
|
|
||||||
- ensure no code-{local, remote} is created,
|
|
||||||
if gencode is not producing code
|
|
||||||
- ensure THAT code-{local, remote} contains what gencode created
|
|
||||||
- abort if gencode-* fails
|
|
||||||
- abort if code-* fails
|
|
||||||
- abort == raise(FooException)
|
|
||||||
- gencode-*: ensure ENVIRONMENT is setup correctly
|
|
||||||
|
|
||||||
run_type_explorer()
|
|
||||||
- ensure ALL type explores have been run
|
|
||||||
- ensure output is saved to correct path
|
|
||||||
- ensure a type with {0,1,2} explorers works ?
|
|
||||||
- none, one, multiple
|
|
||||||
- ensure ENVIRONMENT is setup correctly
|
|
||||||
- fails if ANY of the given explorer fails
|
|
||||||
|
|
||||||
run_global_explorers():
|
|
||||||
- ensure ALL type explores have been run
|
|
||||||
- ensure output is saved to correct path
|
|
||||||
- ensure a type with {0,1,2} explorers works ?
|
|
||||||
- none, one, multiple
|
|
||||||
- ensure ENVIRONMENT is setup correctly
|
|
||||||
- fails if ANY of the given explorer fails
|
|
||||||
|
|
||||||
Code fixes needed:
|
|
||||||
|
|
||||||
- shutil, os.mkdir, etc. everywhere: catch/reraise exceptions correctly
|
|
|
@ -26,6 +26,7 @@ def commandline():
|
||||||
|
|
||||||
import cdist.banner
|
import cdist.banner
|
||||||
import cdist.config
|
import cdist.config
|
||||||
|
import cdist.install
|
||||||
import cdist.shell
|
import cdist.shell
|
||||||
|
|
||||||
# Construct parser others can reuse
|
# Construct parser others can reuse
|
||||||
|
@ -90,6 +91,10 @@ def commandline():
|
||||||
help='Select shell to use, defaults to current shell')
|
help='Select shell to use, defaults to current shell')
|
||||||
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
|
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
|
||||||
|
|
||||||
|
# Install
|
||||||
|
parser['install'] = parser['sub'].add_parser('install',
|
||||||
|
parents=[parser['loglevel'], parser['config']])
|
||||||
|
parser['install'].set_defaults(func=cdist.install.Install.commandline)
|
||||||
|
|
||||||
for p in parser:
|
for p in parser:
|
||||||
parser[p].epilog = "Get cdist at http://www.nico.schottelius.org/software/cdist/"
|
parser[p].epilog = "Get cdist at http://www.nico.schottelius.org/software/cdist/"
|
||||||
|
|
Loading…
Reference in a new issue