Compare commits

...

4 Commits

Author SHA1 Message Date
Darko Poljak eac9aa3e1a Refactor cdist-info script
Use -g for GLOB option instead of -b.
Define and use functions.
2019-12-22 17:58:27 +01:00
Darko Poljak 3a71a7fb28 Mv cdist-new-type to libexec; create cdist-info 2019-12-21 16:57:04 +01:00
Darko Poljak a812167dc6 Exit with libexec command return code 2019-12-20 23:40:46 +01:00
Darko Poljak 7dddcb794b Add libexec support and migrate cdist-dump 2019-12-20 23:10:47 +01:00
10 changed files with 467 additions and 13 deletions

View File

@ -463,7 +463,7 @@ eof
shellcheck-scripts)
# shellcheck disable=SC2086
${SHELLCHECKCMD} scripts/cdist-dump scripts/cdist-new-type > "${SHELLCHECKTMP}"
${SHELLCHECKCMD} cdist/conf/libexec/cdist-dump cdist/conf/libexec/cdist-new-type > "${SHELLCHECKTMP}"
test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; }
;;

View File

@ -6,6 +6,7 @@ import collections
import functools
import cdist.configuration
import cdist.preos
import cdist.libexec as libexec
# set of beta sub-commands
@ -436,6 +437,9 @@ def get_parsers():
' should be POSIX compatible shell.'))
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
# Libexec
libexec.create_parsers(parser, parser['sub'])
for p in parser:
parser[p].epilog = EPILOG

399
cdist/conf/libexec/cdist-info Executable file
View File

