diff --git a/Makefile b/Makefile
index b739ab1f..fa3327d1 100644
--- a/Makefile
+++ b/Makefile
@@ -31,9 +31,9 @@ help:
@echo "docs-clean clean documentation"
@echo "clean clean"
-DOCS_SRC_DIR=docs/src
-SPEECHDIR=docs/speeches
-TYPEDIR=cdist/conf/type
+DOCS_SRC_DIR=./docs/src
+SPEECHDIR=./docs/speeches
+TYPEDIR=./cdist/conf/type
SPHINXM=make -C $(DOCS_SRC_DIR) man
SPHINXH=make -C $(DOCS_SRC_DIR) html
diff --git a/cdist/conf/type/__acl/explorer/missing_users_groups b/cdist/conf/type/__acl/explorer/checks
similarity index 58%
rename from cdist/conf/type/__acl/explorer/missing_users_groups
rename to cdist/conf/type/__acl/explorer/checks
index b4af614c..70bb0412 100755
--- a/cdist/conf/type/__acl/explorer/missing_users_groups
+++ b/cdist/conf/type/__acl/explorer/checks
@@ -18,30 +18,22 @@
# along with cdist. If not, see .
#
-[ ! -e "/$__object_id" ] && exit 0
+# TODO check if filesystem has ACL turned on etc
-for parameter in user group
-do
- if [ ! -f "$__object/parameter/$parameter" ]
- then
- continue
- fi
-
- while read -r acl
+if [ -f "$__object/parameter/acl" ]
+then
+ grep -E '^(default:)?(user|group):' "$__object/parameter/acl" \
+ | while read -r acl
do
- check="$( echo "$acl" | awk -F: '{print $1}' )"
+ param="$( echo "$acl" | awk -F: '{print $(NF-2)}' )"
+ check="$( echo "$acl" | awk -F: '{print $(NF-1)}' )"
- if [ "$parameter" = 'user' ]
- then
- getent_db=passwd
- else
- getent_db="$parameter"
- fi
+ [ "$param" = 'user' ] && db=passwd || db="$param"
- if ! getent "$getent_db" "$check" > /dev/null
+ if ! getent "$db" "$check" > /dev/null
then
- echo "missing $parameter '$check'"
+ echo "missing $param '$check'" >&2
+ exit 1
fi
- done \
- < "$__object/parameter/$parameter"
-done
+ done
+fi
diff --git a/cdist/conf/type/__acl/gencode-remote b/cdist/conf/type/__acl/gencode-remote
index a0f25a15..6dab4d09 100755
--- a/cdist/conf/type/__acl/gencode-remote
+++ b/cdist/conf/type/__acl/gencode-remote
@@ -20,59 +20,65 @@
file_is="$( cat "$__object/explorer/file_is" )"
-[ "$file_is" = 'missing' ] && exit 0
-
-missing_users_groups="$( cat "$__object/explorer/missing_users_groups" )"
-
-if [ -n "$missing_users_groups" ]
-then
- echo "$missing_users_groups" >&2
- exit 1
-fi
+[ "$file_is" = 'missing' ] && [ -z "$__cdist_dry_run" ] && exit 0
os="$( cat "$__global/explorer/os" )"
-acl_is="$( cat "$__object/explorer/acl_is" )"
-
acl_path="/$__object_id"
-if [ -f "$__object/parameter/default" ] && [ "$file_is" = 'directory' ]
+acl_is="$( cat "$__object/explorer/acl_is" )"
+
+if [ -f "$__object/parameter/acl" ]
then
- set_default=1
+ acl_should="$( cat "$__object/parameter/acl" )"
+elif
+ [ -f "$__object/parameter/user" ] \
+ || [ -f "$__object/parameter/group" ] \
+ || [ -f "$__object/parameter/mask" ] \
+ || [ -f "$__object/parameter/other" ]
+then
+ acl_should="$( for param in user group mask other
+ do
+ [ ! -f "$__object/parameter/$param" ] && continue
+
+ echo "$param" | grep -Eq 'mask|other' && sep=:: || sep=:
+
+ echo "$param$sep$( cat "$__object/parameter/$param" )"
+ done )"
else
- set_default=0
+ echo 'no parameters set' >&2
+ exit 1
fi
-acl_should="$( for parameter in user group mask other
-do
- if [ ! -f "$__object/parameter/$parameter" ]
- then
- continue
- fi
+if [ -f "$__object/parameter/default" ]
+then
+ acl_should="$( echo "$acl_should" \
+ | sed 's/^default://' \
+ | sort -u \
+ | sed 's/\(.*\)/default:\1\n\1/' )"
+fi
- while read -r acl
- do
- if echo "$acl" | awk -F: '{ print $NF }' | grep -Fq 'X'
- then
- [ "$file_is" = 'directory' ] && rep=x || rep=-
+if [ "$file_is" = 'regular' ] \
+ && echo "$acl_should" | grep -Eq '^default:'
+then
+ # only directories can have default ACLs,
+ # but instead of error,
+ # let's just remove default entries
+ acl_should="$( echo "$acl_should" | grep -Ev '^default:' )"
+fi
- acl="$( echo "$acl" | sed "s/\(.*\)X/\1$rep/" )"
- fi
+if echo "$acl_should" | awk -F: '{ print $NF }' | grep -Fq 'X'
+then
+ [ "$file_is" = 'directory' ] && rep=x || rep=-
- echo "$parameter" | grep -Eq '(mask|other)' && sep=:: || sep=:
-
- echo "$parameter$sep$acl"
-
- [ "$set_default" = '1' ] && echo "default:$parameter$sep$acl"
- done \
- < "$__object/parameter/$parameter"
-done )"
+ acl_should="$( echo "$acl_should" | sed "s/\\(.*\\)X/\\1$rep/" )"
+fi
setfacl_exec='setfacl'
if [ -f "$__object/parameter/recursive" ]
then
- if echo "$os" | grep -Eq 'macosx|freebsd'
+ if echo "$os" | grep -Fq 'freebsd'
then
echo "$os setfacl do not support recursive operations" >&2
else
@@ -82,44 +88,36 @@ fi
if [ -f "$__object/parameter/remove" ]
then
- if echo "$os" | grep -Fq 'solaris'
- then
- # Solaris setfacl behaves differently.
- # We will not support Solaris for now, because no way to test it.
- # But adding support should be easy (use -s instead of -m on modify).
- echo "$os setfacl do not support -x flag for ACL remove" >&2
- else
- echo "$acl_is" | while read -r acl
- do
- # Skip wanted ACL entries which already exist
- # and skip mask and other entries, because we
- # can't actually remove them, but only change.
- if echo "$acl_should" | grep -Eq "^$acl" \
- || echo "$acl" | grep -Eq '^(default:)?(mask|other)'
- then continue
- fi
+ echo "$acl_is" | while read -r acl
+ do
+ # skip wanted ACL entries which already exist
+ # and skip mask and other entries, because we
+ # can't actually remove them, but only change.
+ if echo "$acl_should" | grep -Eq "^$acl" \
+ || echo "$acl" | grep -Eq '^(default:)?(mask|other)'
+ then continue
+ fi
- if echo "$os" | grep -Eq 'macosx|freebsd'
- then
- remove="$acl"
- else
- remove="$( echo "$acl" | sed 's/:...$//' )"
- fi
+ if echo "$os" | grep -Fq 'freebsd'
+ then
+ remove="$acl"
+ else
+ remove="$( echo "$acl" | sed 's/:...$//' )"
+ fi
- echo "$setfacl_exec -x \"$remove\" \"$acl_path\""
- echo "removed '$remove'" >> "$__messages_out"
- done
- fi
+ echo "$setfacl_exec -x \"$remove\" \"$acl_path\""
+ echo "removed '$remove'" >> "$__messages_out"
+ done
fi
for acl in $acl_should
do
if ! echo "$acl_is" | grep -Eq "^$acl"
then
- if echo "$os" | grep -Eq 'macosx|freebsd' \
+ if echo "$os" | grep -Fq 'freebsd' \
&& echo "$acl" | grep -Eq '^default:'
then
- echo "setting default ACL in $os is currently not supported. sorry :(" >&2
+ echo "setting default ACL in $os is currently not supported" >&2
else
echo "$setfacl_exec -m \"$acl\" \"$acl_path\""
echo "added '$acl'" >> "$__messages_out"
diff --git a/cdist/conf/type/__acl/man.rst b/cdist/conf/type/__acl/man.rst
index 092eb555..85e946ce 100644
--- a/cdist/conf/type/__acl/man.rst
+++ b/cdist/conf/type/__acl/man.rst
@@ -8,46 +8,36 @@ cdist-type__acl - Set ACL entries
DESCRIPTION
-----------
-ACL must be defined as 3-symbol combination, using ``r``, ``w``, ``x`` and ``-``.
-
-Fully supported on Linux (tested on Debian and CentOS).
-
-Partial support for FreeBSD, OSX and Solaris.
-
-OpenBSD and NetBSD support is not possible.
+Fully supported and tested on Linux (ext4 filesystem), partial support for FreeBSD.
See ``setfacl`` and ``acl`` manpages for more details.
-OPTIONAL MULTIPLE PARAMETERS
+REQUIRED MULTIPLE PARAMETERS
----------------------------
-user
- Add user ACL entry.
-
-group
- Add group ACL entry.
-
-
-OPTIONAL PARAMETERS
--------------------
-mask
- Add mask ACL entry.
-
-other
- Add other ACL entry.
+acl
+ Set ACL entry following ``getfacl`` output syntax.
BOOLEAN PARAMETERS
------------------
+default
+ Set all ACL entries as default too.
+ Only directories can have default ACLs.
+ Setting default ACL in FreeBSD is currently not supported.
+
recursive
Make ``setfacl`` recursive (Linux only), but not ``getfacl`` in explorer.
-default
- Add default ACL entries (FreeBSD not supported).
-
remove
- Remove undefined ACL entries (Solaris not supported).
- ACL entries for ``mask`` and ``other`` can't be removed.
+ Remove undefined ACL entries.
+ ``mask`` and ``other`` entries can't be removed, but only changed.
+
+
+DEPRECATED PARAMETERS
+---------------------
+Parameters ``user``, ``group``, ``mask`` and ``other`` are deprecated and they
+will be removed in future versions. Please use ``acl`` parameter instead.
EXAMPLES
@@ -56,15 +46,30 @@ EXAMPLES
.. code-block:: sh
__acl /srv/project \
+ --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
+
+ # 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
+
+ __acl /srv/project2/subdir \
--default \
--remove \
- --user alice:rwx \
- --user bob:r-x \
- --group project-group:rwx \
- --group some-other-group:r-x \
- --mask r-x \
- --other r-x
+ --acl group:secret-project:rwx \
+ --acl user:alice:r-x
AUTHORS
diff --git a/cdist/conf/type/__acl/parameter/deprecated/group b/cdist/conf/type/__acl/parameter/deprecated/group
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/group
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/mask b/cdist/conf/type/__acl/parameter/deprecated/mask
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/mask
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/other b/cdist/conf/type/__acl/parameter/deprecated/other
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/other
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/deprecated/user b/cdist/conf/type/__acl/parameter/deprecated/user
new file mode 100644
index 00000000..94e14159
--- /dev/null
+++ b/cdist/conf/type/__acl/parameter/deprecated/user
@@ -0,0 +1 @@
+see manual for details
diff --git a/cdist/conf/type/__acl/parameter/optional_multiple b/cdist/conf/type/__acl/parameter/optional_multiple
index 22f5a52c..95c25d55 100644
--- a/cdist/conf/type/__acl/parameter/optional_multiple
+++ b/cdist/conf/type/__acl/parameter/optional_multiple
@@ -1,2 +1,3 @@
+acl
user
group
diff --git a/cdist/conf/type/__apt_key/explorer/state b/cdist/conf/type/__apt_key/explorer/state
index f7940741..38f1bd3c 100755
--- a/cdist/conf/type/__apt_key/explorer/state
+++ b/cdist/conf/type/__apt_key/explorer/state
@@ -27,6 +27,18 @@ else
keyid="$__object_id"
fi
-apt-key export "$keyid" | head -n 1 | grep -Fqe "BEGIN PGP PUBLIC KEY BLOCK" \
- && echo present \
- || echo absent
+keydir="$(cat "$__object/parameter/keydir")"
+keyfile="$keydir/$__object_id.gpg"
+
+if [ -d "$keydir" ]
+then
+ if [ -f "$keyfile" ]
+ then echo present
+ else echo absent
+ fi
+else
+ # fallback to deprecated apt-key
+ apt-key export "$keyid" | head -n 1 | grep -Fqe "BEGIN PGP PUBLIC KEY BLOCK" \
+ && echo present \
+ || echo absent
+fi
diff --git a/cdist/conf/type/__apt_key/gencode-remote b/cdist/conf/type/__apt_key/gencode-remote
index 9c4fa00c..47c8bb49 100755
--- a/cdist/conf/type/__apt_key/gencode-remote
+++ b/cdist/conf/type/__apt_key/gencode-remote
@@ -31,12 +31,84 @@ if [ "$state_should" = "$state_is" ]; then
exit 0
fi
+keydir="$(cat "$__object/parameter/keydir")"
+keyfile="$keydir/$__object_id.gpg"
+
case "$state_should" in
present)
keyserver="$(cat "$__object/parameter/keyserver")"
- echo "apt-key adv --keyserver \"$keyserver\" --recv-keys \"$keyid\""
+
+ if [ -f "$__object/parameter/uri" ]; then
+ uri="$(cat "$__object/parameter/uri")"
+
+ if [ -d "$keydir" ]; then
+ cat << EOF
+
+curl -s -L \\
+ -o "$keyfile" \\
+ "$uri"
+
+if grep -Fq 'BEGIN PGP PUBLIC KEY BLOCK' \\
+ "$keyfile"
+then
+ cat "$keyfile" \\
+ | gpg --export > "$keyfile"
+fi
+
+EOF
+ else
+ # fallback to deprecated apt-key
+ echo "curl -s -L '$uri' | apt-key add -"
+ fi
+ elif [ -d "$keydir" ]; then
+ tmp='/tmp/cdist_apt_key_tmp'
+
+ # we need to kill gpg after 30 seconds, because gpg
+ # can get stuck if keyserver is not responding.
+ # exporting env var and not exit 1,
+ # because we need to clean up and kill dirmngr.
+ cat << EOF
+
+mkdir -m 700 -p "$tmp"
+
+if timeout 30s \\
+ gpg --homedir "$tmp" \\
+ --keyserver "$keyserver" \\
+ --recv-keys "$keyid"
+then
+ gpg --homedir "$tmp" \\
+ --export "$keyid" \\
+ > "$keyfile"
+else
+ export GPG_GOT_STUCK=1
+fi
+
+GNUPGHOME="$tmp" gpgconf --kill dirmngr
+
+rm -rf "$tmp"
+
+if [ -n "\$GPG_GOT_STUCK" ]
+then
+ echo "GPG GOT STUCK - no response from keyserver after 30 seconds" >&2
+ exit 1
+fi
+
+EOF
+ else
+ # fallback to deprecated apt-key
+ echo "apt-key adv --keyserver \"$keyserver\" --recv-keys \"$keyid\""
+ fi
+
+ echo "added '$keyid'" >> "$__messages_out"
;;
absent)
- echo "apt-key del \"$keyid\""
+ if [ -f "$keyfile" ]; then
+ echo "rm '$keyfile'"
+ else
+ # fallback to deprecated apt-key
+ echo "apt-key del \"$keyid\""
+ fi
+
+ echo "removed '$keyid'" >> "$__messages_out"
;;
esac
diff --git a/cdist/conf/type/__apt_key/man.rst b/cdist/conf/type/__apt_key/man.rst
index 9009877e..234bc715 100644
--- a/cdist/conf/type/__apt_key/man.rst
+++ b/cdist/conf/type/__apt_key/man.rst
@@ -28,6 +28,12 @@ keyserver
the keyserver from which to fetch the key. If omitted the default set
in ./parameter/default/keyserver is used.
+keydir
+ key save location, defaults to ``/etc/apt/trusted.pgp.d``
+
+uri
+ the URI from which to download the key
+
EXAMPLES
--------
@@ -47,15 +53,20 @@ EXAMPLES
# same thing with other keyserver
__apt_key UbuntuArchiveKey --keyid 437D05B5 --keyserver keyserver.ubuntu.com
+ # download key from the internet
+ __apt_key rabbitmq \
+ --uri http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
+
AUTHORS
-------
Steven Armstrong
+Ander Punnar
COPYING
-------
-Copyright \(C) 2011-2014 Steven Armstrong. 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
+Copyright \(C) 2011-2019 Steven Armstrong and 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_key/manifest b/cdist/conf/type/__apt_key/manifest
new file mode 100755
index 00000000..010357cd
--- /dev/null
+++ b/cdist/conf/type/__apt_key/manifest
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+
+__package gnupg
+
+if [ -f "$__object/parameter/uri" ]
+then __package curl
+else __package dirmngr
+fi
diff --git a/cdist/conf/type/__apt_key/parameter/default/keydir b/cdist/conf/type/__apt_key/parameter/default/keydir
new file mode 100644
index 00000000..190eb2de
--- /dev/null
+++ b/cdist/conf/type/__apt_key/parameter/default/keydir
@@ -0,0 +1 @@
+/etc/apt/trusted.gpg.d
diff --git a/cdist/conf/type/__apt_key/parameter/optional b/cdist/conf/type/__apt_key/parameter/optional
index 18cf2586..de647375 100644
--- a/cdist/conf/type/__apt_key/parameter/optional
+++ b/cdist/conf/type/__apt_key/parameter/optional
@@ -1,3 +1,5 @@
state
keyid
keyserver
+keydir
+uri
diff --git a/cdist/conf/type/__docker/manifest b/cdist/conf/type/__docker/manifest
index 04a9ff27..6a57d85a 100755
--- a/cdist/conf/type/__docker/manifest
+++ b/cdist/conf/type/__docker/manifest
@@ -64,6 +64,43 @@ case "$os" in
require="__apt_source/docker" __package docker-ce --state "${state}"
fi
;;
+ devuan)
+ os_version="$(cat "$__global/explorer/os_version")"
+
+ case "$os_version" in
+ ascii)
+ distribution="stretch"
+ ;;
+ jessie)
+ distribution="jessie"
+ ;;
+ *)
+ echo "Your devuan release ($os_version) is currently not supported by this type (${__type##*/}).">&2
+ echo "Please contribute an implementation for it if you can." >&2
+ exit 1
+ ;;
+ esac
+
+ if [ "${state}" = "present" ]; then
+ __package apt-transport-https
+ __package ca-certificates
+ __package gnupg2
+ fi
+ __apt_key_uri docker --name "Docker Release (CE deb) " \
+ --uri "https://download.docker.com/linux/${os}/gpg" --state "${state}"
+
+ require="__apt_key_uri/docker" __apt_source docker \
+ --uri "https://download.docker.com/linux/${os}" \
+ --distribution "${distribution}" \
+ --state "${state}" \
+ --component "stable"
+ if [ "$version" != "latest" ]; then
+ require="__apt_source/docker" __package docker-ce --version "${version}" --state "${state}"
+ else
+ require="__apt_source/docker" __package docker-ce --state "${state}"
+ fi
+
+ ;;
*)
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
diff --git a/cdist/conf/type/__docker_swarm/explorer/swarm-state b/cdist/conf/type/__docker_swarm/explorer/swarm-state
index 9c1bc32d..2c9fd598 100755
--- a/cdist/conf/type/__docker_swarm/explorer/swarm-state
+++ b/cdist/conf/type/__docker_swarm/explorer/swarm-state
@@ -18,4 +18,4 @@
# along with cdist. If not, see .
#
-docker info 2>/dev/null | grep "^Swarm: " | cut -d " " -f 2-
+docker info 2>/dev/null | grep '^ *Swarm: ' | awk '{print $2}'
diff --git a/cdist/conf/type/__grafana_dashboard/manifest b/cdist/conf/type/__grafana_dashboard/manifest
index 9cd1465d..e652202b 100755
--- a/cdist/conf/type/__grafana_dashboard/manifest
+++ b/cdist/conf/type/__grafana_dashboard/manifest
@@ -8,10 +8,12 @@ case $os in
debian|devuan)
case $os_version in
8*|jessie)
- apt_source_distribution=jessie
+ # Differntation not needed anymore
+ apt_source_distribution=stable
;;
9*|ascii/ceres|ascii)
- apt_source_distribution=stretch
+ # Differntation not needed anymore
+ apt_source_distribution=stable
;;
*)
echo "Don't know how to install Grafana on $os $os_version. Send us a pull request!" >&2
@@ -21,10 +23,10 @@ case $os in
__apt_key_uri grafana \
--name 'Grafana Release Signing Key' \
- --uri https://packagecloud.io/gpg.key
+ --uri https://packages.grafana.com/gpg.key
require="$require __apt_key_uri/grafana" __apt_source grafana \
- --uri https://packagecloud.io/grafana/stable/debian/ \
+ --uri https://packages.grafana.com/oss/deb \
--distribution $apt_source_distribution \
--component main
diff --git a/cdist/conf/type/__letsencrypt_cert/manifest b/cdist/conf/type/__letsencrypt_cert/manifest
index d6892c9b..d598949e 100755
--- a/cdist/conf/type/__letsencrypt_cert/manifest
+++ b/cdist/conf/type/__letsencrypt_cert/manifest
@@ -62,11 +62,12 @@ if [ -z "${certbot_fullpath}" ]; then
--distribution ascii-backports \
--component main
- require="__apt_source/ascii-backports" __package_apt python-certbot \
- --target-release ascii-backports
require="__apt_source/ascii-backports" __package_apt certbot \
--target-release ascii-backports
;;
+ bewoulf*)
+ __package_apt certbot
+ ;;
*)
echo "Unsupported OS version: $os_version" >&2
exit 1
diff --git a/cdist/config.py b/cdist/config.py
index 1a0ab4d5..26d07fc4 100644
--- a/cdist/config.py
+++ b/cdist/config.py
@@ -767,6 +767,16 @@ class Config(object):
deprecated)
else:
self.log.warning("Type %s is deprecated.", cdist_type.name)
+ for param in cdist_object.parameters:
+ if param in cdist_type.deprecated_parameters:
+ msg = cdist_type.deprecated_parameters[param]
+ if msg:
+ format = "%s parameter of type %s is deprecated: %s"
+ args = [param, cdist_type.name, msg]
+ else:
+ format = "%s parameter of type %s is deprecated."
+ args = [param, cdist_type.name]
+ self.log.warning(format, *args)
def object_prepare(self, cdist_object, transfer_type_explorers=True):
"""Prepare object: Run type explorer + manifest"""
diff --git a/cdist/core/cdist_type.py b/cdist/core/cdist_type.py
index 7cabd72f..4500f50d 100644
--- a/cdist/core/cdist_type.py
+++ b/cdist/core/cdist_type.py
@@ -69,6 +69,7 @@ class CdistType(object):
self.__optional_multiple_parameters = None
self.__boolean_parameters = None
self.__parameter_defaults = None
+ self.__deprecated_parameters = None
def __hash__(self):
return hash(self.name)
@@ -275,3 +276,23 @@ class CdistType(object):
finally:
self.__parameter_defaults = defaults
return self.__parameter_defaults
+
+ @property
+ def deprecated_parameters(self):
+ if not self.__deprecated_parameters:
+ deprecated = {}
+ try:
+ deprecated_dir = os.path.join(self.absolute_path,
+ "parameter",
+ "deprecated")
+ for name in cdist.core.listdir(deprecated_dir):
+ try:
+ with open(os.path.join(deprecated_dir, name)) as fd:
+ deprecated[name] = fd.read().strip()
+ except EnvironmentError:
+ pass # Swallow errors raised by open() or read()
+ except EnvironmentError:
+ pass # Swallow error raised by os.listdir()
+ finally:
+ self.__deprecated_parameters = deprecated
+ return self.__deprecated_parameters
diff --git a/cdist/test/cdist_type/__init__.py b/cdist/test/cdist_type/__init__.py
index ac84d874..a51a1e6f 100644
--- a/cdist/test/cdist_type/__init__.py
+++ b/cdist/test/cdist_type/__init__.py
@@ -200,3 +200,18 @@ class TypeTestCase(test.CdistTestCase):
self.assertEqual(
list(sorted(cdist_type.parameter_defaults.keys())),
['bar', 'foo'])
+
+ def test_without_deprecated_parameters(self):
+ base_path = fixtures
+ cdist_type = core.CdistType(base_path,
+ '__without_deprecated_parameters')
+ self.assertEqual(cdist_type.deprecated_parameters, {})
+
+ def test_with_deprecated_parameters(self):
+ base_path = fixtures
+ cdist_type = core.CdistType(base_path, '__with_deprecated_parameters')
+ self.assertTrue('eggs' in cdist_type.deprecated_parameters)
+ self.assertTrue('spam' in cdist_type.deprecated_parameters)
+ self.assertEqual(cdist_type.deprecated_parameters['eggs'],
+ 'Deprecated')
+ self.assertEqual(cdist_type.deprecated_parameters['spam'], '')
diff --git a/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/deprecated/eggs b/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/deprecated/eggs
new file mode 100644
index 00000000..69d9f456
--- /dev/null
+++ b/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/deprecated/eggs
@@ -0,0 +1 @@
+Deprecated
diff --git a/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/deprecated/spam b/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/deprecated/spam
new file mode 100644
index 00000000..e69de29b
diff --git a/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/optional b/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/optional
new file mode 100644
index 00000000..bfe09199
--- /dev/null
+++ b/cdist/test/cdist_type/fixtures/__with_deprecated_parameters/parameter/optional
@@ -0,0 +1,3 @@
+spam
+eggs
+sausage
diff --git a/docs/changelog b/docs/changelog
index ba092840..7594a6d4 100644
--- a/docs/changelog
+++ b/docs/changelog
@@ -1,7 +1,24 @@
Changelog
---------
-next:
+5.1.3: 2019-08-30
+ * Build: Overcome bash CDPATH when building docs (Dmitry Bogatov)
+ * Type __grafana_dashboard: Update distribution name, package signing key URI and repository URI (Dominique Roux)
+ * Type __letsencrypt_cert: Add Devuan Beowulf support (Nico Schottelius)
+ * Type __letsencrypt_cert: Fix Devuan Ascii: support (Nico Schottelius)
+ * Type __docker: Add devuan support (Dominique Roux)
+ * Type __docker_swarm: Fix for Docker 19.03 (Ľubomír Kučera)
+
+5.1.2: 2019-06-21
+ * Core: Add support for type parameters deprecation (Darko Poljak)
+ * Type __acl: Rewrite and improve (Ander Punnar)
+
+5.1.1: 2019-05-28
+ * Type __apt_key: Use gpg key, fallback to deprecated apt-key (Ander Punnar)
+ * Type __acl: Fix and improve (Ander Punnar)
+ * Documentation: Document type stdin inside loop caveats (Darko Poljak)
+
+5.1.0: 2019-05-22
* Type __consul: Add alpine support (Nico Schottelius)
* Type __consul: Add version 1.5.0 (Nico Schottelius)
* Type __consul_agent: Add alpine support (Nico Schottelius)
diff --git a/docs/src/cdist-type.rst b/docs/src/cdist-type.rst
index dfad6fa0..582c0938 100644
--- a/docs/src/cdist-type.rst
+++ b/docs/src/cdist-type.rst
@@ -74,7 +74,7 @@ prevents to be run in more than one instance.
Deprecated types
-----------------
If a type is flagged with 'deprecated' marker then it is considered deprecated.
-Upon it's usage cdist writes warning line. If 'deprecated' marker has content
+When it is used cdist writes warning line. If 'deprecated' marker has content
then this content is printed as a deprecation messages, e.g.:
.. code-block:: sh
@@ -186,6 +186,31 @@ Example: (e.g. in cdist/conf/type/__nginx_vhost/manifest)
fi
+Deprecated parameters
+---------------------
+To deprecate type parameters one can declare a file for each deprecated
+parameter under **parameter/deprecated** directory.
+
+When such parameter is used cdist writes warning line with deprecation message.
+If such file has content then this content is printed as deprecation message.
+If there is no content then generic parameter deprecation message is printed.
+
+Example:
+
+.. code-block:: sh
+
+ $ ls parameter/deprecated/
+ eggs spam
+ $ cat parameter/deprecated/eggs
+ eggs parameter is deprecated, please use multiple egg parameter.
+ $ cat parameter/deprecated/spam
+ $ echo '__foo foo --foo foo --eggs eggs' | ./bin/cdist config -i - 185.203.112.26
+ WARNING: 185.203.112.26: eggs parameter of type __foo is deprecated: eggs parameter is deprecated, please use multiple egg parameter.
+ $ echo '__foo foo --foo foo --eggs eggs --spam spam' | ./bin/cdist config -i - 185.203.112.26
+ WARNING: 185.203.112.26: spam parameter of type __foo is deprecated.
+ WARNING: 185.203.112.26: eggs parameter of type __foo is deprecated: eggs parameter is deprecated, please use multiple egg parameter.
+
+
Input from stdin
----------------
Every type can access what has been written on stdin when it has been called.
@@ -216,6 +241,73 @@ In the __file type, stdin is used as source for the file, if - is used for sourc
....
+Stdin inside a loop
+~~~~~~~~~~~~~~~~~~~
+Since cdist saves type's stdin content in the object as **$__object/stdin**,
+so it can be accessed in manifest and gencode-* scripts, this can lead to
+unexpected behavior. For example, suppose you have some type with the following
+in its manifest:
+
+.. code-block:: sh
+
+ if [ -f "$__object/parameter/foo" ]
+ then
+ while read -r l
+ do
+ __file "$l"
+ echo "$l" >&2
+ done < "$__object/parameter/foo"
+ fi
+
+and init manifest:
+
+.. code-block:: sh
+
+ __foo foo --foo a --foo b --foo c
+
+You expect that manifest stderr content is:
+
+.. code-block:: sh
+
+ a
+ b
+ c
+
+and that files *a*, *b* and *c* are created. But all you get in manifest stderr
+is:
+
+.. code-block:: sh
+
+ a
+
+and only *a* file is created.
+
+When redirecting parameter *foo* file content to while's stdin that means that all
+commands in while body have this same stdin. So when *__file* type gets executed,
+cdist saves its stdin which means it gets the remaining content of parameter *foo*
+file, i.e.:
+
+.. code-block:: sh
+
+ b
+ c
+
+The solution is to make sure that your types inside such loops get their stdin
+from somewhere else, e.g. for the above problem *__file* type can get empty
+stdin from */dev/null*:
+
+.. code-block:: sh
+
+ if [ -f "$__object/parameter/foo" ]
+ then
+ while read -r l
+ do
+ __file "$l" < /dev/null
+ echo "$l" >&2
+ done < "$__object/parameter/foo"
+ fi
+
+
Writing the manifest
--------------------
In the manifest of a type you can use other types, so your type extends