diff --git a/bin/build-helper b/bin/build-helper index 5dcc6989..ed41e438 100755 --- a/bin/build-helper +++ b/bin/build-helper @@ -370,7 +370,7 @@ eof cat << eof Manual steps post release: - cdist-web - - send mail body generated in mailinglist.tmp and inform Dmitry for deb + - send generated mailinglist.tmp mail - twitter eof ;; @@ -463,7 +463,7 @@ eof shellcheck-scripts) # shellcheck disable=SC2086 - ${SHELLCHECKCMD} cdist/conf/libexec/cdist-dump cdist/conf/libexec/cdist-new-type > "${SHELLCHECKTMP}" + ${SHELLCHECKCMD} scripts/cdist-dump scripts/cdist-new-type > "${SHELLCHECKTMP}" test ! -s "${SHELLCHECKTMP}" || { cat "${SHELLCHECKTMP}"; exit 1; } ;; diff --git a/cdist/argparse.py b/cdist/argparse.py index b1ee99da..611c484a 100644 --- a/cdist/argparse.py +++ b/cdist/argparse.py @@ -6,7 +6,7 @@ import collections import functools import cdist.configuration import cdist.preos -import cdist.libexec as libexec +import cdist.info # set of beta sub-commands @@ -437,8 +437,36 @@ def get_parsers(): ' should be POSIX compatible shell.')) parser['shell'].set_defaults(func=cdist.shell.Shell.commandline) - # Libexec - libexec.create_parsers(parser, parser['sub']) + # Info + parser['info'] = parser['sub'].add_parser('info') + parser['info'].add_argument( + '-a', '--all', help='Display all info. This is the default.', + action='store_true', default=False) + parser['info'].add_argument( + '-c', '--conf-dir', + help='Add configuration directory (can be repeated).', + action='append') + parser['info'].add_argument( + '-e', '--global-explorers', + help='Display info for global explorers.', action='store_true', + default=False) + parser['info'].add_argument( + '-F', '--fixed-string', + help='Interpret pattern as a fixed string.', action='store_true', + default=False) + parser['info'].add_argument( + '-f', '--full', help='Display full details.', + action='store_true', default=False) + parser['info'].add_argument( + '-g', '--config-file', + help='Use specified custom configuration file.', + dest="config_file", required=False) + parser['info'].add_argument( + '-t', '--types', help='Display info for types.', + action='store_true', default=False) + parser['info'].add_argument( + 'pattern', nargs='?', help='Glob pattern.') + parser['info'].set_defaults(func=cdist.info.Info.commandline) for p in parser: parser[p].epilog = EPILOG diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks index 87a6b5c6..24540601 100755 --- a/cdist/conf/explorer/disks +++ b/cdist/conf/explorer/disks @@ -1,27 +1,67 @@ -#!/bin/sh +#!/bin/sh -e +# +# based on previous work by other people, modified by: +# 2020 Dennis Camera +# +# 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 . +# +# Finds disks of the system (excl. ram disks, floppy, cdrom) uname_s="$(uname -s)" -case "${uname_s}" in +case $uname_s in FreeBSD) sysctl -n kern.disks ;; - OpenBSD|NetBSD) - sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]+' | xargs + OpenBSD) + sysctl -n hw.disknames | grep -Eo '[lsw]d[0-9]+' + ;; + NetBSD) + PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin" + sysctl -n hw.disknames \ + | awk 'BEGIN { RS = " " } /^[lsw]d[0-9]+/' ;; Linux) - if command -v lsblk > /dev/null + # list of major device numbers toexclude: + # ram disks, floppies, cdroms + # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt + ign_majors='1 2 11' + + if command -v lsblk >/dev/null 2>&1 then - # exclude ram disks, floppies and cdroms - # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt - lsblk -e 1,2,11 -dno name | xargs + lsblk -e "$(echo "$ign_majors" | tr ' ' ',')" -dno name + elif test -d /sys/block/ + then + # shellcheck disable=SC2012 + ls -1 /sys/block/ \ + | awk -v ign_majors="$(echo "$ign_majors" | tr ' ' '|')" ' + { + devfile = "/sys/block/" $0 "/dev" + getline devno < devfile + close(devfile) + if (devno !~ "^(" ign_majors "):") print + }' else - printf "Don't know how to list disks for %s operating system without lsblk, if you can please submit a patch\n" "${uname_s}" >&2 + echo "Don't know how to list disks on Linux without lsblk and sysfs." >&2 + echo 'If you can, please submit a patch.'>&2 fi ;; *) - printf "Don't know how to list disks for %s operating system, if you can please submit a patch\n" "${uname_s}" >&2 + printf "Don't know how to list disks for %s operating system.\n" "${uname_s}" >&2 + printf 'If you can please submit a patch\n' >&2 ;; -esac - -exit 0 +esac \ +| xargs diff --git a/cdist/conf/explorer/init b/cdist/conf/explorer/init index a8a7857e..1b921c68 100755 --- a/cdist/conf/explorer/init +++ b/cdist/conf/explorer/init @@ -1,7 +1,8 @@ -#!/bin/sh +#!/bin/sh -e # # 2016 Daniel Heule (hda at sfs.biz) # Copyright 2017, Philippe Gregoire +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -19,21 +20,422 @@ # along with cdist. If not, see . # # -# Returns the process name of pid 1 ( normaly the init system ) -# for example at linux this value is "init" or "systemd" in most cases +# Returns the name of the init system (PID 1) + +# Expected values: +# Linux: +# Adélie Linux: +# sysvinit+openrc +# Alpine Linux: +# busybox-init+openrc +# ArchLinux: +# systemd, sysvinit +# CRUX: +# sysvinit +# Debian: +# systemd, upstart, sysvinit, openrc, ??? +# Devuan: +# sysvinit, sysvinit+openrc +# Gentoo: +# sysvinit+openrc, openrc-init, systemd +# OpenBMC: +# systemd +# OpenWrt: +# procd, init??? +# RedHat (RHEL, CentOS, Fedora, RedHat Linux, ...): +# systemd, upstart, upstart-legacy, sysvinit +# Slackware: +# sysvinit +# SuSE: +# systemd, sysvinit +# Ubuntu: +# systemd, upstart, upstart-legacy, sysvinit +# VoidLinux: +# runit # +# GNU: +# Debian: +# sysvinit, hurd-init +# +# BSD: +# {Free,Open,Net}BSD: +# init +# +# Mac OS X: +# launchd, init+SystemStarter +# +# Solaris/Illumos: +# smf, init??? -uname_s="$(uname -s)" +# NOTE: init systems can be stacked. This is popular to run OpenRC on top of +# sysvinit (Gentoo) or busybox-init (Alpine), but can also be used to run runit +# as a systemd service. This makes init system detection very complicated +# (which result is expected?) This script tries to untangle some combinations, +# OpenRC on top of sysv or busybox (X+openrc), but will ignore others (runit as +# a systemd service) -case "$uname_s" in - Linux) - (pgrep -P0 -l | awk '/^1[ \t]/ {print $2;}') || true - ;; - FreeBSD|OpenBSD) - ps -o comm= -p 1 || true - ;; - *) - # return a empty string as unknown value - echo "" - ;; -esac +# NOTE: When we have no idea, nothing will be printed! + +# NOTE: +# When trying to gather information about the init system make sure to do so +# without calling the binary! On some systems this triggers a reinitialisation +# of the system which we don't want (e.g. embedded systems). + + +set -e + +KERNEL_NAME=$(uname -s) + +KNOWN_INIT_SYSTEMS=$(cat </dev/null 2>&1 || return 1 + launchctl getenv PATH >/dev/null || return 1 + echo launchd +} + +check_openrc() { + test -f /run/openrc/softlevel || return 1 + echo openrc +} + +check_procd() ( + procd_path=${1:-/sbin/procd} + test -x "${procd_path}" || return 1 + grep -q 'procd' "${procd_path}" || return 1 + echo procd +) + +check_runit() { + test -d /run/runit || return 1 + echo runit +} + +check_smf() { + # XXX: Is this the correct way?? + test -f /etc/svc/volatile/svc_nonpersist.db || return 1 + echo smf +} + +check_systemd() { + # NOTE: sd_booted(3) + test -d /run/systemd/system/ || return 1 + # systemctl --version | sed -e '/^systemd/!d;s/^systemd //' + echo systemd +} + +check_systemstarter() { + test -d /System/Library/StartupItems/ || return 1 + test -f /System/Library/StartupItems/LoginWindow/StartupParameters.plist || return 1 + echo init+SystemStarter +} + +check_sysvinit() ( + init_path=${1:-/sbin/init} + grep -q 'INIT_VERSION=sysvinit-[0-9.]*' "${init_path}" || return 1 + + # It is quite common to use SysVinit to stack other init systemd + # (like OpenRC) on top of it. So we check for that, too. + if stacked=$(check_openrc) + then + echo "sysvinit+${stacked}" + else + echo sysvinit + fi + unset stacked +) + +check_upstart() { + test -x "$(command -v initctl)" || return 1 + case $(initctl version) + in + *'(upstart '*')') + if test -d /etc/init + then + # modern (DBus-based?) upstart >= 0.5 + echo upstart + elif test -d /etc/event.d + then + # ancient upstart + echo upstart-legacy + else + # whatever... + echo upstart + fi + ;; + *) + return 1 + ;; + esac +} + +find_init_procfs() ( + # First, check if the required file in procfs exists... + test -h /proc/1/exe || return 1 + + # Find init executable + init_exe=$(ls -l /proc/1/exe 2>/dev/null) || return 1 + init_exe=${init_exe#* -> } + + if ! test -x "$init_exe" + then + # On some rare occasions it can happen that the + # running init's binary has been replaced. In this + # case Linux adjusts the symlink to "X (deleted)" + + # [root@fedora-12 ~]# readlink /proc/1/exe + # /sbin/init (deleted) + # [root@fedora-12 ~]# ls -l /proc/1/exe + # lrwxrwxrwx. 1 root root 0 2020-01-30 23:00 /proc/1/exe -> /sbin/init (deleted) + + init_exe=${init_exe% (deleted)} + test -x "$init_exe" || return 1 + fi + + echo "${init_exe}" +) + +guess_by_path() { + case $1 + in + /bin/busybox) + check_busybox_init "$1" && return + ;; + /lib/systemd/systemd) + check_systemd "$1" && return + ;; + /hurd/init) + check_hurd_init "$1" && return + ;; + /sbin/launchd) + check_launchd "$1" && return + ;; + /usr/bin/runit|/sbin/runit) + check_runit "$1" && return + ;; + /sbin/openrc-init) + if check_openrc "$1" >/dev/null + then + echo openrc-init + return + fi + ;; + /sbin/procd) + check_procd "$1" && return + ;; + /sbin/init|*/init) + # init: it could be anything -> (explicit) no match + return 1 + ;; + esac + + # No match + return 1 +} + +guess_by_comm_name() { + case $1 + in + busybox) + check_busybox_init && return + ;; + openrc-init) + if check_openrc >/dev/null + then + echo openrc-init + return 0 + fi + ;; + init) + # init could be anything -> no match + return 1 + ;; + *) + # Run check function by comm name if available. + # Fall back to comm name if either it does not exist or + # returns non-zero. + if type "check_$1" >/dev/null + then + "check_$1" && return + else + echo "$1" ; return 0 + fi + esac + + return 1 +} + +check_list() ( + # List must be a multi-line input on stdin (one name per line) + while read -r init + do + "check_${init}" || continue + return 0 + done + return 1 +) + + +# BusyBox's versions of ps and pgrep do not support some options +# depending on which compile-time options have been used. + +find_init_pgrep() { + pgrep -P0 -fl 2>/dev/null | awk -F '[[:blank:]]' '$1 == 1 { print $2 }' +} + +find_init_ps() { + case $KERNEL_NAME + in + Darwin) + ps -o command -p 1 2>/dev/null | tail -n +2 + ;; + FreeBSD) + ps -o args= -p 1 2>/dev/null | cut -d ' ' -f 1 + ;; + Linux) + ps -o comm= -p 1 2>/dev/null + ;; + NetBSD) + ps -o comm= -p 1 2>/dev/null + ;; + OpenBSD) + ps -o args -p 1 2>/dev/null | tail -n +2 | cut -d ' ' -f 1 + ;; + *) + ps -o args= -p 1 2>/dev/null + ;; + esac | trim # trim trailing whitespace (some ps like Darwin add it) +} + +find_init() { + case $KERNEL_NAME + in + Linux|GNU|NetBSD) + find_init_procfs || find_init_pgrep || find_init_ps + ;; + FreeBSD) + find_init_procfs || find_init_ps + ;; + OpenBSD) + find_init_pgrep || find_init_ps + ;; + Darwin|SunOS) + find_init_ps + ;; + *) + echo "Don't know how to determine init." >&2 + echo 'Please send a patch.' >&2 + exit 1 + esac +} + +# ----- + +init=$(find_init) + +# If we got a path, guess by the path first (fall back to file name if no match) +# else guess by file name directly. +# shellcheck disable=SC2015 +{ + test -x "${init}" \ + && guess_by_path "${init}" \ + || guess_by_comm_name "$(basename "${init}")" +} && exit 0 || true + + +# Guessing based on the file path and name didn’t lead to a definitive result. +# +# We go through all of the checks until we find a match. To speed up the +# process, common cases will be checked first based on the underlying kernel. + +{ common_candidates_by_kernel; echo "${KNOWN_INIT_SYSTEMS}"; } \ + | unique | check_list diff --git a/cdist/conf/explorer/os_release b/cdist/conf/explorer/os_release index cfc01004..6489446b 100644 --- a/cdist/conf/explorer/os_release +++ b/cdist/conf/explorer/os_release @@ -1,6 +1,7 @@ #!/bin/sh # # 2018 Adam Dej (dejko.a at gmail.com) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -21,6 +22,17 @@ # See os-release(5) and http://0pointer.de/blog/projects/os-release -set +e +if test -f /etc/os-release +then + # Linux and FreeBSD (usually a symlink) + cat /etc/os-release +elif test -f /usr/lib/os-release +then + # systemd + cat /usr/lib/os-release +elif test -f /var/run/os-release +then + # FreeBSD (created by os-release service) + cat /var/run/os-release +fi -cat /etc/os-release || cat /usr/lib/os-release || true diff --git a/cdist/conf/explorer/os_version b/cdist/conf/explorer/os_version index 4c41695b..1d54ea60 100755 --- a/cdist/conf/explorer/os_version +++ b/cdist/conf/explorer/os_version @@ -70,4 +70,7 @@ case "$("$__explorer/os")" in ubuntu) lsb_release -sr ;; -esac + alpine) + cat /etc/alpine-release + ;; +esac \ No newline at end of file diff --git a/cdist/conf/libexec/cdist-info b/cdist/conf/libexec/cdist-info deleted file mode 100755 index 19ec4cad..00000000 --- a/cdist/conf/libexec/cdist-info +++ /dev/null @@ -1,399 +0,0 @@ -#!/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}" diff --git a/cdist/conf/type/__acl/gencode-remote b/cdist/conf/type/__acl/gencode-remote index 6dab4d09..e5404a9d 100755 --- a/cdist/conf/type/__acl/gencode-remote +++ b/cdist/conf/type/__acl/gencode-remote @@ -20,7 +20,13 @@ file_is="$( cat "$__object/explorer/file_is" )" -[ "$file_is" = 'missing' ] && [ -z "$__cdist_dry_run" ] && exit 0 +if [ "$file_is" = 'missing' ] \ + && [ -z "$__cdist_dry_run" ] \ + && \( [ ! -f "$__object/parameter/file" ] \ + || [ ! -f "$__object/parameter/directory" ] \) +then + exit 0 +fi os="$( cat "$__global/explorer/os" )" @@ -28,7 +34,20 @@ acl_path="/$__object_id" acl_is="$( cat "$__object/explorer/acl_is" )" -if [ -f "$__object/parameter/acl" ] +if [ -f "$__object/parameter/source" ] +then + acl_source="$( cat "$__object/parameter/source" )" + + if [ "$acl_source" = '-' ] + then + acl_should="$( cat "$__object/stdin" )" + else + acl_should="$( grep -Ev '^#|^$' "$acl_source" )" + fi +elif [ -f "$__object/parameter/entry" ] +then + acl_should="$( cat "$__object/parameter/entry" )" +elif [ -f "$__object/parameter/acl" ] then acl_should="$( cat "$__object/parameter/acl" )" elif diff --git a/cdist/conf/type/__acl/man.rst b/cdist/conf/type/__acl/man.rst index 85e946ce..28412871 100644 --- a/cdist/conf/type/__acl/man.rst +++ b/cdist/conf/type/__acl/man.rst @@ -15,10 +15,24 @@ See ``setfacl`` and ``acl`` manpages for more details. REQUIRED MULTIPLE PARAMETERS ---------------------------- -acl +entry Set ACL entry following ``getfacl`` output syntax. +OPTIONAL PARAMETERS +------------------- +source + Read ACL entries from stdin or file. + Ordering of entries is not important. + When reading from file, comments and empty lines are ignored. + +file + Create/change file with ``__file`` using ``user:group:mode`` pattern. + +directory + Create/change directory with ``__directory`` using ``user:group:mode`` pattern. + + BOOLEAN PARAMETERS ------------------ default @@ -36,8 +50,8 @@ remove DEPRECATED PARAMETERS --------------------- -Parameters ``user``, ``group``, ``mask`` and ``other`` are deprecated and they -will be removed in future versions. Please use ``acl`` parameter instead. +Parameters ``acl``, ``user``, ``group``, ``mask`` and ``other`` are deprecated and they +will be removed in future versions. Please use ``entry`` parameter instead. EXAMPLES @@ -49,27 +63,38 @@ EXAMPLES --default \ --recursive \ --remove \ - --acl user:alice:rwx \ - --acl user:bob:r-x \ - --acl group:project-group:rwx \ - --acl group:some-other-group:r-x \ - --acl mask::r-x \ - --acl other::r-x + --entry user:alice:rwx \ + --entry user:bob:r-x \ + --entry group:project-group:rwx \ + --entry group:some-other-group:r-x \ + --entry mask::r-x \ + --entry other::r-x # give Alice read-only access to subdir, # but don't allow her to see parent content. __acl /srv/project2 \ --remove \ - --acl default:group:secret-project:rwx \ - --acl group:secret-project:rwx \ - --acl user:alice:--x + --entry default:group:secret-project:rwx \ + --entry group:secret-project:rwx \ + --entry user:alice:--x __acl /srv/project2/subdir \ --default \ --remove \ - --acl group:secret-project:rwx \ - --acl user:alice:r-x + --entry group:secret-project:rwx \ + --entry user:alice:r-x + + # read acl from stdin + echo 'user:alice:rwx' \ + | __acl /path/to/directory --source - + + # create/change directory too + __acl /path/to/directory \ + --default \ + --remove \ + --directory root:root:770 \ + --entry user:nobody:rwx AUTHORS diff --git a/cdist/conf/type/__acl/manifest b/cdist/conf/type/__acl/manifest new file mode 100755 index 00000000..5fd23110 --- /dev/null +++ b/cdist/conf/type/__acl/manifest @@ -0,0 +1,11 @@ +#!/bin/sh -e + +for p in file directory +do + [ ! -f "$__object/parameter/$p" ] && continue + + "__$p" "/$__object_id" \ + --owner "$( awk -F: '{print $1}' "$__object/parameter/$p" )" \ + --group "$( awk -F: '{print $2}' "$__object/parameter/$p" )" \ + --mode "$( awk -F: '{print $3}' "$__object/parameter/$p" )" +done diff --git a/cdist/conf/type/__acl/parameter/deprecated/acl b/cdist/conf/type/__acl/parameter/deprecated/acl new file mode 100644 index 00000000..94e14159 --- /dev/null +++ b/cdist/conf/type/__acl/parameter/deprecated/acl @@ -0,0 +1 @@ +see manual for details diff --git a/cdist/conf/type/__acl/parameter/optional b/cdist/conf/type/__acl/parameter/optional index 4b32086b..cdcbc0b8 100644 --- a/cdist/conf/type/__acl/parameter/optional +++ b/cdist/conf/type/__acl/parameter/optional @@ -1,2 +1,5 @@ mask other +source +file +directory diff --git a/cdist/conf/type/__acl/parameter/optional_multiple b/cdist/conf/type/__acl/parameter/optional_multiple index 95c25d55..c615d507 100644 --- a/cdist/conf/type/__acl/parameter/optional_multiple +++ b/cdist/conf/type/__acl/parameter/optional_multiple @@ -1,3 +1,4 @@ +entry acl user group diff --git a/cdist/conf/type/__apt_unattended_upgrades/man.rst b/cdist/conf/type/__apt_unattended_upgrades/man.rst new file mode 100644 index 00000000..2231b5f9 --- /dev/null +++ b/cdist/conf/type/__apt_unattended_upgrades/man.rst @@ -0,0 +1,68 @@ +cdist-type__apt_unattended_upgrades(7) +====================================== + +NAME +---- +cdist-type__apt_unattended_upgrades - automatic installation of updates + + +DESCRIPTION +----------- + +Install and configure unattended-upgrades package. + +For more information see https://wiki.debian.org/UnattendedUpgrades. + + +OPTIONAL MULTIPLE PARAMETERS +---------------------------- +option + Set options for unattended-upgrades. See examples. + + Supported options with default values (as of 2020-01-17) are: + + - AutoFixInterruptedDpkg, default is "true" + - MinimalSteps, default is "true" + - InstallOnShutdown, default is "false" + - Mail, default is "" (empty) + - MailOnlyOnError, default is "false" + - Remove-Unused-Kernel-Packages, default is "true" + - Remove-New-Unused-Dependencies, default is "true" + - Remove-Unused-Dependencies, default is "false" + - Automatic-Reboot, default is "false" + - Automatic-Reboot-WithUsers, default is "true" + - Automatic-Reboot-Time, default is "02:00" + - SyslogEnable, default is "false" + - SyslogFacility, default is "daemon" + - OnlyOnACPower, default is "true" + - Skip-Updates-On-Metered-Connections, default is "true" + - Verbose, default is "false" + - Debug, default is "false" + +blacklist + Python regular expressions, matching packages to exclude from upgrading. + + +EXAMPLES +-------- + +.. code-block:: sh + + __apt_unattended_upgrades \ + --option Mail=root \ + --option MailOnlyOnError=true \ + --blacklist multipath-tools \ + --blacklist open-iscsi + + +AUTHORS +------- +Ander Punnar + + +COPYING +------- +Copyright \(C) 2020 Ander Punnar. 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. diff --git a/cdist/conf/type/__apt_unattended_upgrades/manifest b/cdist/conf/type/__apt_unattended_upgrades/manifest new file mode 100755 index 00000000..3c00e2f4 --- /dev/null +++ b/cdist/conf/type/__apt_unattended_upgrades/manifest @@ -0,0 +1,80 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +__package unattended-upgrades + +export require='__package/unattended-upgrades' + +# in normal circumstances 20auto-upgrades is managed +# by debconf and it can only contain these lines + +__file /etc/apt/apt.conf.d/20auto-upgrades \ + --owner root \ + --group root \ + --mode 644 \ + --source - << EOF +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Unattended-Upgrade "1"; +EOF + +# lets not write into upstream 50unattended-upgrades file, +# but use our own config file to avoid clashes + +conf_file='/etc/apt/apt.conf.d/51unattended-upgrades-cdist' + +conf='# this file is managed by cdist' + +if [ -f "$__object/parameter/option" ] +then + o='' + + while read -r l + do + o="$( printf '%s\nUnattended-Upgrade::%s "%s";\n' "$o" "${l%%=*}" "${l#*=}" )" + done \ + < "$__object/parameter/option" + + conf="$( printf '%s\n%s\n' "$conf" "$o" )" +fi + +if [ -f "$__object/parameter/blacklist" ] +then + b='Unattended-Upgrade::Package-Blacklist {' + + while read -r l + do + b="$( printf '%s\n"%s";\n' "$b" "$l" )" + done \ + < "$__object/parameter/blacklist" + + conf="$( printf '%s\n%s\n}\n' "$conf" "$b" )" +fi + +if [ "$( echo "$conf" | wc -l )" -gt 1 ] +then + echo "$conf" \ + | __file "$conf_file" \ + --owner root \ + --group root \ + --mode 644 \ + --source - +else + __file "$conf_file" --state absent +fi diff --git a/cdist/conf/type/__apt_unattended_upgrades/parameter/optional_multiple b/cdist/conf/type/__apt_unattended_upgrades/parameter/optional_multiple new file mode 100644 index 00000000..ea4fba2b --- /dev/null +++ b/cdist/conf/type/__apt_unattended_upgrades/parameter/optional_multiple @@ -0,0 +1,2 @@ +option +blacklist diff --git a/cdist/conf/type/__apt_unattended_upgrades/singleton b/cdist/conf/type/__apt_unattended_upgrades/singleton new file mode 100644 index 00000000..e69de29b diff --git a/cdist/conf/type/__consul_agent/man.rst b/cdist/conf/type/__consul_agent/man.rst index 966abc60..62ee70bb 100644 --- a/cdist/conf/type/__consul_agent/man.rst +++ b/cdist/conf/type/__consul_agent/man.rst @@ -116,6 +116,9 @@ verify-incoming verify-outgoing enforce the use of TLS and verify the peers authenticity on outgoing connections +use-distribution-package + uses distribution package instead of upstream binary + EXAMPLES -------- diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest index a88d26ed..0d819d45 100755 --- a/cdist/conf/type/__consul_agent/manifest +++ b/cdist/conf/type/__consul_agent/manifest @@ -2,6 +2,7 @@ # # 2015 Steven Armstrong (steven-cdist at armstrong.cc) # 2015-2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2019 Timothée Floure (timothee.floure at ungleich.ch) # # This file is part of cdist. # @@ -19,133 +20,75 @@ # along with cdist. If not, see . # - os=$(cat "$__global/explorer/os") -case "$os" in - alpine|scientific|centos|debian|devuan|redhat|ubuntu) - # whitelist safeguard - : - ;; - *) - echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2 - echo "Please contribute an implementation for it if you can." >&2 - exit 1 - ;; -esac +### +# Type parameters. state="$(cat "$__object/parameter/state")" user="$(cat "$__object/parameter/user")" group="$(cat "$__object/parameter/group")" +release=$(cat "$__global/explorer/lsb_release") +if [ -f "$__object/parameter/use-distribution-package" ]; then + use_distribution_package=1 +fi + +### +# Those are default that might be overriden by os-specific logic. + data_dir="/var/lib/consul" conf_dir="/etc/consul/conf.d" conf_file="config.json" +tls_dir="$conf_dir/tls" -# FIXME: there has got to be a better way to handle the dependencies in this case -case "$state" in - present) - __group "$group" --system --state "$state" - require="__group/$group" \ - __user "$user" --system --gid "$group" \ - --home "$data_dir" --state "$state" - export require="__user/consul" - ;; - absent) - echo "Sorry, state=absent currently not supported :-(" >&2 - exit 1 - require="$__object_name" \ - __user "$user" --system --gid "$group" --state "$state" - require="__user/$user" \ - __group "$group" --system --state "$state" - ;; -esac +### +# Sane deployment, based on distribution package when available. -__directory /etc/consul \ - --owner root --group "$group" --mode 750 --state "$state" -require="__directory/etc/consul" \ - __directory "$conf_dir" \ - --owner root --group "$group" --mode 750 --state "$state" +distribution_setup () { + case "$os" in + debian) + # consul is only available starting Debian 10 (buster). + # See https://packages.debian.org/buster/consul + if [ "$release" -lt 10 ]; then + echo "Consul is not available for your debian release." >&2 + echo "Please use the 'manual' (i.e. non-package) installation or \ + upgrade the target system." >&2 + exit 1 + fi -if [ -f "$__object/parameter/ca-file-source" ] || [ -f "$__object/parameter/cert-file-source" ] || [ -f "$__object/parameter/key-file-source" ]; then - # create directory for ssl certs - require="__directory/etc/consul" \ - __directory /etc/consul/ssl \ - --owner root --group "$group" --mode 750 --state "$state" -fi + # Override previously defined environment to match debian packaging. + conf_dir='/etc/consul.d' + user='consul' + group='consul' + ;; + alpine) + # consul is only available starting Alpine 3.12 (= edge during the 3.11 cycle). + # See https://pkgs.alpinelinux.org/packages?name=consul&branch=edge -__directory "$data_dir" \ - --owner "$user" --group "$group" --mode 770 --state "$state" + # Override previously defined environment to match alpine packaging. + conf_dir='/etc/consul' + conf_file='server.json' + data_dir='/var/consul' + user='consul' + group='consul' + ;; + *) + echo "Your operating system ($os) is currently not supported with the \ + --use-distribution-package flag (${__type##*/})." >&2 + echo "Please use non-package installation or contribute an \ + implementation for if you can." >&2 + exit 1 + ;; + esac + # Install consul package. + __package consul --state "$state" -# Generate json config file -( -echo "{" + export config_deployment_requires="__package/consul" +} -# parameters we define ourself -printf ' "data_dir": "%s"\n' "$data_dir" - -cd "$__object/parameter/" -for param in *; do - case "$param" in - state|user|group|json-config) continue ;; - ca-file-source|cert-file-source|key-file-source) - source="$(cat "$__object/parameter/$param")" - destination="/etc/consul/ssl/${source##*/}" - require="__directory/etc/consul/ssl" \ - __file "$destination" \ - --owner root --group consul --mode 640 \ - --source "$source" \ - --state "$state" - key="$(echo "${param%-*}" | tr '-' '_')" - printf ' ,"%s": "%s"\n' "$key" "$destination" - ;; - disable-remote-exec|disable-update-check|leave-on-terminate|rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing) - # handle boolean parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": true\n' "$key" - ;; - retry-join) - # join multiple parameters into json array - retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")" - # remove trailing , - printf ' ,"retry_join": [%s]\n' "${retry_join%*,}" - ;; - retry-join-wan) - # join multiple parameters into json array over wan - retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")" - # remove trailing , - printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}" - ;; - bootstrap-expect) - # integer key=value parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")" - ;; - *) - # string key=value parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")" - ;; - esac -done -if [ -f "$__object/parameter/json-config" ]; then - json_config="$(cat "$__object/parameter/json-config")" - if [ "$json_config" = "-" ]; then - json_config="$__object/stdin" - fi - # remove leading and trailing whitespace and commas from first and last line - # indent each line with 3 spaces for consistency - json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config") - printf ' ,%s\n' "$json" -fi -echo "}" -) | \ -require="__directory${conf_dir}" \ - __config_file "${conf_dir}/${conf_file}" \ - --owner root --group "$group" --mode 640 \ - --state "$state" \ - --onchange 'service consul status >/dev/null && service consul reload || true' \ - --source - +### +# LEGACY manual deployment, kept for compatibility reasons. init_sysvinit() { @@ -179,47 +122,186 @@ init_upstart() require="__file/etc/init/consul.conf" __start_on_boot consul } -# Install init script to start on boot -case "$os" in - alpine|devuan) - init_sysvinit debian - ;; - centos|redhat) - os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")" - major_version="${os_version%%.*}" - case "$major_version" in - [456]) - init_sysvinit redhat - ;; - 7) - init_systemd - ;; - *) - echo "Unsupported CentOS/Redhat version: $os_version" >&2 - exit 1 - ;; - esac - ;; +manual_setup () { + case "$os" in + alpine|scientific|centos|debian|devuan|redhat|ubuntu) + # whitelist safeguard + : + ;; + *) + echo "Your operating system ($os) is currently not supported by this \ + type (${__type##*/})." >&2 + echo "Please contribute an implementation for it if you can." >&2 + exit 1 + ;; + esac - debian) - os_version=$(cat "$__global/explorer/os_version") - major_version="${os_version%%.*}" + # FIXME: there has got to be a better way to handle the dependencies in this case + case "$state" in + present) + __group "$group" --system --state "$state" + require="__group/$group" __user "$user" \ + --system --gid "$group" --home "$data_dir" --state "$state" + ;; + *) + echo "The $state state is not (yet?) supported by this type." >&2 + exit 1 + ;; + esac - case "$major_version" in - [567]) - init_sysvinit debian - ;; - [89]) - init_systemd - ;; - *) - echo "Unsupported Debian version $os_version" >&2 - exit 1 - ;; - esac - ;; + # Create data directory. + require="__user/consul" __directory "$data_dir" \ + --owner "$user" --group "$group" --mode 770 --state "$state" - ubuntu) - init_upstart + # Create config directory. + require="__user/consul" __directory "$conf_dir" \ + --parents --owner root --group "$group" --mode 750 --state "$state" + + # Install init script to start on boot + case "$os" in + devuan) + init_sysvinit debian + ;; + centos|redhat) + os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")" + major_version="${os_version%%.*}" + case "$major_version" in + [456]) + init_sysvinit redhat + ;; + 7) + init_systemd + ;; + *) + echo "Unsupported CentOS/Redhat version: $os_version" >&2 + exit 1 + ;; + esac + ;; + + debian) + os_version=$(cat "$__global/explorer/os_version") + major_version="${os_version%%.*}" + + case "$major_version" in + [567]) + init_sysvinit debian + ;; + [89]|10) + init_systemd + ;; + *) + echo "Unsupported Debian version $os_version" >&2 + exit 1 + ;; + esac + ;; + + ubuntu) + init_upstart + ;; + esac + + config_deployment_requires="__user/consul __directory/$conf_dir" +} + +### +# Trigger requested installation method. +if [ $use_distribution_package ]; then + distribution_setup +else + manual_setup +fi + +### +# Install TLS certificates. + +if [ -f "$__object/parameter/ca-file-source" ] || \ + [ -f "$__object/parameter/cert-file-source" ] || \ + [ -f "$__object/parameter/key-file-source" ]; then + + requires="$config_deployment_requires" __directory $tls_dir \ + --owner root --group "$group" --mode 750 --state "$state" + + # Append to service restart requirements. + restart_requires="$restart_requires __directory/$conf_dir/tls" +fi + +### +# Generate and deploy configuration. + +json_configuration=$( + echo "{" + + # parameters we define ourself + printf ' "data_dir": "%s"\n' "$data_dir" + + cd "$__object/parameter/" + for param in *; do + case "$param" in + state|user|group|json-config|use-distribution-package) continue ;; + ca-file-source|cert-file-source|key-file-source) + source="$(cat "$__object/parameter/$param")" + destination="$tls_dir/${source##*/}" + require="__directory/$tls_dir" \ + __file "$destination" \ + --owner root --group consul --mode 640 \ + --source "$source" \ + --state "$state" + key="$(echo "${param%-*}" | tr '-' '_')" + printf ' ,"%s": "%s"\n' "$key" "$destination" ;; -esac + disable-remote-exec|disable-update-check|leave-on-terminate\ + |rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing) + # handle boolean parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": true\n' "$key" + ;; + retry-join) + # join multiple parameters into json array + retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")" + # remove trailing , + printf ' ,"retry_join": [%s]\n' "${retry_join%*,}" + ;; + retry-join-wan) + # join multiple parameters into json array over wan + retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")" + # remove trailing , + printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}" + ;; + bootstrap-expect) + # integer key=value parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + *) + # string key=value parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + esac + done + if [ -f "$__object/parameter/json-config" ]; then + json_config="$(cat "$__object/parameter/json-config")" + if [ "$json_config" = "-" ]; then + json_config="$__object/stdin" + fi + # remove leading and trailing whitespace and commas from first and last line + # indent each line with 3 spaces for consistency + json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config") + printf ' ,%s\n' "$json" + fi + echo "}" +) +echo "$json_configuration" | require="$config_deployment_requires" \ + __file "$conf_dir/$conf_file" \ + --owner root --group "$group" --mode 640 \ + --state "$state" \ + --source - + +# Set configuration deployment as requirement for service restart. +restart_requires="__file/$conf_dir/$conf_file" + +### +# Restart consul agent after everything else. +require="$restart_requires" __service consul --action restart diff --git a/cdist/conf/type/__consul_agent/parameter/boolean b/cdist/conf/type/__consul_agent/parameter/boolean index 91f7f17e..c86853c3 100644 --- a/cdist/conf/type/__consul_agent/parameter/boolean +++ b/cdist/conf/type/__consul_agent/parameter/boolean @@ -6,3 +6,4 @@ server enable-syslog verify-incoming verify-outgoing +use-distribution-package diff --git a/cdist/conf/type/__consul_check/explorer/conf-dir b/cdist/conf/type/__consul_check/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_check/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_check/manifest b/cdist/conf/type/__consul_check/manifest index c9f7add9..522aa1a9 100755 --- a/cdist/conf/type/__consul_check/manifest +++ b/cdist/conf/type/__consul_check/manifest @@ -19,7 +19,7 @@ # name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="check_${name}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_service/explorer/conf-dir b/cdist/conf/type/__consul_service/explorer/conf-dir new file mode 100644 index 00000000..0fc9ef84 --- /dev/null +++ b/cdist/conf/type/__consul_service/explorer/conf-dir @@ -0,0 +1,15 @@ +# Determine the configuration directory used by consul. + +check_dir () { + if [ -d "$1" ]; then + printf '%s' "$1" + exit + fi +} + +check_dir '/etc/consul/conf.d' +check_dir '/etc/consul.d' +check_dir '/etc/consul' + +echo 'Could not determine consul configuration dir. Exiting.' >&2 +exit 1 diff --git a/cdist/conf/type/__consul_service/manifest b/cdist/conf/type/__consul_service/manifest index 60397db7..d16f18e0 100755 --- a/cdist/conf/type/__consul_service/manifest +++ b/cdist/conf/type/__consul_service/manifest @@ -19,7 +19,7 @@ # name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="service_${name}.json" state="$(cat "$__object/parameter/state")" @@ -45,7 +45,7 @@ printf ' "name": "%s"\n' "$name" cd "$__object/parameter/" for param in *; do case "$param" in - state|name|check-interval) continue ;; + state|name|check-interval|conf-dir) continue ;; check-script) printf ' ,"check": {\n' printf ' "script": "%s"\n' "$(cat "$__object/parameter/check-script")" @@ -86,7 +86,6 @@ echo " }" # end json file echo "}" ) | \ -require="__directory${conf_dir}" \ __config_file "${conf_dir}/${conf_file}" \ --owner root --group consul --mode 640 \ --state "$state" \ diff --git a/cdist/conf/type/__consul_watch_checks/explorer/conf-dir b/cdist/conf/type/__consul_watch_checks/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_checks/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_checks/manifest b/cdist/conf/type/__consul_watch_checks/manifest index 5fdd7a74..4976b25a 100755 --- a/cdist/conf/type/__consul_watch_checks/manifest +++ b/cdist/conf/type/__consul_watch_checks/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_event/explorer/conf-dir b/cdist/conf/type/__consul_watch_event/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_event/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_event/manifest b/cdist/conf/type/__consul_watch_event/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_event/manifest +++ b/cdist/conf/type/__consul_watch_event/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_key/explorer/conf-dir b/cdist/conf/type/__consul_watch_key/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_key/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_key/manifest b/cdist/conf/type/__consul_watch_key/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_key/manifest +++ b/cdist/conf/type/__consul_watch_key/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir b/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_keyprefix/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_keyprefix/manifest b/cdist/conf/type/__consul_watch_keyprefix/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_keyprefix/manifest +++ b/cdist/conf/type/__consul_watch_keyprefix/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir b/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_nodes/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_nodes/manifest b/cdist/conf/type/__consul_watch_nodes/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_nodes/manifest +++ b/cdist/conf/type/__consul_watch_nodes/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_service/explorer/conf-dir b/cdist/conf/type/__consul_watch_service/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_service/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_service/manifest b/cdist/conf/type/__consul_watch_service/manifest index db38eb18..e8d18328 100755 --- a/cdist/conf/type/__consul_watch_service/manifest +++ b/cdist/conf/type/__consul_watch_service/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__consul_watch_services/explorer/conf-dir b/cdist/conf/type/__consul_watch_services/explorer/conf-dir new file mode 120000 index 00000000..daa712c3 --- /dev/null +++ b/cdist/conf/type/__consul_watch_services/explorer/conf-dir @@ -0,0 +1 @@ +../../__consul_service/explorer/conf-dir \ No newline at end of file diff --git a/cdist/conf/type/__consul_watch_services/manifest b/cdist/conf/type/__consul_watch_services/manifest index 61934656..b17680c1 100755 --- a/cdist/conf/type/__consul_watch_services/manifest +++ b/cdist/conf/type/__consul_watch_services/manifest @@ -20,7 +20,7 @@ cdist_type="${__type##*/}" watch_type="${cdist_type##*_}" -conf_dir="/etc/consul/conf.d" +conf_dir=$(cat "$__object/explorer/conf-dir") conf_file="watch_${watch_type}_${__object_id}.json" state="$(cat "$__object/parameter/state")" diff --git a/cdist/conf/type/__cron/gencode-remote b/cdist/conf/type/__cron/gencode-remote index 59398058..9debbc47 100755 --- a/cdist/conf/type/__cron/gencode-remote +++ b/cdist/conf/type/__cron/gencode-remote @@ -31,24 +31,28 @@ if [ -f "$__object/parameter/raw" ]; then elif [ -f "$__object/parameter/raw_command" ]; then entry="$command" else - minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")" - hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")" - day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")" - month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")" - day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")" + minute="$(cat "$__object/parameter/minute")" + hour="$(cat "$__object/parameter/hour")" + day_of_month="$(cat "$__object/parameter/day_of_month")" + month="$(cat "$__object/parameter/month")" + day_of_week="$(cat "$__object/parameter/day_of_week")" entry="$minute $hour $day_of_month $month $day_of_week $command # $name" fi mkdir "$__object/files" echo "$entry" > "$__object/files/entry" -if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then - state_is=present +if [ -s "$__object/explorer/entry" ]; then + if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then + state_is=present + else + state_is=modified + fi else state_is=absent fi -state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")" +state_should="$(cat "$__object/parameter/state")" [ "$state_is" = "$state_should" ] && exit 0 diff --git a/cdist/conf/type/__cron/manifest b/cdist/conf/type/__cron/manifest index 53973e07..e7b51863 100755 --- a/cdist/conf/type/__cron/manifest +++ b/cdist/conf/type/__cron/manifest @@ -22,3 +22,12 @@ if [ -f "$__object/parameter/raw" ] && [ -f "$__object/parameter/raw_command" ]; echo "ERROR: both raw and raw_command specified" >&2 exit 1 fi + +case "$(cat "$__object/parameter/state")" in + present) ;; + absent) ;; + + *) + echo "ERROR: unkown cron state" >&2 + exit 2 +esac diff --git a/cdist/conf/type/__cron/parameter/default/day_of_month b/cdist/conf/type/__cron/parameter/default/day_of_month new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/day_of_month @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/day_of_week b/cdist/conf/type/__cron/parameter/default/day_of_week new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/day_of_week @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/hour b/cdist/conf/type/__cron/parameter/default/hour new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/hour @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/minute b/cdist/conf/type/__cron/parameter/default/minute new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/minute @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/month b/cdist/conf/type/__cron/parameter/default/month new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/month @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__cron/parameter/default/state b/cdist/conf/type/__cron/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__cron/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__directory/explorer/stat b/cdist/conf/type/__directory/explorer/stat index 03d466ba..105d894f 100755 --- a/cdist/conf/type/__directory/explorer/stat +++ b/cdist/conf/type/__directory/explorer/stat @@ -1,6 +1,7 @@ #!/bin/sh # # 2013 Steven Armstrong (steven-cdist armstrong.cc) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -20,24 +21,43 @@ destination="/$__object_id" +fallback() { + # Patch the output together, manually + + ls_line=$(ls -ldn "$destination") + + uid=$(echo "$ls_line" | awk '{ print $3 }') + gid=$(echo "$ls_line" | awk '{ print $4 }') + + owner=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/passwd) + group=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) + + mode_text=$(echo "$ls_line" | awk '{ print $1 }') + mode=$(echo "$mode_text" | awk '{ k=0; for (i=0; i<=8; i++) k += ((substr($1, i+2, 1) ~ /[rwx]/) * 2^(8-i)); printf("%0o", k) }') + + printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\n' \ + "$("$__type_explorer/type")" \ + "$uid" "$owner" \ + "$gid" "$group" \ + "$mode" "$mode_text" +} + # nothing to work with, nothing we could do [ -e "$destination" ] || exit 0 -os=$("$__explorer/os") -case "$os" in +if ! command -v stat >/dev/null +then + fallback + exit +fi + +case $("$__explorer/os") in "freebsd"|"netbsd"|"openbsd"|"macosx") stat -f "type: %HT owner: %Du %Su group: %Dg %Sg mode: %Lp %Sp -" "$destination" | awk '/^type/ { print tolower($0); next; } { print; }' - ;; - alpine) - stat -c "type: %F -owner: %u %U -group: %g %G -mode: %a %A -" "$destination" +" "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; solaris) ls1="$( ls -ld "$destination" )" @@ -69,10 +89,12 @@ mode: %a %A echo "mode: $octets $( echo "$ls1" | awk '{print $1}' )" ;; *) - stat --printf="type: %F + # NOTE: Do not use --printf here as it is not supported by BusyBox stat. + # NOTE: BusyBox's stat might not support the "-c" option, in which case + # we fall through to the shell fallback. + stat -c "type: %F owner: %u %U group: %g %G -mode: %a %A -" "$destination" +mode: %a %A" "$destination" 2>/dev/null || fallback ;; esac diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote index 374db47a..a1a32ea2 100755 --- a/cdist/conf/type/__directory/gencode-remote +++ b/cdist/conf/type/__directory/gencode-remote @@ -3,6 +3,7 @@ # 2011-2013 Nico Schottelius (nico-cdist at schottelius.org) # 2013 Steven Armstrong (steven-cdist armstrong.cc) # 2014 Daniel Heule (hda at sfs.biz) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -21,8 +22,8 @@ # destination="/$__object_id" -state_should="$(cat "$__object/parameter/state")" -type="$(cat "$__object/explorer/type")" +state_should=$(cat "$__object/parameter/state") +type=$(cat "$__object/explorer/type") stat_file="$__object/explorer/stat" # variable to keep track if we have to set directory attributes @@ -72,7 +73,7 @@ set_mode() { } case "$state_should" in - present) + present|exists) if [ "$type" != "directory" ]; then set_attributes=1 if [ "$type" != "none" ]; then @@ -83,6 +84,10 @@ case "$state_should" in fi echo "mkdir $mkdiropt '$destination'" echo "create" >> "$__messages_out" + elif [ "$state_should" = 'exists' ]; then + # The type is directory and --state exists. We are done and do not + # check or set the attributes. + exit 0 fi # Note: Mode - needs to happen last as a chown/chgrp can alter mode by @@ -103,6 +108,26 @@ case "$state_should" in fi done ;; + pre-exists) + case $type in + directory) + # all good + exit 0 + ;; + none) + printf 'Directory "%s" does not exist\n' "$destination" >&2 + exit 1 + ;; + file|symlink) + printf 'File "%s" exists and is a %s, but should be a directory\n' "$destination" "$type" >&2 + exit 1 + ;; + *) + printf 'File or directory "%s" is in an unknown state\n' "$destination" >&2 + exit 1 + ;; + esac + ;; absent) if [ "$type" = "directory" ]; then echo "rm -rf '$destination'" diff --git a/cdist/conf/type/__directory/man.rst b/cdist/conf/type/__directory/man.rst index 74b00afe..7755334c 100644 --- a/cdist/conf/type/__directory/man.rst +++ b/cdist/conf/type/__directory/man.rst @@ -19,7 +19,18 @@ None. OPTIONAL PARAMETERS ------------------- state - 'present' or 'absent', defaults to 'present' + 'present', 'absent', 'exists' or 'pre-exists', defaults to 'present' where: + + present + the directory exists and the given attributes are set. + absent + the directory does not exist. + exists + the directory exists, but its attributes are not altered if it already + existed. + pre-exists + check that the directory exists and is indeed a directory, but do not + create or modify it. group Group to chgrp to. @@ -36,7 +47,7 @@ BOOLEAN PARAMETERS parents Whether to create parents as well (mkdir -p behaviour). Warning: all intermediate directory permissions default - to whatever mkdir -p does. + to whatever mkdir -p does. Usually this means root:root, 0700. diff --git a/cdist/conf/type/__file/explorer/stat b/cdist/conf/type/__file/explorer/stat index 13c1c208..91c8cc84 100755 --- a/cdist/conf/type/__file/explorer/stat +++ b/cdist/conf/type/__file/explorer/stat @@ -2,6 +2,7 @@ # # 2013 Steven Armstrong (steven-cdist armstrong.cc) # 2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -21,29 +22,54 @@ destination="/$__object_id" +fallback() { + # Fallback: Patch the output together, manually. + + ls_line=$(ls -ldn "$destination") + + uid=$(echo "$ls_line" | awk '{ print $3 }') + gid=$(echo "$ls_line" | awk '{ print $4 }') + + owner=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/passwd) + group=$(awk -F: -v uid="$uid" '$3 == uid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) + + mode_text=$(echo "$ls_line" | awk '{ print $1 }') + mode=$(echo "$mode_text" | awk '{ k=0; for (i=0; i<=8; i++) k += ((substr($1, i+2, 1) ~ /[rwx]/) * 2^(8-i)); printf("%0o", k) }') + + size=$(echo "$ls_line" | awk '{ print $5 }') + links=$(echo "$ls_line" | awk '{ print $2 }') + + printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\nsize: %d\nlinks: %d\n' \ + "$("$__type_explorer/type")" \ + "$uid" "$owner" \ + "$gid" "$group" \ + "$mode" "$mode_text" \ + "$size" \ + "$links" +} + + # nothing to work with, nothing we could do [ -e "$destination" ] || exit 0 -os=$("$__explorer/os") -case "$os" in - "freebsd"|"netbsd"|"openbsd"|"macosx") + +if ! command -v stat >/dev/null +then + fallback + exit +fi + + +case $("$__explorer/os") +in + freebsd|netbsd|openbsd|macosx) stat -f "type: %HT owner: %Du %Su group: %Dg %Sg mode: %Lp %Sp size: %Dz links: %Dl -" "$destination" | awk '/^type/ { print tolower($0); next; } { print; }' - ;; - alpine) - # busybox stat - stat -c "type: %F -owner: %u %U -group: %g %G -mode: %a %A -size: %s -links: %h -" "$destination" +" "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; solaris) ls1="$( ls -ld "$destination" )" @@ -77,12 +103,14 @@ links: %h echo "links: $( echo "$ls1" | awk '{print $2}' )" ;; *) - stat --printf="type: %F + # NOTE: Do not use --printf here as it is not supported by BusyBox stat. + # NOTE: BusyBox's stat might not support the "-c" option, in which case + # we fall through to the shell fallback. + stat -c "type: %F owner: %u %U group: %g %G mode: %a %A size: %s -links: %h -" "$destination" - ;; +links: %h" "$destination" 2>/dev/null || fallback + ;; esac diff --git a/cdist/conf/type/__file/gencode-local b/cdist/conf/type/__file/gencode-local index fb9f9a92..231b6927 100755 --- a/cdist/conf/type/__file/gencode-local +++ b/cdist/conf/type/__file/gencode-local @@ -31,12 +31,24 @@ if [ "$state_should" = "pre-exists" ]; then exit 1 fi - if [ "$type" = "file" ]; then - exit 0 # nothing to do - else - echo "File \"$destination\" does not exist" - exit 1 - fi + case $type in + file) + # nothing to do + exit 0 + ;; + none) + printf 'File "%s" does not exist\n' "$destination" >&2 + exit 1 + ;; + directory|symlink) + printf 'File "%s" exists and is a %s, but should be a regular file\n' "$destination" "$type" >&2 + exit 1 + ;; + *) + printf 'File or directory "%s" is in an unknown state\n' "$destination" >&2 + exit 1 + ;; + esac fi upload_file= diff --git a/cdist/conf/type/__file/gencode-remote b/cdist/conf/type/__file/gencode-remote index b04c471e..815593bd 100755 --- a/cdist/conf/type/__file/gencode-remote +++ b/cdist/conf/type/__file/gencode-remote @@ -55,37 +55,41 @@ set_owner() { } set_mode() { - echo "chmod '$1' '$destination'" - echo "chmod '$1'" >> "$__messages_out" - fire_onchange=1 + echo "chmod '$1' '$destination'" + echo "chmod '$1'" >> "$__messages_out" + fire_onchange=1 } case "$state_should" in - present|exists|pre-exists) - # Note: Mode - needs to happen last as a chown/chgrp can alter mode by - # clearing S_ISUID and S_ISGID bits (see chown(2)) - for attribute in group owner mode; do - if [ -f "$__object/parameter/$attribute" ]; then - value_should="$(cat "$__object/parameter/$attribute")" + present|exists) + # Note: Mode - needs to happen last as a chown/chgrp can alter mode by + # clearing S_ISUID and S_ISGID bits (see chown(2)) + for attribute in group owner mode; do + if [ -f "$__object/parameter/$attribute" ]; then + value_should="$(cat "$__object/parameter/$attribute")" - # change 0xxx format to xxx format => same as stat returns - if [ "$attribute" = mode ]; then - value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')" - fi - - value_is="$(get_current_value "$attribute" "$value_should")" - if [ -f "$__object/files/set-attributes" ] || [ "$value_should" != "$value_is" ]; then - "set_$attribute" "$value_should" + # change 0xxx format to xxx format => same as stat returns + if [ "$attribute" = mode ]; then + value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')" + fi + + value_is="$(get_current_value "$attribute" "$value_should")" + if [ -f "$__object/files/set-attributes" ] || [ "$value_should" != "$value_is" ]; then + "set_$attribute" "$value_should" + fi fi + done + if [ -f "$__object/files/set-attributes" ]; then + # set-attributes is created if file is created or uploaded in gencode-local + fire_onchange=1 fi - done - if [ -f "$__object/files/set-attributes" ]; then - # set-attributes is created if file is created or uploaded in gencode-local - fire_onchange=1 - fi - ;; + pre-exists) + # pre-exists should never reach gencode-remote… + exit 1 + ;; + absent) if [ "$type" = "file" ]; then echo "rm -f '$destination'" @@ -101,7 +105,7 @@ case "$state_should" in esac if [ -f "$__object/parameter/onchange" ]; then - if [ -n "$fire_onchange" ]; then - cat "$__object/parameter/onchange" - fi + if [ -n "$fire_onchange" ]; then + cat "$__object/parameter/onchange" + fi fi diff --git a/cdist/conf/type/__install_chroot_umount/manifest b/cdist/conf/type/__install_chroot_umount/manifest new file mode 120000 index 00000000..f17af67a --- /dev/null +++ b/cdist/conf/type/__install_chroot_umount/manifest @@ -0,0 +1 @@ +../__chroot_umount/manifest \ No newline at end of file diff --git a/cdist/conf/type/__letsencrypt_cert/man.rst b/cdist/conf/type/__letsencrypt_cert/man.rst index c4ffc6bc..85eb88ea 100644 --- a/cdist/conf/type/__letsencrypt_cert/man.rst +++ b/cdist/conf/type/__letsencrypt_cert/man.rst @@ -59,13 +59,13 @@ MESSAGES -------- change - Certificte was changed. + Certificate was changed. create - Certificte was created. + Certificate was created. remove - Certificte was removed. + Certificate was removed. EXAMPLES -------- diff --git a/cdist/conf/type/__line/explorer/state b/cdist/conf/type/__line/explorer/state index 2ef252c8..e8fc3630 100755 --- a/cdist/conf/type/__line/explorer/state +++ b/cdist/conf/type/__line/explorer/state @@ -1,6 +1,7 @@ #!/bin/sh -e # # 2018 Steven Armstrong (steven-cdist at armstrong.cc) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -18,6 +19,14 @@ # along with cdist. If not, see . # +if [ -f "$__object/parameter/file" ]; then + file=$(cat "$__object/parameter/file") +else + file="/$__object_id" +fi + +[ -f "$file" ] || exit 0 + if [ -f "$__object/parameter/before" ]; then position="before" elif [ -f "$__object/parameter/after" ]; then @@ -33,63 +42,56 @@ else needle="line" fi -if [ -f "$__object/parameter/file" ]; then - file="$(cat "$__object/parameter/file")" -else - file="/$__object_id" -fi - -if [ ! -f "$file" ]; then - echo "file_missing" - exit 0 -fi - awk -v position="$position" -v needle="$needle" ' function _find(_text, _pattern) { if (needle == "regex") { return match(_text, _pattern) } else { - return index(_text, _pattern) + return index(_text, _pattern) == 1 } } BEGIN { getline anchor < (ENVIRON["__object"] "/parameter/" position) getline pattern < (ENVIRON["__object"] "/parameter/" needle) - state = "absent" + + found_line = 0 + correct_pos = (position != "after" && position != "before") } { if (position == "after") { if (match($0, anchor)) { getline if (_find($0, pattern)) { - state = "present" + found_line++ + correct_pos = 1 + exit 0 } - else { - state = "wrongposition" - } - exit 0 + } else if (_find($0, pattern)) { + found_line++ } - } - else if (position == "before") { + } else if (position == "before") { if (_find($0, pattern)) { + found_line++ getline if (match($0, anchor)) { - state = "present" + correct_pos = 1 + exit 0 } - else { - state = "wrongposition" - } - exit 0 } - } - else { + } else { if (_find($0, pattern)) { - state = "present" + found_line++ exit 0 } } } END { - print state + if (found_line && correct_pos) { + print "present" + } else if (found_line) { + print "wrongposition" + } else { + print "absent" + } } ' "$file" diff --git a/cdist/conf/type/__line/gencode-remote b/cdist/conf/type/__line/gencode-remote index 03e90c1b..88cae68b 100755 --- a/cdist/conf/type/__line/gencode-remote +++ b/cdist/conf/type/__line/gencode-remote @@ -1,6 +1,7 @@ #!/bin/sh -e # # 2018 Steven Armstrong (steven-cdist at armstrong.cc) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -23,9 +24,20 @@ if [ -f "$__object/parameter/before" ] && [ -f "$__object/parameter/after" ]; th exit 1 fi +if [ -f "$__object/parameter/file" ]; then + file="$(cat "$__object/parameter/file")" +else + file="/$__object_id" +fi + state_should="$(cat "$__object/parameter/state")" state_is="$(cat "$__object/explorer/state")" +if [ -z "$state_is" ]; then + printf 'The file "%s" is missing. Please create it before using %s on it.\n' "$file" "${__type##*/}" >&2 + exit 1 +fi + if [ "$state_should" = "$state_is" ]; then # nothing to do exit 0 @@ -46,12 +58,6 @@ else needle="line" fi -if [ -f "$__object/parameter/file" ]; then - file="$(cat "$__object/parameter/file")" -else - file="/$__object_id" -fi - add=0 remove=0 case "$state_should" in @@ -104,10 +110,12 @@ BEGIN { if (anchor && match(\$0, anchor)) { if (position == "before") { print line + add = 0 print } else if (position == "after") { print print line + add = 0 } next } @@ -115,7 +123,7 @@ BEGIN { print } END { - if (add && position == "end") { + if (add) { print line } } diff --git a/cdist/conf/type/__mysql_database/explorer/state b/cdist/conf/type/__mysql_database/explorer/state new file mode 100755 index 00000000..79858695 --- /dev/null +++ b/cdist/conf/type/__mysql_database/explorer/state @@ -0,0 +1,33 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +if [ -f "$__object/parameter/name" ] +then + name="$( cat "$__object/parameter/name" )" +else + name="$__object_id" +fi + +if [ -n "$( mysql -B -N -e "show databases like '$name'" )" ] +then + echo 'present' +else + echo 'absent' +fi diff --git a/cdist/conf/type/__mysql_database/gencode-remote b/cdist/conf/type/__mysql_database/gencode-remote index 23e51b05..1bdb2b11 100755 --- a/cdist/conf/type/__mysql_database/gencode-remote +++ b/cdist/conf/type/__mysql_database/gencode-remote @@ -1,6 +1,6 @@ #!/bin/sh -e # -# 2012 Benedikt Koeppel (code@benediktkoeppel.ch) +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) # # This file is part of cdist. # @@ -17,38 +17,30 @@ # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # -# -# if --database was specified -if [ -f "$__object/parameter/name" ]; then - database="$(cat "$__object/parameter/name")" -else # otherwise use the object id as database name - database="$__object_id" +state_is="$( cat "$__object/explorer/state" )" + +state_should="$( cat "$__object/parameter/state" )" + +if [ "$state_is" = "$state_should" ] +then + exit 0 fi -cat <<-EOFF -mysql -u root <<-EOF - CREATE DATABASE IF NOT EXISTS $database -EOF -EOFF - -# if --user was specified -if [ -f "$__object/parameter/user" ]; then - user="$(cat "$__object/parameter/user")" - - # if --password was specified - if [ -f "$__object/parameter/password" ]; then - password="$(cat "$__object/parameter/password")" - cat <<-EOFF - mysql -u root <<-EOF - GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost' IDENTIFIED BY '$password'; -EOF -EOFF - else - cat <<-EOFF - mysql -u root <<-EOF - GRANT ALL PRIVILEGES ON $database.* to '$user'@'localhost'; -EOF -EOFF - fi +if [ -f "$__object/parameter/name" ] +then + name="$( cat "$__object/parameter/name" )" +else + name="$__object_id" fi + +case "$state_should" in + present) + echo "mysql -e 'create database \`$name\`'" + echo "create database $name" >> "$__messages_out" + ;; + absent) + echo "mysql -e 'drop database \`$name\`'" + echo "drop database $name" >> "$__messages_out" + ;; +esac diff --git a/cdist/conf/type/__mysql_database/man.rst b/cdist/conf/type/__mysql_database/man.rst index 1e245a08..b3b56b5f 100644 --- a/cdist/conf/type/__mysql_database/man.rst +++ b/cdist/conf/type/__mysql_database/man.rst @@ -8,24 +8,24 @@ cdist-type__mysql_database - Manage a MySQL database DESCRIPTION ----------- -This cdist type allows you to install a MySQL database. +Create MySQL database and optionally user with all privileges. -REQUIRED PARAMETERS -------------------- -None. OPTIONAL PARAMETERS ------------------- name - The name of the database to install - defaults to the object id + Name of database. Defaults to object id. user - A user that should have access to the database + Create user and give all privileges to database. password - The password for the user who manages the database + Password for user. + +state + Defaults to present. + If absent and user is also set, both will be removed (with privileges). EXAMPLES @@ -33,17 +33,23 @@ EXAMPLES .. code-block:: sh - __mysql_database "cdist" --name "cdist" --user "myuser" --password "mypwd" + # just create database + __mysql_database foo + + # create database with respective user with all privileges to database + __mysql_database bar \ + --user name \ + --password secret AUTHORS ------- -Benedikt Koeppel +Ander Punnar COPYING ------- -Copyright \(C) 2012 Benedikt Koeppel. 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. +Copyright \(C) 2020 Ander Punnar. 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. diff --git a/cdist/conf/type/__mysql_database/manifest b/cdist/conf/type/__mysql_database/manifest new file mode 100755 index 00000000..a3c9ed5d --- /dev/null +++ b/cdist/conf/type/__mysql_database/manifest @@ -0,0 +1,52 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +if [ -f "$__object/parameter/user" ] +then + user="$( cat "$__object/parameter/user" )" +fi + +if [ -f "$__object/parameter/password" ] +then + password="$( cat "$__object/parameter/password" )" +fi + +if [ -n "$user" ] && [ -n "$password" ] +then + if [ -f "$__object/parameter/name" ] + then + database="$( cat "$__object/parameter/name" )" + else + database="$__object_id" + fi + + state_should="$( cat "$__object/parameter/state" )" + + __mysql_user "$user" \ + --password "$password" \ + --state "$state_should" + + # removing user should remove all user's privileges + require="__mysql_user/$user" \ + __mysql_privileges "$database/$user" \ + --database "$database" \ + --user "$user" \ + --state "$state_should" +fi diff --git a/cdist/conf/type/__mysql_database/parameter/default/state b/cdist/conf/type/__mysql_database/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__mysql_database/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__mysql_database/parameter/optional b/cdist/conf/type/__mysql_database/parameter/optional index 756afee7..6c0b1e85 100644 --- a/cdist/conf/type/__mysql_database/parameter/optional +++ b/cdist/conf/type/__mysql_database/parameter/optional @@ -1,3 +1,4 @@ name user password +state diff --git a/cdist/conf/type/__mysql_privileges/explorer/state b/cdist/conf/type/__mysql_privileges/explorer/state new file mode 100755 index 00000000..4f13a70c --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/explorer/state @@ -0,0 +1,40 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +privileges="$( cat "$__object/parameter/privileges" )" + +database="$( cat "$__object/parameter/database" )" + +table="$( cat "$__object/parameter/table" )" + +user="$( cat "$__object/parameter/user" )" + +host="$( cat "$__object/parameter/host" )" + +check_privileges="$( + mysql -B -N -e "show grants for '$user'@'$host'" \ + | grep -Ei "^grant $privileges on .$database.\..?$table.? to " || true )" + +if [ -n "$check_privileges" ] +then + echo 'present' +else + echo 'absent' +fi diff --git a/cdist/conf/type/__mysql_privileges/gencode-remote b/cdist/conf/type/__mysql_privileges/gencode-remote new file mode 100755 index 00000000..0656699f --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/gencode-remote @@ -0,0 +1,55 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +state_is="$( cat "$__object/explorer/state" )" + +state_should="$( cat "$__object/parameter/state" )" + +if [ "$state_is" = "$state_should" ] +then + exit 0 +fi + +privileges="$( cat "$__object/parameter/privileges" )" + +database="$( cat "$__object/parameter/database" )" + +table="$( cat "$__object/parameter/table" )" + +user="$( cat "$__object/parameter/user" )" + +host="$( cat "$__object/parameter/host" )" + +if [ "$table" != '*' ] +then + # shellcheck disable=SC2016 + table="$( printf '`%s`' "$table" )" +fi + +case "$state_should" in + present) + echo "mysql -e 'grant $privileges on \`$database\`.$table to \`$user\`@\`$host\`'" + echo "grant $privileges on $database.$table to $user@$host" >> "$__messages_out" + ;; + absent) + echo "mysql -e 'revoke $privileges on \`$database\`.$table from \`$user\`@\`$host\`'" + echo "revoke $privileges on $database.$table from $user@$host" >> "$__messages_out" + ;; +esac diff --git a/cdist/conf/type/__mysql_privileges/man.rst b/cdist/conf/type/__mysql_privileges/man.rst new file mode 100644 index 00000000..b72c9eba --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/man.rst @@ -0,0 +1,57 @@ +cdist-type__mysql_privileges(7) +=============================== + +NAME +---- +cdist-type__mysql_privileges - Manage MySQL privileges + + +DESCRIPTION +----------- + +Grant and revoke privileges of MySQL user. + + +REQUIRED PARAMETERS +------------------- +database + Name of database. + +user + Name of user. + + +OPTIONAL PARAMETERS +------------------- +privileges + Defaults to "all". + +table + Defaults to "*". + +host + Defaults to localhost. + +state + "present" grants and "absent" revokes. Defaults to present. + + +EXAMPLES +-------- + +.. code-block:: sh + + __mysql_privileges user-to-db --database db --user user + + +AUTHORS +------- +Ander Punnar + + +COPYING +------- +Copyright \(C) 2020 Ander Punnar. 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. diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/host b/cdist/conf/type/__mysql_privileges/parameter/default/host new file mode 100644 index 00000000..2fbb50c4 --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/parameter/default/host @@ -0,0 +1 @@ +localhost diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/privileges b/cdist/conf/type/__mysql_privileges/parameter/default/privileges new file mode 100644 index 00000000..5472efad --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/parameter/default/privileges @@ -0,0 +1 @@ +all privileges diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/state b/cdist/conf/type/__mysql_privileges/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__mysql_privileges/parameter/default/table b/cdist/conf/type/__mysql_privileges/parameter/default/table new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/parameter/default/table @@ -0,0 +1 @@ +* diff --git a/cdist/conf/type/__mysql_privileges/parameter/optional b/cdist/conf/type/__mysql_privileges/parameter/optional new file mode 100644 index 00000000..d4ed5bc5 --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/parameter/optional @@ -0,0 +1,4 @@ +privileges +table +host +state diff --git a/cdist/conf/type/__mysql_privileges/parameter/required b/cdist/conf/type/__mysql_privileges/parameter/required new file mode 100644 index 00000000..152b4a1e --- /dev/null +++ b/cdist/conf/type/__mysql_privileges/parameter/required @@ -0,0 +1,2 @@ +database +user diff --git a/cdist/conf/type/__mysql_user/explorer/state b/cdist/conf/type/__mysql_user/explorer/state new file mode 100755 index 00000000..6817ee9d --- /dev/null +++ b/cdist/conf/type/__mysql_user/explorer/state @@ -0,0 +1,54 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +if [ -f "$__object/parameter/name" ] +then + name="$( cat "$__object/parameter/name" )" +else + name="$__object_id" +fi + +if [ -f "$__object/parameter/password" ] +then + password="$( cat "$__object/parameter/password" )" +else + password='' +fi + +host="$( cat "$__object/parameter/host" )" + +check_user="$( mysql -B -N -e "select user from mysql.user where user = '$name' and host = '$host'" )" + +if [ -n "$check_user" ] +then + if [ -n "$password" ] + then + check_password="$( mysql -B -N -e "select user from mysql.user where user = '$name' and host = '$host' and password = password( '$password' )" )" + fi + + if [ -n "$password" ] && [ -z "$check_password" ] + then + echo 'change-password' + else + echo 'present' + fi +else + echo 'absent' +fi diff --git a/cdist/conf/type/__mysql_user/gencode-remote b/cdist/conf/type/__mysql_user/gencode-remote new file mode 100755 index 00000000..5f13bc87 --- /dev/null +++ b/cdist/conf/type/__mysql_user/gencode-remote @@ -0,0 +1,68 @@ +#!/bin/sh -e +# +# 2020 Ander Punnar (ander-at-kvlt-dot-ee) +# +# 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 . +# + +state_is="$( cat "$__object/explorer/state" )" + +state_should="$( cat "$__object/parameter/state" )" + +if [ "$state_is" = "$state_should" ] +then + exit 0 +fi + +if [ -f "$__object/parameter/name" ] +then + name="$( cat "$__object/parameter/name" )" +else + name="$__object_id" +fi + +host="$( cat "$__object/parameter/host" )" + +if [ -f "$__object/parameter/password" ] +then + password="$( cat "$__object/parameter/password" )" +else + if [ "$state_should" = 'present' ] + then + echo '--password needed' >&2 + exit 1 + else + password='' + fi +fi + +if [ "$state_is" = 'absent' ] && [ "$state_should" = 'present' ] +then + echo "mysql -e 'create user \`$name\`@\`$host\` identified by \"$password\"'" + echo "create user $name@$host" >> "$__messages_out" + +elif [ "$state_is" != 'absent' ] && [ "$state_should" = 'absent' ] +then + echo "mysql -e 'drop user \`$name\`@\`$host\`'" + echo "drop user $name@$host" >> "$__messages_out" + +elif [ "$state_is" = 'change-password' ] +then + # this only works with MySQL 5.7.6 and later or MariaDB 10.1.20 and later + echo "mysql -e 'alter user \`$name\`@\`$host\` identified by \"$password\"'" + echo "mysql -e 'flush privileges'" + echo "change password $name@$host" >> "$__messages_out" +fi diff --git a/cdist/conf/type/__mysql_user/man.rst b/cdist/conf/type/__mysql_user/man.rst new file mode 100644 index 00000000..c2b222d5 --- /dev/null +++ b/cdist/conf/type/__mysql_user/man.rst @@ -0,0 +1,48 @@ +cdist-type__mysql_user(7) +========================= + +NAME +---- +cdist-type__mysql_user - Manage a MySQL user + + +DESCRIPTION +----------- + +Create MySQL user or change password for the user. + + +OPTIONAL PARAMETERS +------------------- +name + Name of user. Defaults to object id. + +host + Host of user. Defaults to localhost. + +password + Password of user. + +state + Defaults to present. + + +EXAMPLES +-------- + +.. code-block:: sh + + __mysql_user user --password secret + + +AUTHORS +------- +Ander Punnar + + +COPYING +------- +Copyright \(C) 2020 Ander Punnar. 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. diff --git a/cdist/conf/type/__mysql_user/parameter/default/host b/cdist/conf/type/__mysql_user/parameter/default/host new file mode 100644 index 00000000..2fbb50c4 --- /dev/null +++ b/cdist/conf/type/__mysql_user/parameter/default/host @@ -0,0 +1 @@ +localhost diff --git a/cdist/conf/type/__mysql_user/parameter/default/state b/cdist/conf/type/__mysql_user/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__mysql_user/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__mysql_user/parameter/optional b/cdist/conf/type/__mysql_user/parameter/optional new file mode 100644 index 00000000..a286266c --- /dev/null +++ b/cdist/conf/type/__mysql_user/parameter/optional @@ -0,0 +1,4 @@ +name +host +password +state diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote index 699eb0c9..e02564a2 100755 --- a/cdist/conf/type/__package_apt/gencode-remote +++ b/cdist/conf/type/__package_apt/gencode-remote @@ -74,6 +74,14 @@ fi case "$state_should" in present) + # following is bit ugly, but important hack. + # due to how cdist config run works, there isn't + # currently better way to do it :( + cat << EOF +if [ ! -f /var/cache/apt/pkgcache.bin ] || [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ] +then echo apt-get update > /dev/null 2>&1 || true +fi +EOF if [ -n "$version" ]; then name="${name}=${version}" fi diff --git a/cdist/conf/type/__package_apt/man.rst b/cdist/conf/type/__package_apt/man.rst index a3a70d91..a1691eac 100644 --- a/cdist/conf/type/__package_apt/man.rst +++ b/cdist/conf/type/__package_apt/man.rst @@ -11,6 +11,9 @@ DESCRIPTION apt-get is usually used on Debian and variants (like Ubuntu) to manage packages. +This type will also update package index, if it is older +than one day, to avoid missing package error messages. + REQUIRED PARAMETERS ------------------- diff --git a/cdist/conf/type/__postgres_database/gencode-remote b/cdist/conf/type/__postgres_database/gencode-remote index 61cfa50d..47e6b97c 100755 --- a/cdist/conf/type/__postgres_database/gencode-remote +++ b/cdist/conf/type/__postgres_database/gencode-remote @@ -41,12 +41,16 @@ if [ "$state_should" != "$state_is" ]; then present) owner="" if [ -f "$__object/parameter/owner" ]; then - owner="-O '$(cat "$__object/parameter/owner")'" + owner="-O \"$(cat "$__object/parameter/owner")\"" fi - echo "su - '$postgres_user' -c \"createdb $owner '$name'\"" + cat << EOF +su - '$postgres_user' -c "createdb $owner \"$name\"" +EOF ;; absent) - echo "su - '$postgres_user' -c \"dropdb '$name'\"" + cat << EOF +su - '$postgres_user' -c "dropdb \"$name\"" +EOF ;; esac fi diff --git a/cdist/conf/type/__postgres_role/gencode-remote b/cdist/conf/type/__postgres_role/gencode-remote index fd56e85d..282294c9 100755 --- a/cdist/conf/type/__postgres_role/gencode-remote +++ b/cdist/conf/type/__postgres_role/gencode-remote @@ -53,11 +53,13 @@ case "$state_should" in done [ -n "$password" ] && password="PASSWORD '$password'" - - cmd="CREATE ROLE $name WITH $password $booleans" - echo "su - '$postgres_user' -c \"psql postgres -wc \\\"$cmd\\\"\"" + cat << EOF +su - '$postgres_user' -c "psql postgres -wc \"CREATE ROLE \\\\\"$name\\\\\" WITH $password $booleans;\"" +EOF ;; absent) - echo "su - '$postgres_user' -c \"dropuser \\\"$name\\\"\"" + cat << EOF +su - '$postgres_user' -c "dropuser \"$name\"" +EOF ;; esac diff --git a/cdist/conf/type/__service/explorer/service-manager b/cdist/conf/type/__service/explorer/service-manager new file mode 100755 index 00000000..55a873fa --- /dev/null +++ b/cdist/conf/type/__service/explorer/service-manager @@ -0,0 +1,8 @@ +#!/bin/sh + +# Assume systemd if systemctl is in PATH. +if [ "$(command -v systemctl)" ]; then + printf "systemd" +else + printf "unknown" +fi diff --git a/cdist/conf/type/__service/gencode-remote b/cdist/conf/type/__service/gencode-remote new file mode 100755 index 00000000..ac62e05f --- /dev/null +++ b/cdist/conf/type/__service/gencode-remote @@ -0,0 +1,9 @@ +#!/bin/sh + +manager="$(cat "$__object/explorer/service-manager")" +name=$__object_id +action="$(cat "$__object/parameter/action")" + +if [ "$manager" = "unknown" ]; then + echo "service '$name' '$action'" +fi diff --git a/cdist/conf/type/__service/man.rst b/cdist/conf/type/__service/man.rst new file mode 100644 index 00000000..f9b23d5b --- /dev/null +++ b/cdist/conf/type/__service/man.rst @@ -0,0 +1,51 @@ +cdist-type__service(7) +====================== + +NAME +---- +cdist-type__service - Run action on a system service + + +DESCRIPTION +----------- +This type allows you to run an action against a system service. + + +REQUIRED PARAMETERS +------------------- +action + Arbitrary parameter passed as action. Usually 'start', 'stop', 'reload' or 'restart'. + +OPTIONAL PARAMETERS +------------------- +None. + + +BOOLEAN PARAMETERS +------------------ +None. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Restart nginx service. + __service nginx --action restart + + # Stop postfix service. + __service postfix --action stop + + +AUTHORS +------- +Timothée Floure + + +COPYING +------- +Copyright \(C) 2019 Timothée Floure. 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. diff --git a/cdist/conf/type/__service/manifest b/cdist/conf/type/__service/manifest new file mode 100644 index 00000000..cb5af234 --- /dev/null +++ b/cdist/conf/type/__service/manifest @@ -0,0 +1,15 @@ +#!/bin/sh + +manager="$(cat "$__object/explorer/service-manager")" + +name=$__object_id +action="$(cat "$__object/parameter/action")" + +case "$manager" in + systemd) + __systemd_service "$name" --action "$action" + ;; + *) + # Unknown: handled by `service $NAME $action` in gencode-remote. + ;; +esac diff --git a/cdist/conf/type/__service/parameter/required b/cdist/conf/type/__service/parameter/required new file mode 100644 index 00000000..a9f84d41 --- /dev/null +++ b/cdist/conf/type/__service/parameter/required @@ -0,0 +1 @@ +action diff --git a/cdist/conf/type/__systemd_service/explorer/state b/cdist/conf/type/__systemd_service/explorer/state new file mode 100755 index 00000000..f5f751d4 --- /dev/null +++ b/cdist/conf/type/__systemd_service/explorer/state @@ -0,0 +1,43 @@ +#!/bin/sh -e +# explorer/state +# +# 2020 Matthias Stecher +# +# 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 . +# + +# Check if the service is running or stopped. +# +# The explorer must check before if the service exist, because 'systemctl is-active' +# will return "inactive" even if there is no service there: +# systemctl cat foo # does not exist +# systemctl is-active foo # is "inactive" + + +# get name of the service +if [ -f "$__object/parameter/name" ]; then + name="$(cat "$__object/parameter/name")" +else + name="$__object_id" +fi + + +# check if the service exist, else exit without output (also if systemd doesn't exist) +# do not exit here with an error code, will be done in the gencode-remote script +systemctl cat "$name" > /dev/null 2>&1 || exit 0 + +# print if the service is running or not +systemctl is-active -q "$name" && printf "running" || printf "stopped" diff --git a/cdist/conf/type/__systemd_service/gencode-remote b/cdist/conf/type/__systemd_service/gencode-remote new file mode 100755 index 00000000..c867ff22 --- /dev/null +++ b/cdist/conf/type/__systemd_service/gencode-remote @@ -0,0 +1,98 @@ +#!/bin/sh -e +# gencode-remote +# +# 2020 Matthias Stecher +# +# 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 . +# + +# Checks the given state of the service and set it to the given +# state. Optionally, it executes the action if service running. + + +# get name of the service +name="$__object/parameter/name" +if [ -f "$name" ]; then + name="$(cat "$name")" +else + name="$__object_id" +fi + + +# read current status and parameters +state="$(cat "$__object/explorer/state")" +should="$(cat "$__object/parameter/state")" + +# if systemd/service does not exist +if [ -z "$state" ]; then + printf "systemd or service '%s' does not exist!\n" "$name" >&2 + exit 1 +fi + + +# save the action required +required_action="" + +# check the state of the service that should be +if [ "$state" != "$should" ]; then + # select what to do to get the $should state + case "$should" in + running) + if [ "$state" = "stopped" ]; then required_action="start"; fi + ;; + + stopped) + if [ "$state" = "running" ]; then required_action="stop"; fi + ;; + esac +fi + +# check if the action can be achieved if given +if [ -f "$__object/parameter/action" ] \ + && [ -z "$required_action" ] && [ "$state" = "running" ]; then + + # there must be an action + action="$(cat "$__object/parameter/action")" + + # select the action to the required element + case "$action" in + restart) + required_action="restart" + ;; + + reload) + required_action="reload" + ;; + + *) + printf "action '%s' does not exist!" "$action" >&2 + exit 2 + esac + + # Make a special check: only do this action if a dependency did something + # it is required that the dependencies write there action to $__messages_in + if [ -f "$__object/parameter/if-required" ]; then + # exit here if there are no changes from the dependencies affected (nothing to do) + if ! grep -q -f "$__object/require" "$__messages_in"; then exit 0; fi + fi +fi + +# print the execution command if a action given +if [ -n "$required_action" ]; then + # also print it as message + echo "$required_action" >> "$__messages_out" + echo "systemctl $required_action '$name'" +fi diff --git a/cdist/conf/type/__systemd_service/man.rst b/cdist/conf/type/__systemd_service/man.rst new file mode 100644 index 00000000..7eca398b --- /dev/null +++ b/cdist/conf/type/__systemd_service/man.rst @@ -0,0 +1,110 @@ +cdist-type__systemd-service(7) +============================== + +NAME +---- +cdist-type__systemd-service - Controls a systemd service state + +DESCRIPTION +----------- +This type controls systemd services to define a state of the service, +or an action like reloading or restarting. It is useful to reload a +service after configuration applied or shutdown one service. + +The activation or deactivation is out of scope. Look for the +:strong:`cdist-type__systemd_util`\ (7) type instead. + +REQUIRED PARAMETERS +------------------- + +None. + +OPTIONAL PARAMETERS +------------------- + +name + String which will used as name instead of the object id. + +state + The state which the service should be in: + + running + Service should run (default) + + stoppend + Service should stopped + +action + Executes an action on on the service. It will only execute it if the + service keeps the state **running**. There are following actions, where: + + reload + Reloads the service + + restart + Restarts the service + +BOOLEAN PARAMETERS +------------------ + +if-required + Only execute the action if minimum one required type outputs a message to + **$__messages_out**. Through this, the action should only executed if a + dependency did something. The action will not executed if no dependencies + given. + +MESSAGES +-------- + +start + Started the service + +stop + Stopped the service + +restart + Restarted the service + +reload + Reloaded the service + +ABORTS +------ +Aborts in following cases: + +systemd or the service does not exist + +EXAMPLES +-------- +.. code-block:: sh + + # service must run + __systemd_service nginx + + # service must stopped + __systemd_service sshd \ + --state stopped + + # restart the service + __systemd_service apache2 \ + --action restart + + # makes sure the service exist with an alternative name + __systemd_service foo \ + --name sshd + + # reload the service for a modified configuration file + # only reloads the service if the file really changed + require="__config_file/etc/foo.conf" __systemd_service foo \ + --action reload --if-required + +AUTHORS +------- +Matthias Stecher + +COPYRIGHT +--------- +Copyright \(C) 2020 Matthias Stecher. 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. diff --git a/cdist/conf/type/__systemd_service/parameter/boolean b/cdist/conf/type/__systemd_service/parameter/boolean new file mode 100644 index 00000000..a4bccb66 --- /dev/null +++ b/cdist/conf/type/__systemd_service/parameter/boolean @@ -0,0 +1 @@ +if-required diff --git a/cdist/conf/type/__systemd_service/parameter/default/state b/cdist/conf/type/__systemd_service/parameter/default/state new file mode 100644 index 00000000..a2ae71b3 --- /dev/null +++ b/cdist/conf/type/__systemd_service/parameter/default/state @@ -0,0 +1 @@ +running diff --git a/cdist/conf/type/__systemd_service/parameter/optional b/cdist/conf/type/__systemd_service/parameter/optional new file mode 100644 index 00000000..fc78265f --- /dev/null +++ b/cdist/conf/type/__systemd_service/parameter/optional @@ -0,0 +1,3 @@ +name +state +action diff --git a/cdist/conf/type/__update_alternatives/explorer/state b/cdist/conf/type/__update_alternatives/explorer/state new file mode 100755 index 00000000..04a78aaa --- /dev/null +++ b/cdist/conf/type/__update_alternatives/explorer/state @@ -0,0 +1,8 @@ +#!/bin/sh -e +path="$(cat "$__object/parameter/path")" +name="$__object_id" +link="$(readlink "/etc/alternatives/$name")" +if [ "$path" = "$link" ] +then echo present +else echo absent +fi diff --git a/cdist/conf/type/__update_alternatives/gencode-remote b/cdist/conf/type/__update_alternatives/gencode-remote index 0e7b0d89..c0b49814 100755 --- a/cdist/conf/type/__update_alternatives/gencode-remote +++ b/cdist/conf/type/__update_alternatives/gencode-remote @@ -17,9 +17,10 @@ # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # -# -# Setup alternative - no standard way to create, always set -# + +if [ "$(cat "$__object/explorer/state")" = 'present' ] +then exit 0 +fi path="$(cat "$__object/parameter/path")" name="$__object_id" diff --git a/cdist/conf/type/__user/explorer/shadow b/cdist/conf/type/__user/explorer/shadow index 73ce0e29..63d38f0d 100755 --- a/cdist/conf/type/__user/explorer/shadow +++ b/cdist/conf/type/__user/explorer/shadow @@ -24,7 +24,7 @@ name=$__object_id case $("$__explorer/os") in - 'freebsd'|'netbsd'|'openbsd') + 'freebsd'|'netbsd'|'openbsd'|'alpine') database='passwd' ;; # Default to using shadow passwords diff --git a/cdist/exec/local.py b/cdist/exec/local.py index f83c85df..ad6c6e36 100644 --- a/cdist/exec/local.py +++ b/cdist/exec/local.py @@ -69,7 +69,6 @@ class Local(object): self.exec_path = exec_path self.custom_initial_manifest = initial_manifest - self._add_conf_dirs = add_conf_dirs self.cache_path_pattern = cache_path_pattern self.quiet_mode = quiet_mode if configuration: @@ -84,16 +83,7 @@ class Local(object): self._init_cache_dir(None) self._init_paths() self._init_object_marker() - self._init_conf_dirs() - - @property - def dist_conf_dir(self): - return os.path.abspath(os.path.join(os.path.dirname(cdist.__file__), - "conf")) - - @property - def home_dir(self): - return cdist.home_dir() + self._init_conf_dirs(add_conf_dirs) def _init_log(self): self.log = logging.getLogger(self.target_host[0]) @@ -140,28 +130,9 @@ class Local(object): # Does not need to be secure - just randomly different from .cdist self.object_marker_name = tempfile.mktemp(prefix='.cdist-', dir='') - def _init_conf_dirs(self): - self.conf_dirs = [] - - self.conf_dirs.append(self.dist_conf_dir) - - # Is the default place for user created explorer, type and manifest - if self.home_dir: - self.conf_dirs.append(self.home_dir) - - # Add directories defined in the CDIST_PATH environment variable - # if 'CDIST_PATH' in os.environ: - # cdist_path_dirs = re.split(r'(?. +# +# + +import cdist +import cdist.configuration +import cdist.core +import cdist.exec.util as util +import os +import glob +import fnmatch + + +class Info(object): + + def __init__(self, conf_dirs, args): + self.conf_dirs = conf_dirs + self.all = args.all + self.display_global_explorers = args.global_explorers + self.display_types = args.types + if not self.display_global_explorers and not self.display_types: + self.all = True + self.fixed_string = args.fixed_string + self._setup_glob_pattern(args.pattern) + self.full = args.full + + def _setup_glob_pattern(self, pattern): + if pattern is None: + self.glob_pattern = '*' + elif ('?' in pattern or '*' in pattern or '[' in pattern or + self.fixed_string): + self.glob_pattern = pattern + else: + self.glob_pattern = '*' + pattern + '*' + + @classmethod + def commandline(cls, args): + conf_dirs = util.resolve_conf_dirs_from_config_and_args(args) + c = cls(conf_dirs, args) + c.run() + + def _get_global_explorers(self, conf_path): + rv = [] + global_explorer_path = os.path.join(conf_path, "explorer", + self.glob_pattern) + if self.fixed_string: + if os.path.exists(global_explorer_path): + rv.append(global_explorer_path) + else: + for explorer in glob.glob(global_explorer_path): + rv.append(explorer) + return rv + + def _should_display_type(self, dir_entry): + if not dir_entry.is_dir(): + return False + if self.glob_pattern is None: + return True + if self.fixed_string: + return dir_entry.name == self.glob_pattern + else: + return fnmatch.fnmatch(dir_entry.name, self.glob_pattern) + + def _get_types(self, conf_path): + rv = [] + types_path = os.path.join(conf_path, "type") + if not os.path.exists(types_path): + return rv + with os.scandir(types_path) as it: + for entry in it: + if self._should_display_type(entry): + rv.append(entry.path) + return rv + + def _display_details(self, title, details, default_values=None, + deprecated=None): + if not details: + return + if isinstance(details, bool): + print("\t{}: {}".format(title, 'yes' if details else 'no')) + elif isinstance(details, str): + print("\t{}: {}".format(title, details)) + elif isinstance(details, list): + dv = dict(default_values) if default_values else {} + dp = dict(deprecated) if deprecated else {} + + print("\t{}:".format(title)) + for x in sorted(details): + print("\t\t{}".format(x), end='') + has_default = x in dv + is_deprecated = x in dp + need_comma = False + if has_default or is_deprecated: + print(" (", end='') + if has_default: + print("default: {}".format(dv[x]), end='') + need_comma = True + if is_deprecated: + print("{}deprecated".format(', ' if need_comma else ''), + end='') + if has_default or is_deprecated: + print(")", end='') + print() + + def _display_type_parameters(self, cdist_type): + self._display_details("required parameters", + cdist_type.required_parameters, + default_values=cdist_type.parameter_defaults, + deprecated=cdist_type.deprecated_parameters) + self._display_details("required multiple parameters", + cdist_type.required_multiple_parameters, + default_values=cdist_type.parameter_defaults, + deprecated=cdist_type.deprecated_parameters) + self._display_details("optional parameters", + cdist_type.optional_parameters, + default_values=cdist_type.parameter_defaults, + deprecated=cdist_type.deprecated_parameters) + self._display_details("optional multiple parameters", + cdist_type.optional_multiple_parameters, + default_values=cdist_type.parameter_defaults, + deprecated=cdist_type.deprecated_parameters) + self._display_details("boolean parameters", + cdist_type.boolean_parameters, + default_values=cdist_type.parameter_defaults, + deprecated=cdist_type.deprecated_parameters) + + def _display_type_characteristics(self, cdist_type): + characteristics = [] + if cdist_type.is_install: + characteristics.append('install') + else: + characteristics.append('config') + if cdist_type.is_singleton: + characteristics.append('singleton') + if cdist_type.is_nonparallel: + characteristics.append('nonparallel') + else: + characteristics.append('parallel') + if cdist_type.deprecated is not None: + characteristics.append('deprecated') + print("\t{}".format(', '.join(characteristics))) + + def _display_type_details(self, type_path): + dirname, basename = os.path.split(type_path) + cdist_type = cdist.core.CdistType(dirname, basename) + + self._display_type_characteristics(cdist_type) + self._display_type_parameters(cdist_type) + + def run(self): + rv = [] + for cp in self.conf_dirs: + conf_path = os.path.expanduser(cp) + if self.all or self.display_global_explorers: + rv.extend((x, 'E', ) for x in self._get_global_explorers( + conf_path)) + if self.all or self.display_types: + rv.extend((x, 'T', ) for x in self._get_types(conf_path)) + rv = sorted(rv, key=lambda x: x[0]) + for x, t in rv: + print(x) + if self.full and t == 'T': + self._display_type_details(x) diff --git a/cdist/libexec.py b/cdist/libexec.py deleted file mode 100644 index bd22eb86..00000000 --- a/cdist/libexec.py +++ /dev/null @@ -1,45 +0,0 @@ -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) diff --git a/cdist/preos.py b/cdist/preos.py index 378071db..bf2a8e60 100644 --- a/cdist/preos.py +++ b/cdist/preos.py @@ -5,8 +5,9 @@ import inspect import argparse import cdist import logging -import re import cdist.argparse +import cdist.configuration +import cdist.exec.util as util _PREOS_CALL = "commandline" @@ -24,16 +25,6 @@ def extend_plugins_path(dirs): _PLUGINS_PATH.append(preos_dir) -cdist_home = cdist.home_dir() -if cdist_home: - extend_plugins_path((cdist_home, )) -x = 'CDIST_PATH' -if x in os.environ: - vals = re.split(r'(?`_. +`cdist-dump `_. For more info see: .. code-block:: sh - cdist_dump -h + cdist-dump -h Or from cdist git cloned directory: .. code-block:: sh - ./bin/cdist dump -h + ./scripts/cdist-dump -h diff --git a/docs/src/conf.py b/docs/src/conf.py index 78f9842c..47765413 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -56,7 +56,7 @@ master_doc = 'index' # General information about the project. project = 'cdist' -copyright = 'ungleich GmbH 2019' +copyright = 'ungleich GmbH 2020' # author = 'Darko Poljak' # The version info for the project you're documenting, acts as replacement for diff --git a/docs/src/index.rst b/docs/src/index.rst index 5e54d8fc..31c044dc 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -2,8 +2,9 @@ cdist - usable configuration management ======================================= cdist is a usable configuration management system. -It adheres to the KISS principle and +It adheres to the KISS principle and is being used in small up to enterprise grade environments. +It natively supports IPv6 since the first release. .. toctree:: diff --git a/docs/src/man1/cdist-dump.rst b/docs/src/man1/cdist-dump.rst index 5a73b4a8..907cd192 100644 --- a/docs/src/man1/cdist-dump.rst +++ b/docs/src/man1/cdist-dump.rst @@ -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 diff --git a/docs/src/man1/cdist.rst b/docs/src/man1/cdist.rst index 55db82ed..38248821 100644 --- a/docs/src/man1/cdist.rst +++ b/docs/src/man1/cdist.rst @@ -11,7 +11,7 @@ SYNOPSIS :: - cdist [-h] [-V] {banner,config,install,inventory,preos,shell} ... + cdist [-h] [-V] {banner,config,install,inventory,preos,shell,info} ... cdist banner [-h] [-l LOGLEVEL] [-q] [-v] @@ -59,7 +59,9 @@ SYNOPSIS [-I INVENTORY_DIR] [-a] [-f HOSTFILE] [-H] [-t] [host [host ...]] - cdist preos [-h] [-l LOGLEVEL] [-q] [-v] [-c CONF_DIR] [-L] [preos] ... + cdist preos [-h] [-l LOGLEVEL] [-q] [-v] [-c CONF_DIR] [-g CONFIG_FILE] + [-L] + [preos] ... cdist preos [preos-options] debian [-h] [-l LOGLEVEL] [-q] [-v] [-b] [-a ARCH] [-B] [-C] [-c CDIST_PARAMS] [-D DRIVE] [-e REMOTE_EXEC] @@ -84,6 +86,8 @@ SYNOPSIS cdist shell [-h] [-l LOGLEVEL] [-q] [-v] [-s SHELL] + cdist info [-h] [-a] [-c CONF_DIR] [-e] [-F] [-f] [-g CONFIG_FILE] [-t] [pattern] + DESCRIPTION ----------- @@ -462,6 +466,9 @@ Create PreOS. **-c CONF_DIR, --conf-dir CONF_DIR** Add configuration directory (one that contains "preos" subdirectory). +**-g CONFIG_FILE, --config-file CONFIG_FILE** + Use specified custom configuration file. + **-L, --list-preoses** List available PreOS-es. @@ -604,6 +611,39 @@ usage. Its primary use is for debugging type parameters. be POSIX compatible shell. +INFO +---- +Display information for cdist (global explorers, types). + +**pattern** + Glob pattern. If it contains special characters('?', '*', '[') then it is + used as specified, otherwise it is translated to `*pattern*`. + +**-h, --help** + Show help message and exit. + +**-a, --all** + Display all info. This is the default. + +**-c CONF_DIR, --conf-dir CONF_DIR** + Add configuration directory (can be repeated). + +**-e, --global-explorers** + Display info for global explorers. + +**-F, --fixed-string** + Interpret pattern as a fixed string. + +**-f, --full** + Display full details. + +**-g CONFIG_FILE, --config-file CONFIG_FILE** + Use specified custom configuration file. + +**-t, --types** + Display info for types. + + CONFIGURATION ------------- cdist obtains configuration data from the following sources in the following diff --git a/scripts/cdist b/scripts/cdist index 4fc74fb3..7bf12c01 100755 --- a/scripts/cdist +++ b/scripts/cdist @@ -30,20 +30,14 @@ import cdist.config import cdist.install import cdist.shell import cdist.inventory -import cdist.libexec as libexec def commandline(): """Parse command line""" - 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:]) - + # preos subcommand hack + if len(sys.argv) > 1 and sys.argv[1] == 'preos': + return cdist.preos.PreOS.commandline(sys.argv[1:]) parser, cfg = cdist.argparse.parse_and_configure(sys.argv[1:]) args = cfg.get_args() diff --git a/cdist/conf/libexec/cdist-dump b/scripts/cdist-dump similarity index 100% rename from cdist/conf/libexec/cdist-dump rename to scripts/cdist-dump diff --git a/cdist/conf/libexec/cdist-new-type b/scripts/cdist-new-type similarity index 100% rename from cdist/conf/libexec/cdist-new-type rename to scripts/cdist-new-type diff --git a/setup.py b/setup.py index 95ce9574..7b000041 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ setup( name="cdist", packages=["cdist", "cdist.core", "cdist.exec", "cdist.util", ], package_data={'cdist': package_data}, - scripts=["scripts/cdist", ], + scripts=["scripts/cdist", "scripts/cdist-dump", "scripts/cdist-new-type"], version=cdist.version.VERSION, description="A Usable Configuration Management System", author="Nico Schottelius",