@ -0,0 +1,399 @@
#!/bin/sh
VERSION="0.0.1"
RELEASE=""
set -u
# set -x
verbose=0
myname=${0##*/}
mydir=${0%/$myname}
dist_conf=${mydir%/libexec}
print_version()
{
printf "%s %s %s\n" "${myname}" "${VERSION}" "${RELEASE}"
}
usage()
{
cat << eof
${myname}: [options]
eof
print_version
cat << eof
Display information for cdist types and explorers.
Options
-C display only config types
-c CONF_DIR add configuration directory (can be repeated)
-D display only nondeprecated types
-d display only deprecated types
-E display only types without explorers
-e display only types with explorers
-G display global explorers (turns displaying types off,
unless -t is explicitly specified)
-g GLOB use GLOB as name pattern
-h display this help screen and exit
-i display only install types
-l display only types with gencode-local
-M display only types with man page
-m display only types with manifest
-P display only nonparallel types
-p display only parallel types
-R display type parameters
-r display only types with gencode-remote
-S display only nonsingleton types
-s display only singleton types
-t display types (by default, unless -G is specified)
-V display version and exit
-v increase verbosity (verbose output goes to stderr)
if verbosity is greater than 2 then 'set -x' is used
-x display type explorers
Notes:
By default, distribution and home dot cdist directories are used for
configuration directories list.
This helper tool does not parse cdist configuration files. Configuration
directories should be specifed by command line options and/or CDIST_PATH
environment variable.
eof
}
exit_err()
{
printf "%s\n" "$1"
exit 1
}
print_verbose()
{
if [ "${verbose}" -ge "$1" ]
then
printf "%s\n" "$2" >&2
fi
}
print_parameters()
{
param_title=$1
param_fname=$2
if test -f "${param_fname}"
then
printf " %s\n" "${param_title}"
sed "s/^\(.*\)$/ \1/" < "${param_fname}"
fi
}
type_name_matches()
{
if test "$2" == "*"
then
return 0
else
case "$(basename "$1")" in
$2)
return 0
;;
*)
return 1
;;
esac
fi
}
# $1 - do check flag.
# $2 - file path.
# Return false only if check flag is 1 and file does not exist.
type_file_exists()
{
if test "$1" -eq "1"
then
test -f "$2"
else
return 0
fi
}
# $1 - do check flag.
# $2 - file path.
# Return false only if check flag is 1 and file does exist.
type_file_not_exists()
{
if test "$1" -eq "1"
then
test ! -f "$2"
else
return 0
fi
}
type_dir_empty()
{
if test "$1" -eq "1"
then
if test ! -d "$2"
then
return 1
elif ! [ "$(ls -1 "${fname}/explorer")" ]
then
return 1
else
return 0
fi
else
return 0
fi
}
type_dir_not_empty()
{
if test "$1" -eq "1"
then
if test -d "$2"
then
if [ "$(ls -1 "${fname}/explorer")" ]
then
return 1
fi
else
return 0
fi
else
return 0
fi
}
print_type_params()
{
if test "$1" -eq "1"
then
print_parameters "required parameters:" "$2/parameter/required"
print_parameters "required multiple parameters:" "$2/parameter/required_multiple"
print_parameters "optional parameters:" "$2/parameter/optional"
print_parameters "optional multiple parameters:" "$2/parameter/optional_multiple"
print_parameters "boolean parameters:" "$2/parameter/boolean"
param_deprecated="$2/parameter/deprecated"
if test -d "${param_deprecated}"
then
printf " deprecated parameters:\n"
# shellcheck disable=SC2012
ls -1 "${param_deprecated}" | sed "s/^\(.*\)$/ \1/"
fi
fi
}
print_type_explorers()
{
if test "$1" -eq "1"
then
find "$2" -path "*/explorer/*" -type f
fi
}
print_type()
{
if test "$1" -eq "1"
then
printf "%s\n" "$2"
print_type_params "${display_type_params}" "$2"
print_type_explorers "${display_type_explorers}" "$2"
fi
}
print_global_explorers()
{
find "$1" '(' -path "*/explorer/*" -a ! -path "*/type/*/explorer/*" -a ! -path "*/cache/*/explorer/*" ')' -type f -name "$2"
}
conf_dirs="${dist_conf}:${HOME}/.cdist"
glob="*"
manifest_only=0
gencode_local_only=0
gencode_remote_only=0
install_only=0
config_only=0
parallel_only=0
nonparallel_only=0
singleton_only=0
nonsingleton_only=0
man_only=0
explorers_only=0
nonexplorers_only=0
deprecated_only=0
nondeprecated_only=0
display_global_explorers=0
display_types=1
display_type_params=0
display_type_explorers=0
# parse options
while [ "$#" -ge 1 ]
do
case "$1" in
-C)
config_only=1
;;
-c)
if [ "$#" -ge 2 ]
then
case "$2" in
-*)
exit_err "Missing configuration directory argument"
;;
*)
conf_dirs="${conf_dirs}:$2"
shift
;;
esac
else
exit_err "Missing configuration directory argument"
fi
;;
-D)
nondeprecated_only=1
;;
-d)
deprecated_only=1
;;
-E)
nonexplorers_only=1
;;
-e)
explorers_only=1
;;
-G)
display_types=0
display_global_explorers=1
;;
-g)
if [ "$#" -ge 2 ]
then
case "$2" in
-*)
exit_err "Missing glob argument"
;;
*)
glob="$2"
shift
;;
esac
else
exit_err "Missing glob argument"
fi
;;
-h)
usage
exit 0
;;
-i)
install_only=1
;;
-l)
gencode_local_only=1
;;
-M)
man_only=1
;;
-m)
manifest_only=1
;;
-P)
nonparallel_only=1
;;
-p)
parallel_only=1
;;
-R)
display_type_params=1
;;
-r)
gencode_remote_only=1
;;
-S)
nonsingleton_only=1
;;
-s)
singleton_only=1
;;
-t)
display_types=1
;;
-V)
print_version
exit 0
;;
-v)
verbose=$((verbose + 1))
;;
-x)
display_type_explorers=1
;;
*)
exit_err "Unknown argument $1"
;;
esac
shift
done
if test "${verbose}" -gt "2"
then
set -x
fi
if test "${CDIST_PATH:-}"
then
conf_dirs="${conf_dirs}:${CDIST_PATH}"
fi
print_verbose 2 "conf_dirs=${conf_dirs}"
OLD_IFS="${IFS}"
IFS=':'
for x in ${conf_dirs}
do
print_verbose 1 "Processing conf dir '${x}'"
if test "${display_global_explorers}" -eq "1"
then
print_verbose 1 "Printing global explorers"
print_global_explorers "${x}" "${glob}"
fi
if test "${display_types}" -eq "1"
then
print_verbose 1 "Printing types"
find "${x}" -path "*/type/*" -type d -prune | \
while read -r fname
do
print_verbose 2 "Printing type '${fname}'"
display_type=1
type_name_matches "${fname}" "${glob}" || display_type=0
type_file_exists "${manifest_only}" "${fname}/manifest" || display_type=0
type_file_exists "${gencode_local_only}" "${fname}/gencode-local" || display_type=0
type_file_exists "${gencode_remote_only}" "${fname}/gencode-remote" || display_type=0
type_file_not_exists "${config_only}" "${fname}/install" || display_type=0
type_file_exists "${install_only}" "${fname}/install" || display_type=0
type_file_not_exists "${parallel_only}" "${fname}/nonparallel" || display_type=0
type_file_exists "${nonparallel_only}" "${fname}/nonparallel" || display_type=0
type_file_exists "${singleton_only}" "${fname}/singleton" || display_type=0
type_file_not_exists "${nonsingleton_only}" "${fname}/singleton" || display_type=0
type_file_exists "${man_only}" "${fname}/man.rst" || display_type=0
type_file_exists "${deprecated_only}" "${fname}/deprecated" || display_type=0
type_file_not_exists "${nondeprecated_only}" "${fname}/deprecated" || display_type=0
type_dir_empty "${explorers_only}" "${fname}/explorer" || display_type=0
type_dir_not_empty "${nonexplorers_only}" "${fname}/explorer" || display_type=0
print_type "${display_type}" "${fname}"
done
fi
done
IFS="${OLD_IFS}"

