Add helpers for cdist config/install integration. (#551)
Implement simple integration API.
This commit is contained in:
parent
feb221c5df
commit
136f2ecd87
8 changed files with 238 additions and 13 deletions
153
cdist/integration.py
Normal file
153
cdist/integration.py
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 2017 Darko Poljak (darko.poljak at gmail.com)
|
||||
#
|
||||
# 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
|
||||
# needed for cdist.argparse
|
||||
import cdist.banner
|
||||
import cdist.config
|
||||
import cdist.install
|
||||
import cdist.shell
|
||||
import cdist.inventory
|
||||
import cdist.argparse
|
||||
import cdist.log
|
||||
import cdist.config
|
||||
import cdist.install
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import collections
|
||||
import uuid
|
||||
|
||||
|
||||
def find_cdist_exec_in_path():
|
||||
"""Search cdist executable in os.get_exec_path() entries.
|
||||
"""
|
||||
for path in os.get_exec_path():
|
||||
cdist_path = os.path.join(path, 'cdist')
|
||||
if os.access(cdist_path, os.X_OK):
|
||||
return cdist_path
|
||||
return None
|
||||
|
||||
|
||||
_mydir = os.path.dirname(__file__)
|
||||
|
||||
|
||||
def find_cdist_exec():
|
||||
"""Search cdist executable starting from local lib directory.
|
||||
|
||||
Detect if ../scripts/cdist (from local lib direcotry) exists and
|
||||
if it is executable. If not then try to find cdist exec path in
|
||||
os.get_exec_path() entries. If no cdist path is found rasie
|
||||
cdist.Error.
|
||||
"""
|
||||
cdist_path = os.path.abspath(os.path.join(_mydir, '..', 'scripts',
|
||||
'cdist'))
|
||||
if os.access(cdist_path, os.X_OK):
|
||||
return cdist_path
|
||||
cdist_path = find_cdist_exec_in_path()
|
||||
if not cdist_path:
|
||||
raise cdist.Error('Cannot find cdist executable from local lib '
|
||||
'directory: {}, nor in PATH: {}.'.format(
|
||||
_mydir, os.environ.get('PATH')))
|
||||
return cdist_path
|
||||
|
||||
|
||||
ACTION_CONFIG = 'config'
|
||||
ACTION_INSTALL = 'install'
|
||||
|
||||
|
||||
def _process_hosts_simple(action, host, manifest, verbose,
|
||||
cdist_path=None):
|
||||
"""Perform cdist action ('config' or 'install') on hosts with specified
|
||||
manifest using default other cdist options. host parameter can be a
|
||||
string or iterbale of hosts. verbose is a desired verbosity level
|
||||
which defaults to VERBOSE_INFO. cdist_path is path to cdist executable,
|
||||
if it is None then integration lib tries to find it.
|
||||
"""
|
||||
if isinstance(host, str):
|
||||
hosts = [host, ]
|
||||
elif isinstance(host, collections.Iterable):
|
||||
hosts = host
|
||||
else:
|
||||
raise cdist.Error('Invalid host argument: {}'.format(host))
|
||||
|
||||
# Setup sys.argv[0] since cdist relies on command line invocation.
|
||||
if not cdist_path:
|
||||
cdist_path = find_cdist_exec()
|
||||
sys.argv[0] = cdist_path
|
||||
|
||||
cname = action.title()
|
||||
module = getattr(cdist, action)
|
||||
theclass = getattr(module, cname)
|
||||
|
||||
# Build argv for cdist and use argparse for argument parsing.
|
||||
remote_out_dir_base = os.path.join('/', 'var', 'lib', 'cdist')
|
||||
uid = str(uuid.uuid1())
|
||||
out_dir = remote_out_dir_base + uid
|
||||
cache_path_pattern = '%h-' + uid
|
||||
argv = [action, '-i', manifest, '-r', out_dir, '-C', cache_path_pattern, ]
|
||||
for i in range(verbose):
|
||||
argv.append('-v')
|
||||
for x in hosts:
|
||||
argv.append(x)
|
||||
|
||||
parser, cfg = cdist.argparse.parse_and_configure(argv, singleton=False)
|
||||
args = cfg.get_args()
|
||||
configuration = cfg.get_config(section='GLOBAL')
|
||||
|
||||
theclass.construct_remote_exec_copy_patterns(args)
|
||||
base_root_path = theclass.create_base_root_path(None)
|
||||
|
||||
for target_host in args.host:
|
||||
host_base_path, hostdir = theclass.create_host_base_dirs(
|
||||
target_host, base_root_path)
|
||||
theclass.onehost(target_host, None, host_base_path, hostdir, args,
|
||||
parallel=False, configuration=configuration,
|
||||
remove_remote_files_dirs=True)
|
||||
|
||||
|
||||
def configure_hosts_simple(host, manifest,
|
||||
verbose=cdist.argparse.VERBOSE_INFO,
|
||||
cdist_path=None):
|
||||
"""Configure hosts with specified manifest using default other cdist
|
||||
options. host parameter can be a string or iterbale of hosts. verbose
|
||||
is a desired verbosity level which defaults to VERBOSE_INFO.
|
||||
cdist_path is path to cdist executable, if it is None then integration
|
||||
lib tries to find it.
|
||||
"""
|
||||
_process_hosts_simple(action=ACTION_CONFIG, host=host,
|
||||
manifest=manifest, verbose=verbose,
|
||||
cdist_path=cdist_path)
|
||||
|
||||
|
||||
def install_hosts_simple(host, manifest,
|
||||
verbose=cdist.argparse.VERBOSE_INFO,
|
||||
cdist_path=None):
|
||||
"""Install hosts with specified manifest using default other cdist
|
||||
options. host parameter can be a string or iterbale of hosts. verbose
|
||||
is a desired verbosity level which defaults to VERBOSE_INFO.
|
||||
cdist_path is path to cdist executable, if it is None then integration
|
||||
lib tries to find it.
|
||||
"""
|
||||
_process_hosts_simple(action=ACTION_INSTALL, host=host,
|
||||
manifest=manifest, verbose=verbose,
|
||||
cdist_path=cdist_path)
|
||||
Loading…
Add table
Add a link
Reference in a new issue