45
cdist/libexec.py Normal file
View File

@ -0,0 +1,45 @@
import os
import os.path
import cdist.argparse
import subprocess
import sys
libexec_delimiter = '-'
libexec_prefix = 'cdist' + libexec_delimiter
libexec_path = os.path.abspath(
os.path.join(os.path.dirname(cdist.__file__), 'conf', 'libexec'))
def scan():
if os.path.isdir(libexec_path):
with os.scandir(libexec_path) as it:
for entry in it:
if (entry.name.startswith(libexec_prefix) and
entry.is_file() and
os.access(entry.path, os.X_OK)):
start = entry.name.find(libexec_delimiter) + 1
yield entry.name[start:]
def is_libexec_command(name):
for x in scan():
if name == x:
return True
return False
def create_parsers(parser, parent_parser):
for name in scan():
parser[name] = parent_parser.add_parser(name, add_help=False)
def run(name, argv):
lib_name = libexec_prefix + name
lib_path = os.path.join(libexec_path, lib_name)
args = [lib_path, ]
args.extend(argv)
try:
subprocess.check_call(args)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)

View File

@ -48,17 +48,17 @@ Using debug dump helper script
------------------------------
Since cdist stores data to local cache that can be used for debugging there
is a helper script that dumps data from local cache,
`cdist-dump <man1/cdist-dump.html>`_.
`cdist dump <man1/cdist-dump.html>`_.
For more info see:
.. code-block:: sh
cdist-dump -h
cdist_dump -h
Or from cdist git cloned directory:
.. code-block:: sh
./scripts/cdist-dump -h
./bin/cdist dump -h

View File

@ -11,17 +11,17 @@ SYNOPSIS
::
cdist-dump [options] [host...]
cdist dump [options] [host...]
DESCRIPTION
-----------
cdist-dump is a helper script that dumps data from local cdist cache for
cdist dump is a helper script that dumps data from local cdist cache for
specified hosts. If host is not specified then all data from cache directory
is dumped. Default cache directory is '~/.cdist/cache'.
cdist-dump can be used for debugging existing types, host configuration and
cdist dump can be used for debugging existing types, host configuration and
new types.
@ -88,10 +88,10 @@ EXAMPLES
.. code-block:: sh
# Dump all
% cdist-dump -a
% cdist dump -a
# Dump only code-* output
% cdist-dump -c
% cdist dump -c
SEE ALSO

View File

@ -30,14 +30,20 @@ import cdist.config
import cdist.install
import cdist.shell
import cdist.inventory
import cdist.libexec as libexec
def commandline():
"""Parse command line"""
# preos subcommand hack
if len(sys.argv) > 1 and sys.argv[1] == 'preos':
return cdist.preos.PreOS.commandline(sys.argv[1:])
if len(sys.argv) > 1:
# preos subcommand hack
if sys.argv[1] == 'preos':
return cdist.preos.PreOS.commandline(sys.argv[1:])
# libexec subcommands hack
if libexec.is_libexec_command(sys.argv[1]):
return libexec.run(sys.argv[1], sys.argv[2:])
parser, cfg = cdist.argparse.parse_and_configure(sys.argv[1:])
args = cfg.get_args()

View File

@ -56,7 +56,7 @@ setup(
name="cdist",
packages=["cdist", "cdist.core", "cdist.exec", "cdist.util", ],
package_data={'cdist': package_data},
scripts=["scripts/cdist", "scripts/cdist-dump", "scripts/cdist-new-type"],
scripts=["scripts/cdist", ],
version=cdist.version.VERSION,
description="A Usable Configuration Management System",
author="Nico Schottelius",