From 26dfdf37c21ce3c469ae0d6a717d390f422f9fbf Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 21 Jun 2020 01:13:30 +0300 Subject: [PATCH 001/411] [__download] support multiple checksum formats and download utilities, add --onchange and other minor changes --- cdist/conf/type/__download/explorer/state | 78 +++++++++++++++---- cdist/conf/type/__download/gencode-local | 25 +++++- cdist/conf/type/__download/gencode-remote | 7 ++ cdist/conf/type/__download/man.rst | 25 ++++-- .../type/__download/parameter/default/cmd-get | 1 - .../type/__download/parameter/default/cmd-sum | 1 - cdist/conf/type/__download/parameter/optional | 1 + 7 files changed, 116 insertions(+), 22 deletions(-) create mode 100755 cdist/conf/type/__download/gencode-remote delete mode 100644 cdist/conf/type/__download/parameter/default/cmd-get delete mode 100644 cdist/conf/type/__download/parameter/default/cmd-sum diff --git a/cdist/conf/type/__download/explorer/state b/cdist/conf/type/__download/explorer/state index 6a50f5a5..00362545 100755 --- a/cdist/conf/type/__download/explorer/state +++ b/cdist/conf/type/__download/explorer/state @@ -2,19 +2,71 @@ dst="/$__object_id" -# shellcheck disable=SC2059 -cmd="$( printf "$( cat "$__object/parameter/cmd-sum" )" "$dst" )" - -sum="$( cat "$__object/parameter/sum" )" - -if [ -f "$dst" ] +if [ ! -f "$dst" ] then - if [ "$( eval "$cmd" )" = "$sum" ] - then - echo 'present' - else - echo 'mismatch' - fi -else echo 'absent' + exit 0 +fi + +sum_should="$( cat "$__object/parameter/sum" )" + +if [ -f "$__object/parameter/cmd-sum" ] +then + # shellcheck disable=SC2059 + sum_is="$( eval "$( printf \ + "$( cat "$__object/parameter/cmd-sum" )" \ + "$dst" )" )" +else + os="$( "$__explorer/os" )" + + if echo "$sum_should" | grep -Eq '^[0-9]+\s[0-9]+$' + then + sum_is="$( cksum "$dst" | awk '{print $1" "$2}' )" + + elif echo "$sum_should" | grep -Eiq '^md5:[a-f0-9]{32}$' + then + case "$os" in + freebsd) + sum_is="md5:$( md5 -q "$dst" )" + ;; + *) + sum_is="md5:$( md5sum "$dst" | awk '{print $1}' )" + ;; + esac + + elif echo "$sum_should" | grep -Eiq '^sha1:[a-f0-9]{40}$' + then + case "$os" in + freebsd) + sum_is="sha1:$( sha1 -q "$dst" )" + ;; + *) + sum_is="sha1:$( sha1sum "$dst" | awk '{print $1}' )" + ;; + esac + + elif echo "$sum_should" | grep -Eiq '^sha256:[a-f0-9]{64}$' + then + case "$os" in + freebsd) + sum_is="sha256:$( sha256 -q "$dst" )" + ;; + *) + sum_is="sha256:$( sha256sum "$dst" | awk '{print $1}' )" + ;; + esac + fi +fi + +if [ -z "$sum_is" ] +then + echo 'no checksum from target' >&2 + exit 1 +fi + +if [ "$sum_is" = "$sum_should" ] +then + echo 'present' +else + echo 'mismatch' fi diff --git a/cdist/conf/type/__download/gencode-local b/cdist/conf/type/__download/gencode-local index 49e9c699..85ef3a60 100755 --- a/cdist/conf/type/__download/gencode-local +++ b/cdist/conf/type/__download/gencode-local @@ -9,12 +9,31 @@ fi url="$( cat "$__object/parameter/url" )" -cmd="$( cat "$__object/parameter/cmd-get" )" - tmp="$( mktemp )" dst="/$__object_id" +if [ -f "$__object/parameter/cmd-get" ] +then + cmd="$( cat "$__object/parameter/cmd-get" )" + +elif command -v wget > /dev/null +then + cmd="wget -O - '%s'" + +elif command -v curl > /dev/null +then + cmd="curl -o - '%s'" + +elif command -v fetch > /dev/null +then + cmd="fetch -o - '%s'" + +else + echo 'no usable locally installed utility for downloading' >&2 + exit 1 +fi + printf "$cmd > %s\n" \ "$url" \ "$tmp" @@ -33,3 +52,5 @@ printf '%s %s %s:%s\n' \ "$dst" echo "rm -f '$tmp'" + +echo 'downloaded' > "$__messages_out" diff --git a/cdist/conf/type/__download/gencode-remote b/cdist/conf/type/__download/gencode-remote new file mode 100755 index 00000000..b08d0050 --- /dev/null +++ b/cdist/conf/type/__download/gencode-remote @@ -0,0 +1,7 @@ +#!/bin/sh -e + +if [ -f "$__object/parameter/onchange" ] \ + && grep -Fq "$__object_id:downloaded" "$__messages_in" +then + cat "$__object/parameter/onchange" +fi diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index c973448f..63a41bc4 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -10,7 +10,13 @@ DESCRIPTION ----------- You must use persistent storage in target host for destination file (``$__object_id``) because it will be used for checksum calculation -in order to decide if file must be downloaded. +in order to decide if file must be (re-)downloaded. + +By default type will try to use following locally installed utilities +for downloading (in order): ``wget``, ``curl`` or ``fetch``. + +Environment variables like ``{http,https,ftp}_proxy`` etc can be used on +cdist execution (``http_proxy=foo cdist config ...``). REQUIRED PARAMETERS @@ -19,20 +25,29 @@ url URL from which to download the file. sum - Checksum of downloaded file. + Checksum of file going to be downloaded. + By default output of ``cksum`` without filename is expected. + Other hash formats supported with prefixes: ``md5:``, ``sha1:`` and ``sha256:``. + +onchange + Execute this command after download. OPTIONAL PARAMETERS ------------------- cmd-get Command used for downloading. - Default is ``wget -O- '%s'``. Command must output to ``stdout``. + Parameter will be used for ``printf`` and must include only one + variable ``%s`` which will become URL. + For example: ``wget -O - '%s'``. cmd-sum Command used for checksum calculation. - Default is ``md5sum '%s' | awk '{print $1}'``. Command output and ``--sum`` parameter must match. + Parameter will be used for ``printf`` and must include only one + variable ``%s`` which will become destination. + For example: ``md5sum '%s' | awk '{print $1}'``. EXAMPLES @@ -45,7 +60,7 @@ EXAMPLES require='__directory/opt/cpma' \ __download /opt/cpma/cnq3.zip \ --url https://cdn.playmorepromode.com/files/cnq3/cnq3-1.51.zip \ - --sum 46da3021ca9eace277115ec9106c5b46 + --sum md5:46da3021ca9eace277115ec9106c5b46 require='__download/opt/cpma/cnq3.zip' \ __unpack /opt/cpma/cnq3.zip \ diff --git a/cdist/conf/type/__download/parameter/default/cmd-get b/cdist/conf/type/__download/parameter/default/cmd-get deleted file mode 100644 index 2daa38a1..00000000 --- a/cdist/conf/type/__download/parameter/default/cmd-get +++ /dev/null @@ -1 +0,0 @@ -wget -O- '%s' diff --git a/cdist/conf/type/__download/parameter/default/cmd-sum b/cdist/conf/type/__download/parameter/default/cmd-sum deleted file mode 100644 index 3e8a9295..00000000 --- a/cdist/conf/type/__download/parameter/default/cmd-sum +++ /dev/null @@ -1 +0,0 @@ -md5sum '%s' | awk '{print $1}' diff --git a/cdist/conf/type/__download/parameter/optional b/cdist/conf/type/__download/parameter/optional index 22783e02..38c0ce4d 100644 --- a/cdist/conf/type/__download/parameter/optional +++ b/cdist/conf/type/__download/parameter/optional @@ -1,2 +1,3 @@ cmd-get cmd-sum +onchange From 49dde11def71cec121e5f698d0fb6ed3a539f97a Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 24 Jun 2020 07:04:06 +0200 Subject: [PATCH 002/411] Remove deprecated __pf_apply --- cdist/conf/type/__pf_apply/deprecated | 1 - cdist/conf/type/__pf_apply/explorer/rcvar | 36 --------------- cdist/conf/type/__pf_apply/gencode-remote | 51 --------------------- cdist/conf/type/__pf_apply/man.rst | 55 ----------------------- cdist/conf/type/__pf_apply/singleton | 0 5 files changed, 143 deletions(-) delete mode 100644 cdist/conf/type/__pf_apply/deprecated delete mode 100755 cdist/conf/type/__pf_apply/explorer/rcvar delete mode 100755 cdist/conf/type/__pf_apply/gencode-remote delete mode 100644 cdist/conf/type/__pf_apply/man.rst delete mode 100644 cdist/conf/type/__pf_apply/singleton diff --git a/cdist/conf/type/__pf_apply/deprecated b/cdist/conf/type/__pf_apply/deprecated deleted file mode 100644 index 36cfed90..00000000 --- a/cdist/conf/type/__pf_apply/deprecated +++ /dev/null @@ -1 +0,0 @@ -Consider moving to __pf_apply_anchor. Get in touch if you need __pf_apply. diff --git a/cdist/conf/type/__pf_apply/explorer/rcvar b/cdist/conf/type/__pf_apply/explorer/rcvar deleted file mode 100755 index 7c8d535f..00000000 --- a/cdist/conf/type/__pf_apply/explorer/rcvar +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# 2012 Jake Guffey (jake.guffey at eprotex.com) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# -# -# Get the location of the pf ruleset on the target host. -# - -# Debug -#exec >&2 -#set -x - -# Check /etc/rc.conf for pf's configuration file name. Default to /etc/pf.conf - -RC="/etc/rc.conf" -PFCONF="$(grep '^pf_rules=' ${RC} | cut -d= -f2 | sed 's/"//g')" -echo "${PFCONF:-"/etc/pf.conf"}" - -# Debug -#set +x - diff --git a/cdist/conf/type/__pf_apply/gencode-remote b/cdist/conf/type/__pf_apply/gencode-remote deleted file mode 100755 index c8f7a25a..00000000 --- a/cdist/conf/type/__pf_apply/gencode-remote +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh -e -# -# 2012 Jake Guffey (jake.guffey at eprotex.com) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# -# -# Apply pf(4) ruleset on *BSD -# - -# Debug -#exec >&2 -#set -x - -rcvar=$(cat "$__object/explorer/rcvar") - -cat <&2 - fi -fi -EOF - -# Debug -#set +x - diff --git a/cdist/conf/type/__pf_apply/man.rst b/cdist/conf/type/__pf_apply/man.rst deleted file mode 100644 index eee345e7..00000000 --- a/cdist/conf/type/__pf_apply/man.rst +++ /dev/null @@ -1,55 +0,0 @@ -cdist-type__pf_apply(7) -======================= - -NAME ----- -cdist-type__pf_apply - Apply pf(4) ruleset on \*BSD - - -DESCRIPTION ------------ -This type is used on \*BSD systems to manage the pf firewall's active ruleset. - - -REQUIRED PARAMETERS -------------------- -NONE - - -OPTIONAL PARAMETERS -------------------- -NONE - - -EXAMPLES --------- - -.. code-block:: sh - - # Modify the ruleset on $__target_host: - __pf_ruleset --state present --source /my/pf/ruleset.conf - require="__pf_ruleset" \ - __pf_apply - - # Remove the ruleset on $__target_host (implies disabling pf(4): - __pf_ruleset --state absent - require="__pf_ruleset" \ - __pf_apply - - -SEE ALSO --------- -:strong:`pf`\ (4), :strong:`cdist-type__pf_ruleset`\ (7) - - -AUTHORS -------- -Jake Guffey - - -COPYING -------- -Copyright \(C) 2012 Jake Guffey. 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/__pf_apply/singleton b/cdist/conf/type/__pf_apply/singleton deleted file mode 100644 index e69de29b..00000000 From 85614aabd6f3abef5af6d362203db956c9d72aa9 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 28 Jun 2020 16:38:15 +0300 Subject: [PATCH 003/411] [__download] add --download (local|remote), update manual --- .../conf/type/__download/explorer/remote_cmd | 19 +++++++++++++++ cdist/conf/type/__download/gencode-local | 4 +++- cdist/conf/type/__download/gencode-remote | 22 +++++++++++++++-- cdist/conf/type/__download/man.rst | 24 ++++++++++++------- cdist/conf/type/__download/manifest | 6 +++++ .../__download/parameter/default/download | 1 + cdist/conf/type/__download/parameter/optional | 1 + 7 files changed, 65 insertions(+), 12 deletions(-) create mode 100755 cdist/conf/type/__download/explorer/remote_cmd create mode 100755 cdist/conf/type/__download/manifest create mode 100644 cdist/conf/type/__download/parameter/default/download diff --git a/cdist/conf/type/__download/explorer/remote_cmd b/cdist/conf/type/__download/explorer/remote_cmd new file mode 100755 index 00000000..fbd4d84c --- /dev/null +++ b/cdist/conf/type/__download/explorer/remote_cmd @@ -0,0 +1,19 @@ +#!/bin/sh -e + +if [ -f "$__object/parameter/cmd-get" ] +then + cmd="$( cat "$__object/parameter/cmd-get" )" + +elif command -v curl > /dev/null +then + cmd="curl -o - '%s'" + +elif command -v fetch > /dev/null +then + cmd="fetch -o - '%s'" + +else + cmd="wget -O - '%s'" +fi + +echo "$cmd" diff --git a/cdist/conf/type/__download/gencode-local b/cdist/conf/type/__download/gencode-local index 85ef3a60..339827c2 100755 --- a/cdist/conf/type/__download/gencode-local +++ b/cdist/conf/type/__download/gencode-local @@ -1,8 +1,10 @@ #!/bin/sh -e +download="$( cat "$__object/parameter/download" )" + state_is="$( cat "$__object/explorer/state" )" -if [ "$state_is" = 'present' ] +if [ "$download" != 'local' ] || [ "$state_is" = 'present' ] then exit 0 fi diff --git a/cdist/conf/type/__download/gencode-remote b/cdist/conf/type/__download/gencode-remote index b08d0050..89ba72af 100755 --- a/cdist/conf/type/__download/gencode-remote +++ b/cdist/conf/type/__download/gencode-remote @@ -1,7 +1,25 @@ #!/bin/sh -e -if [ -f "$__object/parameter/onchange" ] \ - && grep -Fq "$__object_id:downloaded" "$__messages_in" +download="$( cat "$__object/parameter/download" )" + +state_is="$( cat "$__object/explorer/state" )" + +if [ "$download" = 'remote' ] && [ "$state_is" != 'present' ] +then + cmd="$( cat "$__object/explorer/remote_cmd" )" + + url="$( cat "$__object/parameter/url" )" + + dst="/$__object_id" + + printf "$cmd > %s\n" \ + "$url" \ + "$dst" + + echo 'downloaded' > "$__messages_out" +fi + +if [ -f "$__object/parameter/onchange" ] && [ "$state" != "present" ] then cat "$__object/parameter/onchange" fi diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index 63a41bc4..c161f4e4 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -3,26 +3,28 @@ cdist-type__download(7) NAME ---- -cdist-type__download - Download file to local storage and copy it to target host +cdist-type__download - Download a file DESCRIPTION ----------- -You must use persistent storage in target host for destination file -(``$__object_id``) because it will be used for checksum calculation -in order to decide if file must be (re-)downloaded. +Persistent storage for destination file in target host must be used +(``$__object_id``) because it will be used for checksum calculation in +order to decide if file must be (re-)downloaded. -By default type will try to use following locally installed utilities -for downloading (in order): ``wget``, ``curl`` or ``fetch``. +By default type will try to use ``wget``, ``curl`` or ``fetch`` for +downloading. If ``--download remote`` type will fallback to (and +install) ``wget``. -Environment variables like ``{http,https,ftp}_proxy`` etc can be used on -cdist execution (``http_proxy=foo cdist config ...``). +If ``--download local`` (default), then environment variables like +``{http,https,ftp}_proxy`` etc can be used on cdist execution +(``http_proxy=foo cdist config ...``). REQUIRED PARAMETERS ------------------- url - URL from which to download the file. + File's URL. sum Checksum of file going to be downloaded. @@ -35,6 +37,10 @@ onchange OPTIONAL PARAMETERS ------------------- +download + If ``local`` (default), then download file to local storage and copy + it to target host. If ``remote``, then download happens in target. + cmd-get Command used for downloading. Command must output to ``stdout``. diff --git a/cdist/conf/type/__download/manifest b/cdist/conf/type/__download/manifest new file mode 100755 index 00000000..7ec8d86d --- /dev/null +++ b/cdist/conf/type/__download/manifest @@ -0,0 +1,6 @@ +#!/bin/sh -e + +if grep -Eq '^wget' "$__object/explorer/remote_cmd" +then + __package wget +fi diff --git a/cdist/conf/type/__download/parameter/default/download b/cdist/conf/type/__download/parameter/default/download new file mode 100644 index 00000000..40830374 --- /dev/null +++ b/cdist/conf/type/__download/parameter/default/download @@ -0,0 +1 @@ +local diff --git a/cdist/conf/type/__download/parameter/optional b/cdist/conf/type/__download/parameter/optional index 38c0ce4d..838e2fbf 100644 --- a/cdist/conf/type/__download/parameter/optional +++ b/cdist/conf/type/__download/parameter/optional @@ -1,3 +1,4 @@ cmd-get cmd-sum +download onchange From b6bf90e3f1a775ec1bd27a99015107d24a397787 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 28 Jun 2020 16:43:45 +0300 Subject: [PATCH 004/411] [__download] update manual --- cdist/conf/type/__download/man.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index c161f4e4..eafa9dfc 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -8,15 +8,14 @@ cdist-type__download - Download a file DESCRIPTION ----------- -Persistent storage for destination file in target host must be used -(``$__object_id``) because it will be used for checksum calculation in -order to decide if file must be (re-)downloaded. +Destination (``$__object_id``) in target host must be persistent storage +in order to calculate checksum and decide if file must be (re-)downloaded. -By default type will try to use ``wget``, ``curl`` or ``fetch`` for -downloading. If ``--download remote`` type will fallback to (and -install) ``wget``. +By default type will try to use ``wget``, ``curl`` or ``fetch``. +If download happens in target (see ``--download``) then type will +fallback to (and install) ``wget``. -If ``--download local`` (default), then environment variables like +If download happens in local machine, then environment variables like ``{http,https,ftp}_proxy`` etc can be used on cdist execution (``http_proxy=foo cdist config ...``). From 3860f1feeaa2844191eeea84444963818bb42c4b Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 26 Jun 2020 14:33:16 +0200 Subject: [PATCH 005/411] [type/{__file/__directory}] Support setuid,setguid,sticky bits --- cdist/conf/type/__directory/explorer/stat | 17 +++++++++-------- cdist/conf/type/__directory/gencode-remote | 4 ++-- cdist/conf/type/__file/explorer/stat | 14 +++++++------- cdist/conf/type/__file/gencode-remote | 4 ++-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/cdist/conf/type/__directory/explorer/stat b/cdist/conf/type/__directory/explorer/stat index 105d894f..a7dc8431 100755 --- a/cdist/conf/type/__directory/explorer/stat +++ b/cdist/conf/type/__directory/explorer/stat @@ -33,7 +33,7 @@ fallback() { 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) }') + mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[st]/)*2^(9+i/3)}printf("%04o",k)}') printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\n' \ "$("$__type_explorer/type")" \ @@ -51,13 +51,14 @@ then exit fi -case $("$__explorer/os") in - "freebsd"|"netbsd"|"openbsd"|"macosx") - stat -f "type: %HT +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 }' +mode: %Mp%03Lp %Sp +' "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; solaris) ls1="$( ls -ld "$destination" )" @@ -92,9 +93,9 @@ mode: %Lp %Sp # 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 + stat -c 'type: %F owner: %u %U group: %g %G -mode: %a %A" "$destination" 2>/dev/null || fallback +mode: %04a %A' "$destination" 2>/dev/null || fallback ;; esac diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote index a1a32ea2..2c2c56fd 100755 --- a/cdist/conf/type/__directory/gencode-remote +++ b/cdist/conf/type/__directory/gencode-remote @@ -97,9 +97,9 @@ case "$state_should" in value_should="$(cat "$__object/parameter/$attribute")" value_is="$(get_current_value "$attribute" "$value_should")" - # change 0xxx format to xxx format => same as stat returns + # format mode in four digits => same as stat returns if [ "$attribute" = mode ]; then - value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')" + value_should=$(printf '%04u' "${value_should}") fi if [ "$set_attributes" = 1 ] || [ "$value_should" != "$value_is" ]; then diff --git a/cdist/conf/type/__file/explorer/stat b/cdist/conf/type/__file/explorer/stat index 91c8cc84..231768f6 100755 --- a/cdist/conf/type/__file/explorer/stat +++ b/cdist/conf/type/__file/explorer/stat @@ -34,7 +34,7 @@ fallback() { 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) }') + mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[st]/)*2^(9+i/3)}printf("%04o",k)}') size=$(echo "$ls_line" | awk '{ print $5 }') links=$(echo "$ls_line" | awk '{ print $2 }') @@ -63,13 +63,13 @@ fi case $("$__explorer/os") in freebsd|netbsd|openbsd|macosx) - stat -f "type: %HT + stat -f 'type: %HT owner: %Du %Su group: %Dg %Sg -mode: %Lp %Sp +mode: %Mp%03Lp %Sp size: %Dz links: %Dl -" "$destination" | awk '/^type/ { print tolower($0); next } { print }' +' "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; solaris) ls1="$( ls -ld "$destination" )" @@ -106,11 +106,11 @@ links: %Dl # 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 + stat -c 'type: %F owner: %u %U group: %g %G -mode: %a %A +mode: %04a %A size: %s -links: %h" "$destination" 2>/dev/null || fallback +links: %h' "$destination" 2>/dev/null || fallback ;; esac diff --git a/cdist/conf/type/__file/gencode-remote b/cdist/conf/type/__file/gencode-remote index 815593bd..a69154df 100755 --- a/cdist/conf/type/__file/gencode-remote +++ b/cdist/conf/type/__file/gencode-remote @@ -68,9 +68,9 @@ case "$state_should" in if [ -f "$__object/parameter/$attribute" ]; then value_should="$(cat "$__object/parameter/$attribute")" - # change 0xxx format to xxx format => same as stat returns + # format mode in four digits => same as stat returns if [ "$attribute" = mode ]; then - value_should="$(echo "$value_should" | sed 's/^0\(...\)/\1/')" + value_should=$(printf '%04u' "${value_should}") fi value_is="$(get_current_value "$attribute" "$value_should")" From fe193ecab8addf9b1c5b6d3c06c11ae9f9803378 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 1 Jul 2020 14:05:45 +0200 Subject: [PATCH 006/411] Make code consistent * Remove supreflous checking and warning message. * Fix cache recording. --- cdist/emulator.py | 65 +++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/cdist/emulator.py b/cdist/emulator.py index adbcbd9d..9fe84056 100644 --- a/cdist/emulator.py +++ b/cdist/emulator.py @@ -91,10 +91,6 @@ class Emulator: self.type_name = os.path.basename(argv[0]) self.cdist_type = core.CdistType(self.type_base_path, self.type_name) - # If set then object alreay exists and this var holds existing - # requirements. - self._existing_reqs = None - self.__init_log() def run(self): @@ -230,9 +226,6 @@ class Emulator: self.parameters[key] = value if self.cdist_object.exists and 'CDIST_OVERRIDE' not in self.env: - # Make existing requirements a set so that we can compare it - # later with new requirements. - self._existing_reqs = set(self.cdist_object.requirements) obj_params = self._object_params_in_context() if obj_params != self.parameters: errmsg = ("Object %s already exists with conflicting " @@ -251,23 +244,26 @@ class Emulator: else: self.cdist_object.create() self.cdist_object.parameters = self.parameters - # record the created object in typeorder file - with open(self.typeorder_path, 'a') as typeorderfile: - print(self.cdist_object.name, file=typeorderfile) - # record the created object in parent object typeorder file - __object_name = self.env.get('__object_name', None) - depname = self.cdist_object.name - if __object_name: - parent = self.cdist_object.object_from_name(__object_name) - parent.typeorder.append(self.cdist_object.name) - if self._order_dep_on(): - self.log.trace(('[ORDER_DEP] Adding %s to typeorder dep' - ' for %s'), depname, parent.name) - parent.typeorder_dep.append(depname) - elif self._order_dep_on(): - self.log.trace('[ORDER_DEP] Adding %s to global typeorder dep', - depname) - self._add_typeorder_dep(depname) + # Do the following recording even if object exists, but with + # different requirements. + + # record the created object in typeorder file + with open(self.typeorder_path, 'a') as typeorderfile: + print(self.cdist_object.name, file=typeorderfile) + # record the created object in parent object typeorder file + __object_name = self.env.get('__object_name', None) + depname = self.cdist_object.name + if __object_name: + parent = self.cdist_object.object_from_name(__object_name) + parent.typeorder.append(self.cdist_object.name) + if self._order_dep_on(): + self.log.trace(('[ORDER_DEP] Adding %s to typeorder dep' + ' for %s'), depname, parent.name) + parent.typeorder_dep.append(depname) + elif self._order_dep_on(): + self.log.trace('[ORDER_DEP] Adding %s to global typeorder dep', + depname) + self._add_typeorder_dep(depname) # Record / Append source self.cdist_object.source.append(self.object_source) @@ -322,8 +318,6 @@ class Emulator: # This ensures pattern matching is done against sanitised list self.cdist_object.requirements.append(cdist_object.name) - return cdist_object.name - def _order_dep_on(self): return os.path.exists(self.order_dep_state_path) @@ -392,7 +386,6 @@ class Emulator: # so do not set a requirement pass - reqs = set() if "require" in self.env: requirements = self.env['require'] self.log.debug("reqs = " + requirements) @@ -400,23 +393,7 @@ class Emulator: # Ignore empty fields - probably the only field anyway if len(requirement) == 0: continue - object_name = self.record_requirement(requirement) - reqs.add(object_name) - if self._existing_reqs is not None: - # If object exists then compare existing and new requirements. - if self._existing_reqs != reqs: - warnmsg = ("Object {} already exists with requirements:\n" - "{}: {}\n" - "{}: {}\n" - "Dependency resolver could not handle dependencies " - "as expected.".format( - self.cdist_object.name, - " ".join(self.cdist_object.source), - self._existing_reqs, - self.object_source, - reqs - )) - self.log.warning(warnmsg) + self.record_requirement(requirement) def record_auto_requirements(self): """An object shall automatically depend on all objects that it From 8ee71e67f49ff673db3844498521dd289e40cd27 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Tue, 2 Jun 2020 22:33:30 +0200 Subject: [PATCH 007/411] [__lxc_container] initial work for lxc contaienr type This should theoretically work, but is untested. It is able to create and delete, change basic configuration and start/stop/freeze the container. --- .../conf/type/__lxc_container/explorer/config | 37 ++++ .../type/__lxc_container/explorer/lxcpath | 16 ++ .../conf/type/__lxc_container/explorer/state | 18 ++ cdist/conf/type/__lxc_container/gencode-local | 54 +++++ .../conf/type/__lxc_container/gencode-remote | 203 ++++++++++++++++++ cdist/conf/type/__lxc_container/helper-exec | 68 ++++++ cdist/conf/type/__lxc_container/helper-param | 27 +++ cdist/conf/type/__lxc_container/issue.txt | 1 + cdist/conf/type/__lxc_container/man.rst | 125 +++++++++++ cdist/conf/type/__lxc_container/manifest | 106 +++++++++ .../type/__lxc_container/parameter/boolean | 1 + .../__lxc_container/parameter/default/state | 1 + .../__lxc_container/parameter/default/user | 1 + .../type/__lxc_container/parameter/optional | 10 + .../parameter/optional_multiple | 3 + cdist/conf/type/__lxc_container/todo.txt | 28 +++ 16 files changed, 699 insertions(+) create mode 100755 cdist/conf/type/__lxc_container/explorer/config create mode 100755 cdist/conf/type/__lxc_container/explorer/lxcpath create mode 100755 cdist/conf/type/__lxc_container/explorer/state create mode 100755 cdist/conf/type/__lxc_container/gencode-local create mode 100755 cdist/conf/type/__lxc_container/gencode-remote create mode 100644 cdist/conf/type/__lxc_container/helper-exec create mode 100644 cdist/conf/type/__lxc_container/helper-param create mode 100644 cdist/conf/type/__lxc_container/issue.txt create mode 100644 cdist/conf/type/__lxc_container/man.rst create mode 100755 cdist/conf/type/__lxc_container/manifest create mode 100644 cdist/conf/type/__lxc_container/parameter/boolean create mode 100644 cdist/conf/type/__lxc_container/parameter/default/state create mode 100644 cdist/conf/type/__lxc_container/parameter/default/user create mode 100644 cdist/conf/type/__lxc_container/parameter/optional create mode 100644 cdist/conf/type/__lxc_container/parameter/optional_multiple create mode 100644 cdist/conf/type/__lxc_container/todo.txt diff --git a/cdist/conf/type/__lxc_container/explorer/config b/cdist/conf/type/__lxc_container/explorer/config new file mode 100755 index 00000000..d82dbb25 --- /dev/null +++ b/cdist/conf/type/__lxc_container/explorer/config @@ -0,0 +1,37 @@ +#!/bin/sh -e +# explorer/config + +# Prints out the current container configuration (if required). This makes +# it easy to differ changes. + +# abort if container will be absent - no config required +if [ "$(cat "$__object/parameter/state")" = "absent" ]; then + exit 0 +fi + + +# read the lxcpath (reusing explorer) +lxcpath="$( "$__type_explorer/lxcpath" )" + +# get name +name="$__object/parameter/name" +if [ -f "$name" ]; then + name="$(cat "$name")" +else + name="$__object_id" +fi + + +# assemble the container configuration file +config="$lxcpath/$name/config" + +# check if the file exist +if [ -r "$config" ]; then + # print configuration and strip files to just values + # grep will hide all comments and empty lines - all others must be key-values + # sed will uniform patterns, that no spaces will be problematic (before, in the middle and at end) + grep -E -v "^([[:blank:]]*)(#|$)" "$config" | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' +else + >&2 printf "config file \"%s\" does not exist or is not readable\n" "$config" + exit 1 +fi diff --git a/cdist/conf/type/__lxc_container/explorer/lxcpath b/cdist/conf/type/__lxc_container/explorer/lxcpath new file mode 100755 index 00000000..a3505f94 --- /dev/null +++ b/cdist/conf/type/__lxc_container/explorer/lxcpath @@ -0,0 +1,16 @@ +#!/bin/sh -e +# explorer/lxcpath + +# Echos the lxcpath variable for all container instances + +# Load important functions and parameter handling +. "$__type/helper-param" +. "$__type/helper-exec" + + +# lxcpath parameter +if [ -z "$lxcpath" ]; then + lxc_g config "lxc.lxcpath" +else + echo "$lxcpath" +fi diff --git a/cdist/conf/type/__lxc_container/explorer/state b/cdist/conf/type/__lxc_container/explorer/state new file mode 100755 index 00000000..23900ba6 --- /dev/null +++ b/cdist/conf/type/__lxc_container/explorer/state @@ -0,0 +1,18 @@ +#!/bin/sh -e +# explorer/state + +# Outputs if the container exist +# possible values: present || absent || running || stopped || frozen + +# source param lib +. "$__type/helper-param" +. "$__type/helper-exec" + +# the lxc-info command will exit non-zero if container not exist +if ! lxc_c info -H -S >/dev/null 2>&1; then + # not exist + echo "absent" +else + # print state (command output matches to type states) + lxc_c info -H -s | tr '[[:upper:]]' '[[:lower:]]' +fi diff --git a/cdist/conf/type/__lxc_container/gencode-local b/cdist/conf/type/__lxc_container/gencode-local new file mode 100755 index 00000000..1c8a18c8 --- /dev/null +++ b/cdist/conf/type/__lxc_container/gencode-local @@ -0,0 +1,54 @@ +#!/bin/sh -e +# gencode-local + +# This uploads the diff of the configuration file, which is applied by gencode-remote + + +# check both states +state_is="$(cat "$__object/explorer/state")" +state_should="$(cat "$__object/parameter/state")" + +# Check the configurations only if the container exists +if [ "$state_should" != "absent" ]; then + # do changes + + # predict remote lxc config file + container_config="$(cat "$__object/explorer/lxcpath")/$name/config" + + # IPv6 fix + if echo "${__target_host}" | grep -q -E '^[0-9a-fA-F:]+$' + then + my_target_host="[${__target_host}]" + else + my_target_host="${__target_host}" + fi + + + # config-present + # remove all config lines from config-present that are already set or absent anyway + if grep -v -f "$__object/explorer/config" -f "$__object/files/config-absent" \ + "$__object/files/config-present" > "$__object/files/config.add"; then + + # get temp file name + add_dest="$($__remote_exec $__target_host "mktemp $container_config-add.XXXXXXXXXX")" + printf "%s" "$add_dest" > "$__object/files/remote-tmpfile_add" + # upload diff + cat < "$__object/files/config.del"; then + + # get temp file name + del_dest="$($__remote_exec $__target_host "mktemp $container_config-del.XXXXXXXXXX")" + printf "%s" "$del_dest" > "$__object/files/remote-tmpfile_del" + # upload diff + cat <> "$__messages_out" + ;; + + absent) + # shutdown and delete the container + # we could force-delete, but better be polite + # snapshots are deleted, too - to keep everything clean. May someone does not want it? + cat <> "$__messages_out" + ;; + + # error handling: invalid state + *) + printf "Container '%s' in unknown state %s\n" "$name" "$state_should" >&2 + exit 2 + ;; + esac + + # end of su here-document + echo "SU" +fi + + +# Check the configurations only if the container exists and there are changes +if [ "$state_should" != "absent" ] && \ + ( [ -f "${tmppath}_add" ] || [ -f "${tmppath}_del" ] ); then + # shortcut + tmppath="$__object/files/remote-tmpfile" + + # generate config path + container_config="$(cat "$__object/explorer/lxcpath")/$name/config" + # create remote tmpfile for config + cat <> "\$tmpconfig" +rm -rf "$(cat "${tmppath}_add")" +DONE + fi + + # check if smth. to be deleted + if [ -f "${tmppath}_del" ]; then + cat < "\$tmpconfig" +rm -rf "$(cat "${tmppath}_del")" +DONE + fi + + + # apply all changes + cat <> "$__messages_out" +fi + + +# TODO user context again +# Check if there is a difference within the states +if [ "$state_is" != "$state_should" ] && [ "$state_should" != "absent" ]; then + # change privileges (too complex to make exceptions) + cat <&2 echo "error: can not create and clone a container at once!" + >&2 echo "error: --template and --clone can not work together" + exit 2 +fi + +# no clone option if --template given +if [ -f "$param/template" ]; then + if [ -f "$param/clonepath" ] + then + >&2 echo "error: container will created by template, no clone options required!" + exit 2 + fi +fi + +# no template options if --clone given +if [ -f "$__object/parameter/clone" ]; then + if [ -f "$param/template-opts" ] \ + || [ -f "$param/default-config" ] \ + || [ -f "$param/no-default-config" ] \ + || [ -f "$param/release" ] \ + || [ -f "$param/arch" ] + then + >&2 echo "error: container will created by clone, no template options required!" + exit 2 + fi +fi + + + + +# ============================== # +# == CONFIGURATION HANDLING == # +# ============================== # + +# Function to read multiple parameter input for configuration and print it to a single file. +# It will handle file paths as well as the stdin. Instead of the file, the content will be printed. +# +# Parameters: +# 1: parameter name +# 2: file to print +write_multi_param() { + touch "$2" + while read line; do + if [ "$line" = "-" ]; then + # append stdin + cat "$__object/stdin" >> "$2" + elif [ -f "$line" ]; then + # append file content + cat "$line" >> "$2" + else + # print out content + printf "%s\n" "$line" >> "$2" + fi + done < "$__object/parameter/$1" +} + +# Function to get rid of whitespaces inside of key-value pairs. It will clear all of these. +# +# Parameters: +# 1: the file which should be handled +trimm_whitespaces() { + cp "$1" "$1"~ # backup file to see original content + grep -E -v "^([[:blank:]]*)(#|$)" "$1" \ + | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' +} + +# Only required if container will not be absent +# get the wanted configuration lines +if [ "$(cat "$__object/parameter/state")" != "absent" ]; then + # Create the files directory + mkdir "$__object/files/" + + # Create the file of the locally configuration + conffile="$__object/files/config-present" + write_multi_param config "$conffile" + trimm_whitespaces "$conffile" > "$conffile" + + # Create the file of the absent configuration + absentfile="$__object/files/config-absent" + write_multi_param config-absent "$absentfile" + trimm_whitespaces "$absentfile" > "$absentfile" +fi diff --git a/cdist/conf/type/__lxc_container/parameter/boolean b/cdist/conf/type/__lxc_container/parameter/boolean new file mode 100644 index 00000000..caf89a8e --- /dev/null +++ b/cdist/conf/type/__lxc_container/parameter/boolean @@ -0,0 +1 @@ +no-default-config diff --git a/cdist/conf/type/__lxc_container/parameter/default/state b/cdist/conf/type/__lxc_container/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__lxc_container/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__lxc_container/parameter/default/user b/cdist/conf/type/__lxc_container/parameter/default/user new file mode 100644 index 00000000..d8649da3 --- /dev/null +++ b/cdist/conf/type/__lxc_container/parameter/default/user @@ -0,0 +1 @@ +root diff --git a/cdist/conf/type/__lxc_container/parameter/optional b/cdist/conf/type/__lxc_container/parameter/optional new file mode 100644 index 00000000..fc4bb71b --- /dev/null +++ b/cdist/conf/type/__lxc_container/parameter/optional @@ -0,0 +1,10 @@ +name +user +state +lxcpath +template +default-config +release +arch +clone +clonepath diff --git a/cdist/conf/type/__lxc_container/parameter/optional_multiple b/cdist/conf/type/__lxc_container/parameter/optional_multiple new file mode 100644 index 00000000..069c02b1 --- /dev/null +++ b/cdist/conf/type/__lxc_container/parameter/optional_multiple @@ -0,0 +1,3 @@ +config +config-absent +template-opts diff --git a/cdist/conf/type/__lxc_container/todo.txt b/cdist/conf/type/__lxc_container/todo.txt new file mode 100644 index 00000000..17c4edaf --- /dev/null +++ b/cdist/conf/type/__lxc_container/todo.txt @@ -0,0 +1,28 @@ +# List of all featues that should be implemented +storage: + - backing_storage + - other settings prior to storage +template: + - type: a.E. debian, ubuntu -> what on change? + - release + - arch + - possible ssh auth key? + - possible root_password? + - possible packages? + - possible mirrors? + - other options?? +auto..: + - group + - start +lxc config .. +how to find lxc containers path? +lxc-copy: ephemeral containers? -> seperate type if it makes sense + +If config already created, it's considered the container is already created + -> first create; then setup + detection if template changed?? + + +lxc configuration at startup: + flag -f can used to set a default config (instead the system default) + there is no problem to change config before the first startup From 1b735fb1508edbe144263f892b5b1a1fdc03c95e Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sun, 28 Jun 2020 14:12:49 +0200 Subject: [PATCH 008/411] [__lxc_container] fix SC2021 Problems with backets and tr. --- cdist/conf/type/__lxc_container/explorer/state | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__lxc_container/explorer/state b/cdist/conf/type/__lxc_container/explorer/state index 23900ba6..0c79d3c8 100755 --- a/cdist/conf/type/__lxc_container/explorer/state +++ b/cdist/conf/type/__lxc_container/explorer/state @@ -14,5 +14,5 @@ if ! lxc_c info -H -S >/dev/null 2>&1; then echo "absent" else # print state (command output matches to type states) - lxc_c info -H -s | tr '[[:upper:]]' '[[:lower:]]' + lxc_c info -H -s | tr '[:upper:]' '[:lower:]' fi From 939abf6d45eca4ba6fb6133acbb8fc936c9a2d3b Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Tue, 30 Jun 2020 18:05:19 +0200 Subject: [PATCH 009/411] [__lxc_container] got type to fly with heavier changes Helper scripts do not work with explorers, so there are useless; and some other problems detected at runtime. `gencode-remote` *will be refactored - be aware* --- .../conf/type/__lxc_container/explorer/config | 5 +- .../type/__lxc_container/explorer/lxcpath | 15 ++- .../conf/type/__lxc_container/explorer/state | 35 +++++- cdist/conf/type/__lxc_container/gencode-local | 2 +- .../conf/type/__lxc_container/gencode-remote | 108 +++++++++++------- cdist/conf/type/__lxc_container/helper-exec | 68 ----------- cdist/conf/type/__lxc_container/helper-param | 27 ----- cdist/conf/type/__lxc_container/manifest | 28 +++-- 8 files changed, 128 insertions(+), 160 deletions(-) delete mode 100644 cdist/conf/type/__lxc_container/helper-exec delete mode 100644 cdist/conf/type/__lxc_container/helper-param diff --git a/cdist/conf/type/__lxc_container/explorer/config b/cdist/conf/type/__lxc_container/explorer/config index d82dbb25..287a5063 100755 --- a/cdist/conf/type/__lxc_container/explorer/config +++ b/cdist/conf/type/__lxc_container/explorer/config @@ -25,13 +25,10 @@ fi # assemble the container configuration file config="$lxcpath/$name/config" -# check if the file exist +# check if the file exist, else the container is absent if [ -r "$config" ]; then # print configuration and strip files to just values # grep will hide all comments and empty lines - all others must be key-values # sed will uniform patterns, that no spaces will be problematic (before, in the middle and at end) grep -E -v "^([[:blank:]]*)(#|$)" "$config" | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' -else - >&2 printf "config file \"%s\" does not exist or is not readable\n" "$config" - exit 1 fi diff --git a/cdist/conf/type/__lxc_container/explorer/lxcpath b/cdist/conf/type/__lxc_container/explorer/lxcpath index a3505f94..a4116b9b 100755 --- a/cdist/conf/type/__lxc_container/explorer/lxcpath +++ b/cdist/conf/type/__lxc_container/explorer/lxcpath @@ -3,14 +3,21 @@ # Echos the lxcpath variable for all container instances -# Load important functions and parameter handling -. "$__type/helper-param" -. "$__type/helper-exec" +# get parameter if exist +lxcpath="$(cat "$__object/parameter/lxcpath" 2>/dev/null || true)" # lxcpath parameter if [ -z "$lxcpath" ]; then - lxc_g config "lxc.lxcpath" + user="$(cat "$__object/parameter/user")" + + # gather default value from config + if [ "$user" != "$USER" ]; then + su -s "$(which -- lxc-config)" -- "$user" lxc.lxcpath + else + lxc-config lxc.lxcpath + fi else + # output the parameter echo "$lxcpath" fi diff --git a/cdist/conf/type/__lxc_container/explorer/state b/cdist/conf/type/__lxc_container/explorer/state index 0c79d3c8..fc37edf7 100755 --- a/cdist/conf/type/__lxc_container/explorer/state +++ b/cdist/conf/type/__lxc_container/explorer/state @@ -4,15 +4,40 @@ # Outputs if the container exist # possible values: present || absent || running || stopped || frozen -# source param lib -. "$__type/helper-param" -. "$__type/helper-exec" +# general parameters +name="$__object/parameter/name" +if [ -f "$name" ]; then + name="$(cat "$name")" +else + name="$__object_id" +fi +user="$(cat "$__object/parameter/user")" + +# lxcpath +lxcpath="$(cat "$__object/parameter/lxcpath" 2>/dev/null || true)" + +# assemble optional parameters +LXC_PARAM="" +if [ "$lxcpath" ]; then + LXC_PARAM="$LXC_PARAM -P \"$lxcpath\"" +fi + + +# function to get information +lxc_info() { + if [ "$user" != "$USER" ]; then + su -s "$(which -- lxc-info)" -- "$user" $LXC_PARAM -n "$name" -H "$@" + else + lxc-info $LXC_PARAM -n "$name" -H "$@" + fi +} + # the lxc-info command will exit non-zero if container not exist -if ! lxc_c info -H -S >/dev/null 2>&1; then +if ! lxc_info -S >/dev/null 2>&1; then # not exist echo "absent" else # print state (command output matches to type states) - lxc_c info -H -s | tr '[:upper:]' '[:lower:]' + lxc_info -s | tr '[:upper:]' '[:lower:]' fi diff --git a/cdist/conf/type/__lxc_container/gencode-local b/cdist/conf/type/__lxc_container/gencode-local index 1c8a18c8..dbfca7e8 100755 --- a/cdist/conf/type/__lxc_container/gencode-local +++ b/cdist/conf/type/__lxc_container/gencode-local @@ -48,7 +48,7 @@ OUT printf "%s" "$del_dest" > "$__object/files/remote-tmpfile_del" # upload diff cat <> "$__messages_out" - ;; + # end of su here-document + echo "SU" - absent) - # shutdown and delete the container - # we could force-delete, but better be polite - # snapshots are deleted, too - to keep everything clean. May someone does not want it? - cat <> "$__messages_out" + ;; + + absent) + # change privileges (too complex to make exceptions) + cat <> "$__messages_out" - ;; + # end of su here-document + echo "SU" - # error handling: invalid state - *) - printf "Container '%s' in unknown state %s\n" "$name" "$state_should" >&2 - exit 2 - ;; - esac + # write to the message system + echo "destroy" >> "$__messages_out" + ;; - # end of su here-document - echo "SU" -fi + # error handling: invalid state + *) + printf "Container '%s' in unknown state %s\n" "$name" "$state_should" >&2 + exit 2 + ;; +esac +# shortcut +tmppath="$__object/files/remote-tmpfile" + # Check the configurations only if the container exists and there are changes if [ "$state_should" != "absent" ] && \ ( [ -f "${tmppath}_add" ] || [ -f "${tmppath}_del" ] ); then - # shortcut - tmppath="$__object/files/remote-tmpfile" # generate config path container_config="$(cat "$__object/explorer/lxcpath")/$name/config" @@ -123,6 +152,15 @@ tmpconfig="\$(mktemp "$container_config.XXXXXXXXXX")" cp -p "$container_config" "\$tmpconfig" DONE + # check if smth. to be deleted + # must be before adding, because it takes the content of the original file + if [ -f "${tmppath}_del" ]; then + cat < "\$tmpconfig" +rm -rf "$(cat "${tmppath}_del")" +DONE + fi + # check if smth. to be added if [ -f "${tmppath}_add" ]; then cat < "\$tmpconfig" -rm -rf "$(cat "${tmppath}_del")" -DONE - fi - # apply all changes cat <> "$2" + cat "$__object/stdin" elif [ -f "$line" ]; then # append file content - cat "$line" >> "$2" + cat "$line" else # print out content - printf "%s\n" "$line" >> "$2" + printf "%s\n" "$line" fi done < "$__object/parameter/$1" } @@ -83,24 +85,26 @@ write_multi_param() { # Parameters: # 1: the file which should be handled trimm_whitespaces() { - cp "$1" "$1"~ # backup file to see original content - grep -E -v "^([[:blank:]]*)(#|$)" "$1" \ - | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' + mv "$1" "$1"~ # backup file to see original content + grep -E -v "^([[:blank:]]*)(#|$)" "$1"~ \ + | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' \ + > "$1" } + # Only required if container will not be absent -# get the wanted configuration lines +# prepare the wanted configuration lines if [ "$(cat "$__object/parameter/state")" != "absent" ]; then # Create the files directory mkdir "$__object/files/" # Create the file of the locally configuration conffile="$__object/files/config-present" - write_multi_param config "$conffile" - trimm_whitespaces "$conffile" > "$conffile" + write_multi_param config > "$conffile" + trimm_whitespaces "$conffile" # Create the file of the absent configuration absentfile="$__object/files/config-absent" - write_multi_param config-absent "$absentfile" - trimm_whitespaces "$absentfile" > "$absentfile" + write_multi_param config-absent > "$absentfile" + trimm_whitespaces "$absentfile" fi From c92d56293488eebf8df96f55153a0ca1fb16edc7 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 4 Jul 2020 14:25:13 +0200 Subject: [PATCH 010/411] [__lxc_container] refactored gencode-remote processing litte changes to `gencode-local` and more messages, too. --- cdist/conf/type/__lxc_container/gencode-local | 3 +- .../conf/type/__lxc_container/gencode-remote | 133 ++++++++++++------ cdist/conf/type/__lxc_container/man.rst | 12 ++ 3 files changed, 101 insertions(+), 47 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-local b/cdist/conf/type/__lxc_container/gencode-local index dbfca7e8..04935070 100755 --- a/cdist/conf/type/__lxc_container/gencode-local +++ b/cdist/conf/type/__lxc_container/gencode-local @@ -4,8 +4,7 @@ # This uploads the diff of the configuration file, which is applied by gencode-remote -# check both states -state_is="$(cat "$__object/explorer/state")" +# Check desired state state_should="$(cat "$__object/parameter/state")" # Check the configurations only if the container exists diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index b03f13d2..d1e06b6e 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -2,6 +2,16 @@ # gencode-remote # Does all common stuff for the container on the host +# +# Following stages need to be observed when executing this type +# 1. Container creation IF $state_is = absent +# 2. patching container config IF NOT $state_should = absent +# 3. look after runstates (running,frozen,stopped) +# 4. Container destruction IF $state_should = absent +# +# It is only required if: +# - $state_is != $state_should +# - config changed (detects if changes are uploaded) # Parameter gathering @@ -18,7 +28,7 @@ state_is="$(cat "$__object/explorer/state")" state_should="$(cat "$__object/parameter/state")" # general lxc things -lxcpath="$(cat "$__object/parameter/lxcpath" || true)" +lxcpath="$(cat "$__object/parameter/lxcpath" 2>/dev/null || true)" # Summerize common parameter arguments, listed in manual as "COMMON OPTIONS" @@ -31,9 +41,25 @@ if [ -n "$lxcpath" ]; then fi +# shortcut +tmppath="$__object/files/remote-tmpfile" +# shortcut function +config_changes() { + if ( [ -f "${tmppath}_add" ] || [ -f "${tmppath}_del" ] ); then + return 0 + else + return 1 + fi +} + + +# Short curcit if nothing changed +if [ "$state_is" = "$state_should" ] && ( ! config_changes ); then exit; fi + # handle if the container should exist or not case "$state_should" in + # all states where the container should exist present|running|stopped|frozen) # only relevant if the container does not exist before if [ "$state_is" = "absent" ]; then @@ -98,35 +124,25 @@ LXC cat <> "$__messages_out" fi - - # end of su here-document - echo "SU" - - # write to the message system - echo "create" >> "$__messages_out" ;; + + # list other states to get a correct error message in the wildcard case absent) - # change privileges (too complex to make exceptions) - cat <> "$__messages_out" ;; # error handling: invalid state @@ -137,13 +153,8 @@ LXC esac -# shortcut -tmppath="$__object/files/remote-tmpfile" - # Check the configurations only if the container exists and there are changes -if [ "$state_should" != "absent" ] && \ - ( [ -f "${tmppath}_add" ] || [ -f "${tmppath}_del" ] ); then - +if config_changes; then # generate config path container_config="$(cat "$__object/explorer/lxcpath")/$name/config" # create remote tmpfile for config @@ -180,54 +191,86 @@ DONE fi -# TODO user context again # Check if there is a difference within the states -if [ "$state_is" != "$state_should" ] && [ "$state_should" != "absent" ]; then +if [ "$state_is" != "$state_should" ] && [ "$state_should" != "present" ]; then # change privileges (too complex to make exceptions) cat <> "$__messages_out" + fi + # handle if the container should exist or not case "$state_should" in running) - if [ "$state_is" = "frozen" ]; then + # already running if unfreezed + if [ "$state_is" != "frozen" ]; then cat <> "$__messages_out" + fi ;; + # stop the container if it should be removed stopped) - if [ "$state_is" = "frozen" ]; then - cat <> "$__messages_out" + ;; + + # container should be stopped if not already done + absent) + if [ "$state_is" != "stopped" ]; then + cat <> "$__messages_out" fi cat <> "$__messages_out" ;; *) - ;; # must be checked by previous case + # must be checked by previous case + ;; esac # end of su here-document echo "SU" fi + + +# Check if the container needs to be removed +if [ "$state_should" = "absent" ]; then + # change privileges (too complex to make exceptions) + # then, shutdown and delete the container + # we could force-delete, but better be polite + # snapshots are deleted, too - to keep everything clean. May someone does not want it? + cat <> "$__messages_out" +fi diff --git a/cdist/conf/type/__lxc_container/man.rst b/cdist/conf/type/__lxc_container/man.rst index f84b0619..ddf08daa 100644 --- a/cdist/conf/type/__lxc_container/man.rst +++ b/cdist/conf/type/__lxc_container/man.rst @@ -123,3 +123,15 @@ destroy config The container configuration changed. + +start + Started the container. + +stop + Stopped the container. + +freeze + Freezed all container processes. The container will be started if not yet done to be able to freeze. + +melt + Unfreezed all container processes. Will be done if any other state (except `present`) should be reached. From e9256b6e8e3403e1435e4f1b65726dbb5dd991eb Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 4 Jul 2020 18:19:46 +0200 Subject: [PATCH 011/411] [__lxc_container] create: added backingstore and template options With some minor changes, the backingstore parameters and some more template options where added (incl. `man.rst`). --- cdist/conf/type/__lxc_container/gencode-local | 22 ++++++- .../conf/type/__lxc_container/gencode-remote | 56 ++++++++++++++---- cdist/conf/type/__lxc_container/man.rst | 59 +++++++++++++++++-- cdist/conf/type/__lxc_container/manifest | 39 ++++++++++-- .../type/__lxc_container/parameter/optional | 9 +++ cdist/conf/type/__lxc_container/todo.txt | 17 +----- 6 files changed, 161 insertions(+), 41 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-local b/cdist/conf/type/__lxc_container/gencode-local index 04935070..e0572bb4 100755 --- a/cdist/conf/type/__lxc_container/gencode-local +++ b/cdist/conf/type/__lxc_container/gencode-local @@ -4,9 +4,18 @@ # This uploads the diff of the configuration file, which is applied by gencode-remote -# Check desired state +# Get required parameters +name="$__object/parameter/name" +if [ -f "$name" ]; then + name="$(cat "$name")" +else + name="$__object_id" +fi + +state_is="$(cat "$__object/explorer/state")" state_should="$(cat "$__object/parameter/state")" + # Check the configurations only if the container exists if [ "$state_should" != "absent" ]; then # do changes @@ -22,6 +31,13 @@ if [ "$state_should" != "absent" ]; then my_target_host="${__target_host}" fi + # create remote container directory if container is not yet available + if [ "$state_is" = "absent" ]; then + # this must be done because the container will be created after the configuration is uploaded + # would also be possible to do everything in gencode-remote to keep the order + $__remote_exec $__target_host "mkdir $(dirname "$container_config")" + fi + # config-present # remove all config lines from config-present that are already set or absent anyway @@ -31,7 +47,7 @@ if [ "$state_should" != "absent" ]; then # get temp file name add_dest="$($__remote_exec $__target_host "mktemp $container_config-add.XXXXXXXXXX")" printf "%s" "$add_dest" > "$__object/files/remote-tmpfile_add" - # upload diff + # upload delta cat < "$__object/files/remote-tmpfile_del" - # upload diff + # upload delta cat <&2 echo "error: --bdev-dir is only possible for backingstore 'dir' or 'none'" + exit 2 + fi + fi + + if [ "$backingstore" != "lvm" ] && [ "$backingstore" != "loop" ]; then + if [ -f "$param/bdev-fstype" ] \ + || [ -f "$param/bdev-fssize" ] + then + >&2 echo "error: --bdev-fstype and --bdev-fssize only available for backingstore 'lvm' or 'loop'" + exit 2 + fi + fi + + if [ "$backingstore" != "lvm" ]; then + if [ -f "$param/bdev-lvname" ] \ + || [ -f "$param/bdev-vgname" ] \ + || [ -f "$param/bdev-thinpool" ] + then + >&2 echo "error: --bdev-{lv,vg}name and --bdev-thinpool only available for backingstore 'lvm'" + exit 2 + fi + fi +fi + diff --git a/cdist/conf/type/__lxc_container/parameter/optional b/cdist/conf/type/__lxc_container/parameter/optional index fc4bb71b..257283d8 100644 --- a/cdist/conf/type/__lxc_container/parameter/optional +++ b/cdist/conf/type/__lxc_container/parameter/optional @@ -6,5 +6,14 @@ template default-config release arch +mirror +ssh-key clone clonepath +backingstore +bdev-dir +bdev-fstype +bdev-fssize +bdev-lvname +bdev-vgname +bdev-thinpool diff --git a/cdist/conf/type/__lxc_container/todo.txt b/cdist/conf/type/__lxc_container/todo.txt index 17c4edaf..e5f8f471 100644 --- a/cdist/conf/type/__lxc_container/todo.txt +++ b/cdist/conf/type/__lxc_container/todo.txt @@ -1,28 +1,13 @@ # List of all featues that should be implemented -storage: - - backing_storage - - other settings prior to storage template: - type: a.E. debian, ubuntu -> what on change? - - release - - arch - - possible ssh auth key? - possible root_password? - possible packages? - - possible mirrors? - other options?? -auto..: +auto.. (lxc autostart): - group - start -lxc config .. -how to find lxc containers path? -lxc-copy: ephemeral containers? -> seperate type if it makes sense If config already created, it's considered the container is already created -> first create; then setup detection if template changed?? - - -lxc configuration at startup: - flag -f can used to set a default config (instead the system default) - there is no problem to change config before the first startup From 1c8eee17499012a1f8b318b502603d37ca01dc13 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sun, 5 Jul 2020 11:52:34 +0200 Subject: [PATCH 012/411] [__lxc_container] Updated manpage (incl. examples, copyright, ..) Should be fine now. --- .../conf/type/__lxc_container/gencode-remote | 2 +- cdist/conf/type/__lxc_container/man.rst | 99 ++++++++++++++++--- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index 8ee5623b..ef61c66d 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -105,7 +105,7 @@ USER # check, if the container should be created or cloned if [ -f "$__object/parameter/clone" ]; then copy_from="$(cat "$__object/parameter/clone")" - copypath="$(cat "$__object/parameter/clonepath" || true)" + copypath="$(cat "$__object/parameter/clonepath" 2>/dev/null || true)" # assemble own optional lxc options lxc_opts="" diff --git a/cdist/conf/type/__lxc_container/man.rst b/cdist/conf/type/__lxc_container/man.rst index 547178c5..991c86fb 100644 --- a/cdist/conf/type/__lxc_container/man.rst +++ b/cdist/conf/type/__lxc_container/man.rst @@ -3,16 +3,19 @@ cdist-type__lxc_container(7) NAME ---- -cdist-type__lxc_container - Controls the configuration of a lxc container +cdist-type__lxc_container - Controls the state and configuration of a lxc container DESCRIPTION ----------- -TBA. +This type handles lxc containers. It supports containers from different users and paths. +The state describes if the container exists and is running. The container will be created +with the template or clone parameters if required, whatever is set. These options will +be ignored if the container is already created, as the template script only runs at +creation time. REQUIRED PARAMETERS ------------------- - None. OPTIONAL PARAMETERS @@ -28,17 +31,17 @@ user state The state of the container, if it should exist or not. + present + The container exist, but it is ignored if the container will run or not **(default)** + running - The container exist and is running (default) + The container exist and is running stopped The container exist, but does not run frozen - The container exist and is frozen - - present - The container exist, but it is ignored if the container will run or not + The container exist and is frozen. If it is stopped before, it will be started and then freezed. absent The container does not exist @@ -59,7 +62,6 @@ config-absent BOOLEAN PARAMETERS ------------------ - None. CREATE PARAMETERS @@ -103,6 +105,7 @@ bdev-thinpool TEMPLATE PARAMETERS ------------------- + This or the *CLONE PARAMETERS* are required to create an container and must be present if the container should be created. If the template parameters are choosen, `--template` must be present. Then, none of the *CLONE PARAMETERS* must be present. @@ -119,9 +122,9 @@ template this argument and should exist on the target host. default-config - Alternative path to the user-defined default config. For the root user, this is commonly at - `/etc/lxc/default.conf`. It will be included into the container configuration file at creation - time. + Alternative path to the user-defined default config. This file must exist on the target machine. + For the root user, this is commonly at `/etc/lxc/default.conf`. It will be included into the + container configuration file at creation time. no-default-config **(Boolean value)** This parameter avoids using a default config file by using an empty file instead. @@ -149,13 +152,15 @@ ssh-key CLONE PARAMETERS ---------------- + This or the *TEMPLATE PARAMETERS* are required to create an container and must be present if the container should be created. If the clone parameters are choosen, `--clone` must be present. Then, none of the *TEMPLATE PARAMETERS* must be present. clone Instead of creating a new container with a given template, clone an other container and use him. The - argument takes the container name, which will be cloned. He should exist. + argument takes the container name, which will be cloned. He should exist and must be stopped. Else, + the clone will not work. clonepath The container path for the container to clone. It is like the `--lxcpath` parameter, but for the container @@ -180,7 +185,73 @@ stop Stopped the container. freeze - Freezed all container processes. The container will be started if not yet done to be able to freeze. + Freezed all container processes. The container will be started too if the container is stopped before. melt Unfreezed all container processes. Will be done if any other state (except `present`) should be reached. + +ABORTS +------ +Aborts in the following cases: + +The type aborts if there are incompatible arguments found. This may be *CLONE* and *TEMPLATE PARAMETERS*, +backingstorage parameters for the wrong storage or incompatible template option shortcuts. + +When cloning, it aborts if the container to clone from does not exist or is not stopped with no warning. It +may be possible to clone while the container is running, which requires a backing storage supporting it, but +there is nothing in lxc-copy(1) which indicades something about the container state while cloning. + +EXAMPLES +-------- + +.. code-block:: sh + + # create a container that "just should exist" (does not start the container) + # --template is required if the container needs to be created + __lxc_container foo --template debian + __lxc_container foo --state present --template debian + + # remove the container + __lxc_container bar --state absent + + # container that should definitely running + __lxc_container foobar --state running + # freeze this one + __lxc_container water --state frozen + + # create with some template options + __lxc_container special --state stopped --template debian \ + --release stretch --arch amd64 \ + --template-opts "--packages=foo,bar --flush-cache" + + # clone a container instead of creating it + # foo must be stopped that this will work + __lxc_container foofighters --clone foo --state running + + # handle configuration + __lxc_container peter --state running \ + --config "$__files/lxc/default.conf" \ # content of files are possible + --config "lxc.group = onboot" \ # one lines + --config "lxc.start.auto = 1" \ # spaces around the equal sign are ignored + --config-absent "lxc.group = testing" \ # configuration options can be removed + --config - < + +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. From 211393814a8c997d9f1ca27f86367ea8aace7cec Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sun, 5 Jul 2020 20:15:41 +0200 Subject: [PATCH 013/411] [__lxc_container] Updated manpage (completly proof-read it) I think it should be fine now .. :-) --- cdist/conf/type/__lxc_container/man.rst | 116 +++++++++++++----------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/cdist/conf/type/__lxc_container/man.rst b/cdist/conf/type/__lxc_container/man.rst index 991c86fb..d0abf2e2 100644 --- a/cdist/conf/type/__lxc_container/man.rst +++ b/cdist/conf/type/__lxc_container/man.rst @@ -14,6 +14,13 @@ with the template or clone parameters if required, whatever is set. These option be ignored if the container is already created, as the template script only runs at creation time. +The container can be `absent`, which means nothing exists. `present` is the opposite and +completely does not care if the container runs or not. Further states imply that the +container exists. There is `running` and `stopped`, which should be self-explainable. +The state `frozen` means all container processes are frozen. If it moves from `stopped` +to `frozen`, the container will be first started to be frozen. From `frozen` to any other +state, the container will be first unfrozen to continue. + REQUIRED PARAMETERS ------------------- None. @@ -23,13 +30,14 @@ OPTIONAL PARAMETERS name String which will used as container name instead of the object id. This should only required - if multiple lxc instances used from different users/directories (in junction with `--lxcpath`). + if multiple lxc instances used from different users/directories (in junction with ``--user`` + and ``--lxcpath``). user - The unix user name in which lxc commands are executed. Each user have a different lxc instance. + The unix user name with all lxc commands are executed. Each user have a different lxc instance. state - The state of the container, if it should exist or not. + The state of the container, if it should exist or not, and running. present The container exist, but it is ignored if the container will run or not **(default)** @@ -41,23 +49,23 @@ state The container exist, but does not run frozen - The container exist and is frozen. If it is stopped before, it will be started and then freezed. + The container exist and all processes are frozen absent The container does not exist lxcpath Set an other directory as lxc container location instead of the program default. This will passed - to all lxc commands who do smth. with containers. + to all lxc commands. config Contains configuration file paths and/or single configuration lines to assemble the lxc container - configuration file. There is no deep dive into files referenced with `lxc.include`. Can be used + configuration file. There is no deep dive into files referenced with ``lxc.include``. Can be used multiple times. config-absent - Contains configuration file paths and/ro single configuration lines which makes the same as the - `--config` parameter execpt all configuration lines will be removed instead of being added, Can + Contains configuration file paths and/or single configuration lines which makes the same as the + ``--config`` parameter execpt all configuration lines will be removed instead of being added. Can be used multiple times. BOOLEAN PARAMETERS @@ -67,63 +75,63 @@ None. CREATE PARAMETERS ----------------- -This parameters will be used with *TEMPLATE PARAMETERS* or *CLONE PARAMETERS* to create the container +This parameters will be used with **TEMPLATE PARAMETERS** or **CLONE PARAMETERS** to create the container if the container is absent. All of these parameters will only used if the container will be created, in all other cases, these parameters will be ignored. -All backingstore parameters (incl. all bdev-* ones) can be read from the manual lxc-create(1) at option -`--bdev` or lxc-copy(1) at option `--backingstore`. The possibilities may differ from creating and cloning. -The bdev-* parameters are only available for some backingstores. If used for other backingstores, the -type aborts. +All backingstore parameters (incl. all `bdev-*` ones) can be read from the manual lxc-create(1) at option +``--bdev`` or lxc-copy(1) at option ``--backingstore``. The possibilities may differ from creating and +cloning. The `bdev-*` parameters are only available for some backingstores. If used for other backingstores, +the type aborts. backingstore - Set the storage for the container root partition. Commonly, there should be at minimum `dir` (or `none`), - `lvm`, `loop`, `btrfs`, `zfs` or `best` be possible. + Set the storage for the container root filesystem. Commonly, there should be at minimum ``dir`` (or ``none``), + ``lvm``, ``loop``, ``btrfs``, ``zfs`` or ``best`` be possible. bdev-dir Specifies an other path for the rootfs directory instead in the lxc configuration directoy. Only - available for the backingstore `dir` or `none`. + available for the backingstore ``dir`` or ``none``. bdev-fstype Specifies the filesystem to be created instead of the default value. Only available for the - backingstore `lvm` and `loop`. + backingstore ``lvm`` and ``loop``. bdev-fssize Specifies the filesystem size to be created instead of the default value. Only available for the - backingstore `lvm` and `loop`. + backingstore ``lvm`` and ``loop``. bdev-lvname The custom LVM logical volume that will be created for the new container. Only availabe for the - backingstore `lvm`. + backingstore ``lvm``. bdev-vgname - The custon LVM volume group in there the logical volume will be created. Only available for the - backingstore `lvm`. + The custon LVM volume group in where the logical volume will be created. Only available for the + backingstore ``lvm``. bdev-thinpool - The custom thinpool the logical volume will created in. Only available for the backingstore `lvm`. + The custom thinpool the logical volume will created in. Only available for the backingstore ``lvm``. TEMPLATE PARAMETERS ------------------- -This or the *CLONE PARAMETERS* are required to create an container and must be present if the container -should be created. If the template parameters are choosen, `--template` must be present. Then, none of -the *CLONE PARAMETERS* must be present. +This or the **CLONE PARAMETERS** are required to create an container and must be present if the container +should be created. If the template parameters are choosen, ``--template`` must be present. Then, none of +the **CLONE PARAMETERS** must be present. Because the templates vary in the possiblities of arguments and unkown arguments causing the abort of the container creation, the type will throw an error if the compatibility is not garanteed to the given template. -The template options are only applied if the container will be created, there are not applied when -the container is already present. +The template options are only applied if the container will be created. There are not applied if the +container is already present. template - The template which is used to create the the container. The name of the template must passed with + The template which is used to create the the container. The name of the template must passed by this argument and should exist on the target host. default-config - Alternative path to the user-defined default config. This file must exist on the target machine. - For the root user, this is commonly at `/etc/lxc/default.conf`. It will be included into the + Alternative path for the user-defined default config. This file must exist on the target machine. + For the root user, this is commonly at ``/etc/lxc/default.conf``. It will be included into the container configuration file at creation time. no-default-config @@ -131,31 +139,31 @@ no-default-config template-opts Raw options which get passed to the template directly. Can be used multiple times. If the argument - contain spaces, it will be interpreted as multiple arguments and must be escaped for an normal posix - shell if this is not wanted. + contain spaces, it will be interpreted as multiple arguments by the target host and must be escaped + for a normal posix shell if this is not wanted. The following parameters are shortcuts for some template options. As templates may support it or not, you should be careful when using them. You can check all available template options with -`lxc-create -t $template -h` (incl. lxc-create help, too) or `/usr/share/lxc/templates/lxc-$template -h`. +``lxc-create -t $template -h`` (incl. lxc-create help, too) or ``/usr/share/lxc/templates/lxc-$template -h``. release - Sets the release for the wanted distribution. Uses the `-r` option. + Sets the release for the wanted distribution. Uses the ``-r`` option. arch - Sets the architecture used for the creating container. Uses the `-a` option. + Sets the architecture used for the creating container. Uses the ``-a`` option. mirror - Sets the mirror to download from. Uses the `--mirror=` option. + Sets the mirror to download from. Uses the ``--mirror=`` option. ssh-key - Sets the ssh key for the root user- Uses the `-S` option. + Sets the ssh key for the root user. Uses the ``-S`` option. CLONE PARAMETERS ---------------- -This or the *TEMPLATE PARAMETERS* are required to create an container and must be present if the container -should be created. If the clone parameters are choosen, `--clone` must be present. Then, none of the -*TEMPLATE PARAMETERS* must be present. +This or the **TEMPLATE PARAMETERS** are required to create an container and must be present if the container +should be created. If the clone parameters are choosen, ``--clone`` must be present. Then, none of the +**TEMPLATE PARAMETERS** must be present. clone Instead of creating a new container with a given template, clone an other container and use him. The @@ -163,8 +171,8 @@ clone the clone will not work. clonepath - The container path for the container to clone. It is like the `--lxcpath` parameter, but for the container - which will be cloned, not the target container. + The container path for the container to clone from. It is like the ``--lxcpath`` parameter, but for the + container from where will be cloned, not the target container (the container given by ``--clone``). MESSAGES -------- @@ -179,27 +187,27 @@ config The container configuration changed. start - Started the container. + Container was started. stop - Stopped the container. + Container was stopped. freeze - Freezed all container processes. The container will be started too if the container is stopped before. + Freezed all container processes. melt - Unfreezed all container processes. Will be done if any other state (except `present`) should be reached. + Unfreezed all container processes. ABORTS ------ Aborts in the following cases: -The type aborts if there are incompatible arguments found. This may be *CLONE* and *TEMPLATE PARAMETERS*, +The type aborts if there are incompatible arguments found. This may be **CLONE** and **TEMPLATE PARAMETERS**, backingstorage parameters for the wrong storage or incompatible template option shortcuts. -When cloning, it aborts if the container to clone from does not exist or is not stopped with no warning. It -may be possible to clone while the container is running, which requires a backing storage supporting it, but -there is nothing in lxc-copy(1) which indicades something about the container state while cloning. +When cloning, it aborts if the container to clone from does not exist or is not stopped with no warning. +It may be possible to clone while the container is running, which requires a backing storage supporting +it, but there is nothing in lxc-copy(1) which indicades something about the container state while cloning. EXAMPLES -------- @@ -221,7 +229,7 @@ EXAMPLES # create with some template options __lxc_container special --state stopped --template debian \ - --release stretch --arch amd64 \ + --release buster --arch amd64 \ --template-opts "--packages=foo,bar --flush-cache" # clone a container instead of creating it @@ -235,9 +243,9 @@ EXAMPLES --config "lxc.start.auto = 1" \ # spaces around the equal sign are ignored --config-absent "lxc.group = testing" \ # configuration options can be removed --config - < Date: Sun, 5 Jul 2020 20:50:40 +0200 Subject: [PATCH 014/411] [__lxc_container] fix some shellchecks (incl. warnings) To the error in the `explorer/state`: It's intended, as it passes possible parameters to the command. Varibale will set unquoted, so word splitting take action, but the quotes inside the variable work. --- cdist/conf/type/__lxc_container/explorer/state | 2 ++ cdist/conf/type/__lxc_container/gencode-remote | 6 +++--- cdist/conf/type/__lxc_container/manifest | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__lxc_container/explorer/state b/cdist/conf/type/__lxc_container/explorer/state index fc37edf7..c3c7f30f 100755 --- a/cdist/conf/type/__lxc_container/explorer/state +++ b/cdist/conf/type/__lxc_container/explorer/state @@ -19,12 +19,14 @@ lxcpath="$(cat "$__object/parameter/lxcpath" 2>/dev/null || true)" # assemble optional parameters LXC_PARAM="" if [ "$lxcpath" ]; then + # shellcheck disable=SC2089 LXC_PARAM="$LXC_PARAM -P \"$lxcpath\"" fi # function to get information lxc_info() { + # shellcheck disable=SC2090 disable=SC2086 if [ "$user" != "$USER" ]; then su -s "$(which -- lxc-info)" -- "$user" $LXC_PARAM -n "$name" -H "$@" else diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index ef61c66d..2177e377 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -44,7 +44,7 @@ fi # shortcut for checking config changes tmppath="$__object/files/remote-tmpfile" config_changes() { - if ( [ -f "${tmppath}_add" ] || [ -f "${tmppath}_del" ] ); then + if [ -f "${tmppath}_add" ] || [ -f "${tmppath}_del" ]; then return 0 else return 1 @@ -91,7 +91,7 @@ USER backingstore_opts="" if [ -f "$__object/parameter/backingstore" ]; then # -B works for both types, they have different long opts - backingstore_opts="-B '$(cat "$__object/parameter/backingstore")'" + backingstore_opts="$backingstore_opts -B '$(cat "$__object/parameter/backingstore")'" # add parameters if available bdev_add_if_available dir @@ -149,7 +149,7 @@ LXC # at last, apply custom options if [ -f "$__object/parameter/template-opts" ]; then - while read line; do + while read -r line; do template_opts="$template_opts $line" done < "$__object/parameter/template-opts" fi diff --git a/cdist/conf/type/__lxc_container/manifest b/cdist/conf/type/__lxc_container/manifest index d903fa1c..4a74ea18 100755 --- a/cdist/conf/type/__lxc_container/manifest +++ b/cdist/conf/type/__lxc_container/manifest @@ -93,7 +93,7 @@ fi write_multi_param() { if ! [ -f "$__object/parameter/$1" ]; then return 0; fi - while read line; do + while read -r line; do if [ "$line" = "-" ]; then # append stdin cat "$__object/stdin" From 93506d2113e1d05202527639efe883a5b44b220d Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 8 Jul 2020 00:17:12 +0300 Subject: [PATCH 015/411] [__download] curl follow redirects --- cdist/conf/type/__download/explorer/remote_cmd | 2 +- cdist/conf/type/__download/gencode-local | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__download/explorer/remote_cmd b/cdist/conf/type/__download/explorer/remote_cmd index fbd4d84c..e3e35b45 100755 --- a/cdist/conf/type/__download/explorer/remote_cmd +++ b/cdist/conf/type/__download/explorer/remote_cmd @@ -6,7 +6,7 @@ then elif command -v curl > /dev/null then - cmd="curl -o - '%s'" + cmd="curl -L -o - '%s'" elif command -v fetch > /dev/null then diff --git a/cdist/conf/type/__download/gencode-local b/cdist/conf/type/__download/gencode-local index 339827c2..571d2c3c 100755 --- a/cdist/conf/type/__download/gencode-local +++ b/cdist/conf/type/__download/gencode-local @@ -25,7 +25,7 @@ then elif command -v curl > /dev/null then - cmd="curl -o - '%s'" + cmd="curl -L -o - '%s'" elif command -v fetch > /dev/null then From e9062662868d7677a235889ba39a6091085388f0 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 8 Jul 2020 00:20:55 +0300 Subject: [PATCH 016/411] [__download] s/variable/format specification/ --- cdist/conf/type/__download/man.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index eafa9dfc..6ec0b19a 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -44,14 +44,14 @@ cmd-get Command used for downloading. Command must output to ``stdout``. Parameter will be used for ``printf`` and must include only one - variable ``%s`` which will become URL. + format specification ``%s`` which will become URL. For example: ``wget -O - '%s'``. cmd-sum Command used for checksum calculation. Command output and ``--sum`` parameter must match. Parameter will be used for ``printf`` and must include only one - variable ``%s`` which will become destination. + format specification ``%s`` which will become destination. For example: ``md5sum '%s' | awk '{print $1}'``. From cb9933b4a0d343a059899101810b6ee86fc87dbc Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 8 Jul 2020 12:43:55 +0200 Subject: [PATCH 017/411] Fix state -> state_is --- cdist/conf/type/__download/gencode-remote | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__download/gencode-remote b/cdist/conf/type/__download/gencode-remote index 89ba72af..029a0801 100755 --- a/cdist/conf/type/__download/gencode-remote +++ b/cdist/conf/type/__download/gencode-remote @@ -19,7 +19,7 @@ then echo 'downloaded' > "$__messages_out" fi -if [ -f "$__object/parameter/onchange" ] && [ "$state" != "present" ] +if [ -f "$__object/parameter/onchange" ] && [ "$state_is" != "present" ] then cat "$__object/parameter/onchange" fi From b8752e9ee390e983c1ce6467761aca8101b6548d Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 10 Jul 2020 21:03:35 +0200 Subject: [PATCH 018/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index b823421b..54c42bde 100644 --- a/docs/changelog +++ b/docs/changelog @@ -7,6 +7,7 @@ next: * Type __package_opkg: Add locking (Dennis Camera) * Type __hosts: Add --alias parameter (Dennis Camera) * Type __user: Fix shadow explorer for OpenBSD (Dennis Camera) + * Core: Make emulator-part code consistent; remove faulty warning (Darko Poljak) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From 304d974f7bbb488ba80a522cb0f01fc3b79aa1b2 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 11 Jul 2020 18:18:55 +0200 Subject: [PATCH 019/411] [__lxc_container] moved config diff incl. gencode-local to gencode-remote Rather than the config handling is split up over gencode-{local,remote} and the manifest, it is now completly moved to the gencode-remote script. This avoids complexity, file uploading and direct ssh interactions as it was used before. The diff creation was extracted into an extra script, and the gencode-local was removed. Now, the gencode-remote script executes the config diff script before the short curcuit and uses here-documents and pipes if the diff is required on the remote host. With this, the script size grows, but should be no difference if the file is downloaded temporarily. With this, the remote handling of an empty configuration file was enhanced by handling it completely into the code-remote script (hope escaping works correctly). --- .../type/__lxc_container/diff-conf-changes.sh | 72 +++++++++++++++++++ cdist/conf/type/__lxc_container/gencode-local | 69 ------------------ .../conf/type/__lxc_container/gencode-remote | 30 +++++--- cdist/conf/type/__lxc_container/manifest | 59 --------------- 4 files changed, 91 insertions(+), 139 deletions(-) create mode 100755 cdist/conf/type/__lxc_container/diff-conf-changes.sh delete mode 100755 cdist/conf/type/__lxc_container/gencode-local diff --git a/cdist/conf/type/__lxc_container/diff-conf-changes.sh b/cdist/conf/type/__lxc_container/diff-conf-changes.sh new file mode 100755 index 00000000..37d9f195 --- /dev/null +++ b/cdist/conf/type/__lxc_container/diff-conf-changes.sh @@ -0,0 +1,72 @@ +#!/bin/sh -e +# diff-conf-changes.sh + +# This script handles the configuration given to the type. It will be diffed against the existing +# container options and write the "to be done"-options to a separate file. +# +# Output files in "$__object/files/" : +# - config-{present,absent} +# - config.add +# - config.del + + +# Function to read multiple parameter input for configuration and print it to a single file. +# It will handle file paths as well as the stdin. Instead of the file, the content will be printed. +# +# Parameters: +# 1: parameter name +# 2: file to print +write_multi_param() { + if ! [ -f "$__object/parameter/$1" ]; then return 0; fi + + while read -r line; do + if [ "$line" = "-" ]; then + # append stdin + cat "$__object/stdin" + elif [ -f "$line" ]; then + # append file content + cat "$line" + else + # print out content + printf "%s\n" "$line" + fi + done < "$__object/parameter/$1" +} + +# Function to get rid of whitespaces inside of key-value pairs. It will clear all of these. +# +# Parameters: +# 1: the file which should be handled +trimm_whitespaces() { + mv "$1" "$1"~ # backup file to read write back original file + grep -E -v "^([[:blank:]]*)(#|$)" "$1"~ \ + | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' \ + > "$1" + rm -f "$1"~ +} + + +# Only required if container will not be absent +# prepare the wanted configuration lines +if [ "$(cat "$__object/parameter/state")" != "absent" ]; then + # create the files directory + mkdir "$__object/files/" + + # Summary of the locally given configuration options + # config-present + conffile="$__object/files/config-present" + write_multi_param config > "$conffile" + trimm_whitespaces "$conffile" + # config-absent + absentfile="$__object/files/config-absent" + write_multi_param config-absent > "$absentfile" + trimm_whitespaces "$absentfile" + + # Diff the configuration options by removing duplicate config options + # config.add + grep -v -f "$__object/explorer/config" -f "$__object/files/config-absent" \ + "$__object/files/config-present" > "$__object/files/config.add" || true + # config.del + grep -f "$__object/explorer/config" \ + "$__object/files/config-absent" > "$__object/files/config.del" || true +fi diff --git a/cdist/conf/type/__lxc_container/gencode-local b/cdist/conf/type/__lxc_container/gencode-local deleted file mode 100755 index e0572bb4..00000000 --- a/cdist/conf/type/__lxc_container/gencode-local +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh -e -# gencode-local - -# This uploads the diff of the configuration file, which is applied by gencode-remote - - -# Get required parameters -name="$__object/parameter/name" -if [ -f "$name" ]; then - name="$(cat "$name")" -else - name="$__object_id" -fi - -state_is="$(cat "$__object/explorer/state")" -state_should="$(cat "$__object/parameter/state")" - - -# Check the configurations only if the container exists -if [ "$state_should" != "absent" ]; then - # do changes - - # predict remote lxc config file - container_config="$(cat "$__object/explorer/lxcpath")/$name/config" - - # IPv6 fix - if echo "${__target_host}" | grep -q -E '^[0-9a-fA-F:]+$' - then - my_target_host="[${__target_host}]" - else - my_target_host="${__target_host}" - fi - - # create remote container directory if container is not yet available - if [ "$state_is" = "absent" ]; then - # this must be done because the container will be created after the configuration is uploaded - # would also be possible to do everything in gencode-remote to keep the order - $__remote_exec $__target_host "mkdir $(dirname "$container_config")" - fi - - - # config-present - # remove all config lines from config-present that are already set or absent anyway - if grep -v -f "$__object/explorer/config" -f "$__object/files/config-absent" \ - "$__object/files/config-present" > "$__object/files/config.add"; then - - # get temp file name - add_dest="$($__remote_exec $__target_host "mktemp $container_config-add.XXXXXXXXXX")" - printf "%s" "$add_dest" > "$__object/files/remote-tmpfile_add" - # upload delta - cat < "$__object/files/config.del"; then - - # get temp file name - del_dest="$($__remote_exec $__target_host "mktemp $container_config-del.XXXXXXXXXX")" - printf "%s" "$del_dest" > "$__object/files/remote-tmpfile_del" - # upload delta - cat < $file' will not work (> opens before command reads it) + if [ -s "$__object/files/config.del" ]; then cat < "\$tmpconfig" -rm -rf "$(cat "${tmppath}_del")" +grep -v -f - <<'ABSENT' "$container_config" > "\$tmpconfig" +$(cat "$__object/files/config.del") +ABSENT DONE fi # check if smth. to be added - if [ -f "${tmppath}_add" ]; then + if [ -s "$__object/files/config.add" ]; then cat <> "\$tmpconfig" -rm -rf "$(cat "${tmppath}_add")" +cat <<'PRESENT' >> "\$tmpconfig" +$(cat "$__object/files/config.add") +PRESENT DONE fi diff --git a/cdist/conf/type/__lxc_container/manifest b/cdist/conf/type/__lxc_container/manifest index 4a74ea18..99cfa1c0 100755 --- a/cdist/conf/type/__lxc_container/manifest +++ b/cdist/conf/type/__lxc_container/manifest @@ -76,62 +76,3 @@ if [ -f "$param/backingstore" ]; then fi fi fi - - - - -# ============================== # -# == CONFIGURATION HANDLING == # -# ============================== # - -# Function to read multiple parameter input for configuration and print it to a single file. -# It will handle file paths as well as the stdin. Instead of the file, the content will be printed. -# -# Parameters: -# 1: parameter name -# 2: file to print -write_multi_param() { - if ! [ -f "$__object/parameter/$1" ]; then return 0; fi - - while read -r line; do - if [ "$line" = "-" ]; then - # append stdin - cat "$__object/stdin" - elif [ -f "$line" ]; then - # append file content - cat "$line" - else - # print out content - printf "%s\n" "$line" - fi - done < "$__object/parameter/$1" -} - -# Function to get rid of whitespaces inside of key-value pairs. It will clear all of these. -# -# Parameters: -# 1: the file which should be handled -trimm_whitespaces() { - mv "$1" "$1"~ # backup file to see original content - grep -E -v "^([[:blank:]]*)(#|$)" "$1"~ \ - | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' \ - > "$1" -} - - -# Only required if container will not be absent -# prepare the wanted configuration lines -if [ "$(cat "$__object/parameter/state")" != "absent" ]; then - # Create the files directory - mkdir "$__object/files/" - - # Create the file of the locally configuration - conffile="$__object/files/config-present" - write_multi_param config > "$conffile" - trimm_whitespaces "$conffile" - - # Create the file of the absent configuration - absentfile="$__object/files/config-absent" - write_multi_param config-absent > "$absentfile" - trimm_whitespaces "$absentfile" -fi From a5ae26116bd611fcab76c0383998fb4b05f1ae1d Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 11 Jul 2020 18:57:47 +0200 Subject: [PATCH 020/411] [type/__hosts] Fix when used without --alias --- cdist/conf/type/__hosts/manifest | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/cdist/conf/type/__hosts/manifest b/cdist/conf/type/__hosts/manifest index 0d9e61f8..8103ebd5 100755 --- a/cdist/conf/type/__hosts/manifest +++ b/cdist/conf/type/__hosts/manifest @@ -19,21 +19,24 @@ # along with this program. If not, see . # -set -e -u +set -e hostname=$__object_id -state=$(cat "$__object/parameter/state") -marker="# __hosts/$hostname" +state=$(cat "${__object}/parameter/state") +marker="# __hosts/${hostname}" -if [ "$state" = 'absent' ] +if test "${state}" != 'absent' then - set -- --regex "$marker" -else - ip=$(cat "$__object/parameter/ip") - aliases=$(while read -r a; do printf '\t%s' "$a"; done <"$__object/parameter/alias") + ip=$(cat "${__object}/parameter/ip") + if test -s "${__object}/parameter/alias" + then + aliases=$(while read -r a; do printf '\t%s' "$a"; done <"$__object/parameter/alias") + fi set -- --line "$(printf '%s\t%s%s %s' \ - "$ip" "$hostname" "$aliases" "$marker")" + "${ip}" "${hostname}" "${aliases}" "${marker}")" +else + set -- --regex "$(echo "${marker}" | sed -e 's/\./\\./')$" fi -__line "__hosts/$hostname" --file /etc/hosts --state "$state" "$@" +__line "/etc/hosts:${hostname}" --file /etc/hosts --state "${state}" "$@" From 19514662b022c79c4e6a56573c32dad45055310c Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 12 Jul 2020 12:24:00 +0200 Subject: [PATCH 021/411] [type/{__file/__directory}] Fix typo --- cdist/conf/type/__directory/explorer/stat | 2 +- cdist/conf/type/__file/explorer/stat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__directory/explorer/stat b/cdist/conf/type/__directory/explorer/stat index a7dc8431..422c5819 100755 --- a/cdist/conf/type/__directory/explorer/stat +++ b/cdist/conf/type/__directory/explorer/stat @@ -30,7 +30,7 @@ fallback() { 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) + group=$(awk -F: -v gid="$gid" '$3 == gid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) mode_text=$(echo "$ls_line" | awk '{ print $1 }') mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[st]/)*2^(9+i/3)}printf("%04o",k)}') diff --git a/cdist/conf/type/__file/explorer/stat b/cdist/conf/type/__file/explorer/stat index 231768f6..3f971488 100755 --- a/cdist/conf/type/__file/explorer/stat +++ b/cdist/conf/type/__file/explorer/stat @@ -31,7 +31,7 @@ fallback() { 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) + group=$(awk -F: -v gid="$gid" '$3 == gid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) mode_text=$(echo "$ls_line" | awk '{ print $1 }') mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[st]/)*2^(9+i/3)}printf("%04o",k)}') From 9fb7e151b889214576cb891595a68ca8c6196d45 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 12 Jul 2020 12:31:55 +0200 Subject: [PATCH 022/411] [type/{__file/__directory}] Remove special Solaris blocks Solaris 11 has GNU stat (handled by *) Solaris 10 (and older?) does not have stat (handled by failing command -v stat) On Solaris 10 (at least on UFS), setgid cannot be set on directories. Unlike on other systems `chmod 2400` is not `-r----S---`, but `-r----l---`. --- cdist/conf/type/__directory/explorer/stat | 40 +++-------------------- cdist/conf/type/__file/explorer/stat | 40 +++-------------------- 2 files changed, 9 insertions(+), 71 deletions(-) diff --git a/cdist/conf/type/__directory/explorer/stat b/cdist/conf/type/__directory/explorer/stat index 422c5819..f817cb02 100755 --- a/cdist/conf/type/__directory/explorer/stat +++ b/cdist/conf/type/__directory/explorer/stat @@ -33,7 +33,7 @@ fallback() { group=$(awk -F: -v gid="$gid" '$3 == gid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) mode_text=$(echo "$ls_line" | awk '{ print $1 }') - mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[st]/)*2^(9+i/3)}printf("%04o",k)}') + mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[lst]/)*2^(9+i/3)}printf("%04o",k)}') printf 'type: %s\nowner: %d %s\ngroup: %d %s\nmode: %s %s\n' \ "$("$__type_explorer/type")" \ @@ -45,11 +45,10 @@ fallback() { # nothing to work with, nothing we could do [ -e "$destination" ] || exit 0 -if ! command -v stat >/dev/null -then +command -v stat >/dev/null 2>&1 || { fallback exit -fi +} case $("$__explorer/os") in @@ -60,42 +59,13 @@ group: %Dg %Sg mode: %Mp%03Lp %Sp ' "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; - solaris) - ls1="$( ls -ld "$destination" )" - ls2="$( ls -ldn "$destination" )" - - if [ -f "$__object/parameter/mode" ] - then mode_should="$( cat "$__object/parameter/mode" )" - fi - - # yes, it is ugly hack, but if you know better way... - if [ -z "$( find "$destination" -perm "$mode_should" )" ] - then octets=888 - else octets="$( echo "$mode_should" | sed 's/^0//' )" - fi - - case "$( echo "$ls1" | cut -c1-1 )" in - -) echo 'type: regular file' ;; - d) echo 'type: directory' ;; - esac - - echo "owner: $( echo "$ls2" \ - | awk '{print $3}' ) $( echo "$ls1" \ - | awk '{print $3}' )" - - echo "group: $( echo "$ls2" \ - | awk '{print $4}' ) $( echo "$ls1" \ - | awk '{print $4}' )" - - echo "mode: $octets $( echo "$ls1" | awk '{print $1}' )" - ;; *) # 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 + stat -c 'type: %F owner: %u %U group: %g %G mode: %04a %A' "$destination" 2>/dev/null || fallback - ;; + ;; esac diff --git a/cdist/conf/type/__file/explorer/stat b/cdist/conf/type/__file/explorer/stat index 3f971488..29b3c8a3 100755 --- a/cdist/conf/type/__file/explorer/stat +++ b/cdist/conf/type/__file/explorer/stat @@ -34,7 +34,7 @@ fallback() { group=$(awk -F: -v gid="$gid" '$3 == gid { print $1; f=1 } END { if (!f) print "UNKNOWN" }' /etc/group) mode_text=$(echo "$ls_line" | awk '{ print $1 }') - mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[st]/)*2^(9+i/3)}printf("%04o",k)}') + mode=$(echo "$mode_text" | awk '{for(i=8;i>=0;--i){c=substr($1,10-i,1);k+=((c~/[rwxst]/)*2^i);if(!(i%3))k+=(tolower(c)~/[lst]/)*2^(9+i/3)}printf("%04o",k)}') size=$(echo "$ls_line" | awk '{ print $5 }') links=$(echo "$ls_line" | awk '{ print $2 }') @@ -53,11 +53,10 @@ fallback() { [ -e "$destination" ] || exit 0 -if ! command -v stat >/dev/null -then +command -v stat >/dev/null 2>&1 || { fallback exit -fi +} case $("$__explorer/os") @@ -71,37 +70,6 @@ size: %Dz links: %Dl ' "$destination" | awk '/^type/ { print tolower($0); next } { print }' ;; - solaris) - ls1="$( ls -ld "$destination" )" - ls2="$( ls -ldn "$destination" )" - - if [ -f "$__object/parameter/mode" ] - then mode_should="$( cat "$__object/parameter/mode" )" - fi - - # yes, it is ugly hack, but if you know better way... - if [ -z "$( find "$destination" -perm "$mode_should" )" ] - then octets=888 - else octets="$( echo "$mode_should" | sed 's/^0//' )" - fi - - case "$( echo "$ls1" | cut -c1-1 )" in - -) echo 'type: regular file' ;; - d) echo 'type: directory' ;; - esac - - echo "owner: $( echo "$ls2" \ - | awk '{print $3}' ) $( echo "$ls1" \ - | awk '{print $3}' )" - - echo "group: $( echo "$ls2" \ - | awk '{print $4}' ) $( echo "$ls1" \ - | awk '{print $4}' )" - - echo "mode: $octets $( echo "$ls1" | awk '{print $1}' )" - echo "size: $( echo "$ls1" | awk '{print $5}' )" - echo "links: $( echo "$ls1" | awk '{print $2}' )" - ;; *) # 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 @@ -112,5 +80,5 @@ group: %g %G mode: %04a %A size: %s links: %h' "$destination" 2>/dev/null || fallback - ;; + ;; esac From 6d29b0542a82f6cf12429291aec488c649bf1323 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sun, 12 Jul 2020 20:37:59 +0200 Subject: [PATCH 023/411] [__lxc_container] better support config modifications at creation time When a container is created, the configuration is unknown to the explorer. To do the job without the knowleage, following is added: If the container will be created, it adds all absent configuration options to be deleted. Because it do not know which configuration options exist, it tries to remove all if there exists. This behaviour is extended for containers that will be cloned: Because the container who will be cloned is known and it will copy the config nearly one to one, so it will read this configuration. The removal of configuration is generally improved by generating a pattern to ignore spaces at the beginning, near the equal sign and at the end. This deletes the correct configuration lines even they have malformed whitespaces. --- .../type/__lxc_container/diff-conf-changes.sh | 15 +++++++++++++- .../conf/type/__lxc_container/explorer/config | 20 +++++++++++++++++-- .../conf/type/__lxc_container/gencode-remote | 8 ++++++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/cdist/conf/type/__lxc_container/diff-conf-changes.sh b/cdist/conf/type/__lxc_container/diff-conf-changes.sh index 37d9f195..d860a8b8 100755 --- a/cdist/conf/type/__lxc_container/diff-conf-changes.sh +++ b/cdist/conf/type/__lxc_container/diff-conf-changes.sh @@ -46,9 +46,13 @@ trimm_whitespaces() { } +# save states +state_should="$(cat "$__object/parameter/state")" +state_is="$(cat "$__object/explorer/state")" + # Only required if container will not be absent # prepare the wanted configuration lines -if [ "$(cat "$__object/parameter/state")" != "absent" ]; then +if [ "$state_should" != "absent" ]; then # create the files directory mkdir "$__object/files/" @@ -69,4 +73,13 @@ if [ "$(cat "$__object/parameter/state")" != "absent" ]; then # config.del grep -f "$__object/explorer/config" \ "$__object/files/config-absent" > "$__object/files/config.del" || true + + + # fallback: if template parameter exists and container currently absent; try to remove all configs + # If the container is currently absent, nothing will be removed, even it's in the default config + # In this case, it will try to delete every configuration option to be sure + # only the cloning configuration is known, but not if the container will be created in an other way + if [ "$state_is" = "absent" ] && ! [ -f "$__object/parameter/clone" ]; then + cp "$__object/files/config-absent" "$__object/files/config.del" + fi fi diff --git a/cdist/conf/type/__lxc_container/explorer/config b/cdist/conf/type/__lxc_container/explorer/config index 287a5063..16fcf14a 100755 --- a/cdist/conf/type/__lxc_container/explorer/config +++ b/cdist/conf/type/__lxc_container/explorer/config @@ -22,8 +22,24 @@ else fi -# assemble the container configuration file -config="$lxcpath/$name/config" +# if the container will be cloned, use the configuration of the container to clone from +# else, just use the normal container configuration +clone="$__object/parameter/clone" +if [ -f "$clone" ] && [ "$("$__type_explorer/state")" = "absent" ]; then + clone="$(cat "$clone")" + clonepath="$__object/parameter/clonepath" + if [ -f "$clonepath" ]; then + clonepath="$(cat "$clonepath")" + else + clonepath="$lxcpath" + fi + + # set the config path of the container to clone from + config="$clonepath/$clone/config" +else + # assemble the configuration file of the container + config="$lxcpath/$name/config" +fi # check if the file exist, else the container is absent if [ -r "$config" ]; then diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index ca2f2827..bd3f49b6 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -205,10 +205,14 @@ DONE # check if smth. to be deleted # must be before adding, because it takes the content of the original file # because 'cat $file > $file' will not work (> opens before command reads it) + # will create extended regex pattern for grep with malformed spaces if [ -s "$__object/files/config.del" ]; then cat < "\$tmpconfig" -$(cat "$__object/files/config.del") +grep -v -E -f - <<'ABSENT' "$container_config" > "\$tmpconfig" +$(awk -v FS=' = ' -v OFS=' = ' -v blank='[[:blank:]]*' ' +function ntostring(n) { ret=""; for(i=n; i<=NF; i++) ret=ret $i (i Date: Sun, 12 Jul 2020 21:30:44 +0200 Subject: [PATCH 024/411] [__lxc_container] handle $empty_conf for --no-default-config correctly Fixed wrong variable spelling and correct check to remove the tempfile again (forgotten from 304d974f). --- cdist/conf/type/__lxc_container/gencode-remote | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index bd3f49b6..ddba593a 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -132,10 +132,11 @@ LXC create_opts="" if [ -f "$__object/parameter/no-default-config" ]; then # generate a random empty file and append + # maybe work with an nonexistant file - but just be correct cat < Date: Mon, 13 Jul 2020 05:44:26 +0000 Subject: [PATCH 025/411] Merge branch 'bugfix/postfix-master-option' into '6.6' Fix broken --option parameter in __postfix_master type See merge request ungleich-public/cdist!905 (cherry picked from commit 2f433a1458f3a1f7f8859e9ae165178a0ec5b7a0) 9496b234 The option parameter is actually multi-valued 4009bbd7 Protect postfix variables in options --- cdist/conf/type/__postfix_master/gencode-remote | 2 +- cdist/conf/type/__postfix_master/parameter/optional | 1 - cdist/conf/type/__postfix_master/parameter/optional_multiple | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 cdist/conf/type/__postfix_master/parameter/optional_multiple diff --git a/cdist/conf/type/__postfix_master/gencode-remote b/cdist/conf/type/__postfix_master/gencode-remote index 7c109a69..73de1088 100755 --- a/cdist/conf/type/__postfix_master/gencode-remote +++ b/cdist/conf/type/__postfix_master/gencode-remote @@ -67,7 +67,7 @@ case "$state_should" in remove_entry fi cat << DONE -cat >> "$config" << ${__type##*/}_DONE +cat >> "$config" << "${__type##*/}_DONE" $(cat "$entry") ${__type##*/}_DONE DONE diff --git a/cdist/conf/type/__postfix_master/parameter/optional b/cdist/conf/type/__postfix_master/parameter/optional index 792b42c5..410482b8 100644 --- a/cdist/conf/type/__postfix_master/parameter/optional +++ b/cdist/conf/type/__postfix_master/parameter/optional @@ -4,6 +4,5 @@ unpriv chroot wakeup maxproc -option comment state diff --git a/cdist/conf/type/__postfix_master/parameter/optional_multiple b/cdist/conf/type/__postfix_master/parameter/optional_multiple new file mode 100644 index 00000000..01925a15 --- /dev/null +++ b/cdist/conf/type/__postfix_master/parameter/optional_multiple @@ -0,0 +1 @@ +option From 8903540e9106db93e490515c07929a207326be77 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 13 Jul 2020 07:54:12 +0200 Subject: [PATCH 026/411] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index 54c42bde..dac9cbce 100644 --- a/docs/changelog +++ b/docs/changelog @@ -8,6 +8,8 @@ next: * Type __hosts: Add --alias parameter (Dennis Camera) * Type __user: Fix shadow explorer for OpenBSD (Dennis Camera) * Core: Make emulator-part code consistent; remove faulty warning (Darko Poljak) + * Types __file, __directory: Support setuid, setguid, sticky bits (Dennis Camera) + * Type __postfix_master: Fix --option parameter and option expansion (Daniel Fancsali) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From 9fd892a22413104b3a34554588468cd94d1a599e Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Mon, 13 Jul 2020 20:31:18 +0200 Subject: [PATCH 027/411] [__lxc_container] add --restart-if-changed parameter to apply changes This parameter restarts the container if configuration changes and it is already running and should keept running. It handles the freeze state, because it would be expected to apply changes in this state, too. --- .../conf/type/__lxc_container/gencode-remote | 49 ++++++++++++++++++- cdist/conf/type/__lxc_container/man.rst | 6 ++- .../type/__lxc_container/parameter/boolean | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index ddba593a..480d7d41 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -234,8 +234,55 @@ DONE rm -rf "$container_config" mv "\$tmpconfig" "$container_config" DONE - # write message echo "config" >> "$__messages_out" + + + # restart container only if it is running + # do not echo messages start/stop or melt/start/stop/freeze; only restart to avoid junk + case "$state_is" in + running|frozen) + # only do it if the container will run again + case "$state_should" in + present|running|frozen) + # su stuff + cat <> "$__messages_out" + fi + fi + + # ending + echo "restart" >> "$__messages_out" + echo "SU" + ;; + esac + ;; + esac fi diff --git a/cdist/conf/type/__lxc_container/man.rst b/cdist/conf/type/__lxc_container/man.rst index d0abf2e2..7d1f6522 100644 --- a/cdist/conf/type/__lxc_container/man.rst +++ b/cdist/conf/type/__lxc_container/man.rst @@ -70,7 +70,11 @@ config-absent BOOLEAN PARAMETERS ------------------ -None. + +restart-if-changed + Restarts the container if configuration changes. It stop and start the container that new configuration + can be applied. If it whould be restarted with ``lxc-stop -n $name --reboot``, configuration changes + would be ignored. CREATE PARAMETERS ----------------- diff --git a/cdist/conf/type/__lxc_container/parameter/boolean b/cdist/conf/type/__lxc_container/parameter/boolean index caf89a8e..724fa14b 100644 --- a/cdist/conf/type/__lxc_container/parameter/boolean +++ b/cdist/conf/type/__lxc_container/parameter/boolean @@ -1 +1,2 @@ no-default-config +restart-if-changed From 5d6f90555bdf60354dc298c87e06cf8a551a2b1c Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Mon, 13 Jul 2020 21:16:18 +0200 Subject: [PATCH 028/411] [__lxc_container] s/\t/ /g; renewed todo.txt file Replaced all tabs with 4 spaces (~/.vimrc is modified, too). The issue.txt is not required anymore and the todo.txt was updated. --- .../type/__lxc_container/diff-conf-changes.sh | 86 ++-- .../conf/type/__lxc_container/explorer/config | 32 +- .../type/__lxc_container/explorer/lxcpath | 18 +- .../conf/type/__lxc_container/explorer/state | 24 +- .../conf/type/__lxc_container/gencode-remote | 396 +++++++++--------- cdist/conf/type/__lxc_container/issue.txt | 1 - cdist/conf/type/__lxc_container/manifest | 86 ++-- cdist/conf/type/__lxc_container/todo.txt | 10 +- 8 files changed, 328 insertions(+), 325 deletions(-) delete mode 100644 cdist/conf/type/__lxc_container/issue.txt diff --git a/cdist/conf/type/__lxc_container/diff-conf-changes.sh b/cdist/conf/type/__lxc_container/diff-conf-changes.sh index d860a8b8..b18b9fe4 100755 --- a/cdist/conf/type/__lxc_container/diff-conf-changes.sh +++ b/cdist/conf/type/__lxc_container/diff-conf-changes.sh @@ -17,20 +17,20 @@ # 1: parameter name # 2: file to print write_multi_param() { - if ! [ -f "$__object/parameter/$1" ]; then return 0; fi + if ! [ -f "$__object/parameter/$1" ]; then return 0; fi - while read -r line; do - if [ "$line" = "-" ]; then - # append stdin - cat "$__object/stdin" - elif [ -f "$line" ]; then - # append file content - cat "$line" - else - # print out content - printf "%s\n" "$line" - fi - done < "$__object/parameter/$1" + while read -r line; do + if [ "$line" = "-" ]; then + # append stdin + cat "$__object/stdin" + elif [ -f "$line" ]; then + # append file content + cat "$line" + else + # print out content + printf "%s\n" "$line" + fi + done < "$__object/parameter/$1" } # Function to get rid of whitespaces inside of key-value pairs. It will clear all of these. @@ -38,11 +38,11 @@ write_multi_param() { # Parameters: # 1: the file which should be handled trimm_whitespaces() { - mv "$1" "$1"~ # backup file to read write back original file - grep -E -v "^([[:blank:]]*)(#|$)" "$1"~ \ - | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' \ - > "$1" - rm -f "$1"~ + mv "$1" "$1"~ # backup file to read write back original file + grep -E -v "^([[:blank:]]*)(#|$)" "$1"~ \ + | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' \ + > "$1" + rm -f "$1"~ } @@ -53,33 +53,33 @@ state_is="$(cat "$__object/explorer/state")" # Only required if container will not be absent # prepare the wanted configuration lines if [ "$state_should" != "absent" ]; then - # create the files directory - mkdir "$__object/files/" + # create the files directory + mkdir "$__object/files/" - # Summary of the locally given configuration options - # config-present - conffile="$__object/files/config-present" - write_multi_param config > "$conffile" - trimm_whitespaces "$conffile" - # config-absent - absentfile="$__object/files/config-absent" - write_multi_param config-absent > "$absentfile" - trimm_whitespaces "$absentfile" + # Summary of the locally given configuration options + # config-present + conffile="$__object/files/config-present" + write_multi_param config > "$conffile" + trimm_whitespaces "$conffile" + # config-absent + absentfile="$__object/files/config-absent" + write_multi_param config-absent > "$absentfile" + trimm_whitespaces "$absentfile" - # Diff the configuration options by removing duplicate config options - # config.add - grep -v -f "$__object/explorer/config" -f "$__object/files/config-absent" \ - "$__object/files/config-present" > "$__object/files/config.add" || true - # config.del - grep -f "$__object/explorer/config" \ - "$__object/files/config-absent" > "$__object/files/config.del" || true + # Diff the configuration options by removing duplicate config options + # config.add + grep -v -f "$__object/explorer/config" -f "$__object/files/config-absent" \ + "$__object/files/config-present" > "$__object/files/config.add" || true + # config.del + grep -f "$__object/explorer/config" \ + "$__object/files/config-absent" > "$__object/files/config.del" || true - # fallback: if template parameter exists and container currently absent; try to remove all configs - # If the container is currently absent, nothing will be removed, even it's in the default config - # In this case, it will try to delete every configuration option to be sure - # only the cloning configuration is known, but not if the container will be created in an other way - if [ "$state_is" = "absent" ] && ! [ -f "$__object/parameter/clone" ]; then - cp "$__object/files/config-absent" "$__object/files/config.del" - fi + # fallback: if template parameter exists and container currently absent; try to remove all configs + # If the container is currently absent, nothing will be removed, even it's in the default config + # In this case, it will try to delete every configuration option to be sure + # only the cloning configuration is known, but not if the container will be created in an other way + if [ "$state_is" = "absent" ] && ! [ -f "$__object/parameter/clone" ]; then + cp "$__object/files/config-absent" "$__object/files/config.del" + fi fi diff --git a/cdist/conf/type/__lxc_container/explorer/config b/cdist/conf/type/__lxc_container/explorer/config index 16fcf14a..5aa020e4 100755 --- a/cdist/conf/type/__lxc_container/explorer/config +++ b/cdist/conf/type/__lxc_container/explorer/config @@ -6,7 +6,7 @@ # abort if container will be absent - no config required if [ "$(cat "$__object/parameter/state")" = "absent" ]; then - exit 0 + exit 0 fi @@ -26,25 +26,25 @@ fi # else, just use the normal container configuration clone="$__object/parameter/clone" if [ -f "$clone" ] && [ "$("$__type_explorer/state")" = "absent" ]; then - clone="$(cat "$clone")" - clonepath="$__object/parameter/clonepath" - if [ -f "$clonepath" ]; then - clonepath="$(cat "$clonepath")" - else - clonepath="$lxcpath" - fi + clone="$(cat "$clone")" + clonepath="$__object/parameter/clonepath" + if [ -f "$clonepath" ]; then + clonepath="$(cat "$clonepath")" + else + clonepath="$lxcpath" + fi - # set the config path of the container to clone from - config="$clonepath/$clone/config" + # set the config path of the container to clone from + config="$clonepath/$clone/config" else - # assemble the configuration file of the container - config="$lxcpath/$name/config" + # assemble the configuration file of the container + config="$lxcpath/$name/config" fi # check if the file exist, else the container is absent if [ -r "$config" ]; then - # print configuration and strip files to just values - # grep will hide all comments and empty lines - all others must be key-values - # sed will uniform patterns, that no spaces will be problematic (before, in the middle and at end) - grep -E -v "^([[:blank:]]*)(#|$)" "$config" | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' + # print configuration and strip files to just values + # grep will hide all comments and empty lines - all others must be key-values + # sed will uniform patterns, that no spaces will be problematic (before, in the middle and at end) + grep -E -v "^([[:blank:]]*)(#|$)" "$config" | sed 's/^[[:blank:]]*//; s/[[:blank:]]*=[[:blank:]]*/ = /; s/[[:blank:]]*$//' fi diff --git a/cdist/conf/type/__lxc_container/explorer/lxcpath b/cdist/conf/type/__lxc_container/explorer/lxcpath index a4116b9b..e633cff6 100755 --- a/cdist/conf/type/__lxc_container/explorer/lxcpath +++ b/cdist/conf/type/__lxc_container/explorer/lxcpath @@ -9,15 +9,15 @@ lxcpath="$(cat "$__object/parameter/lxcpath" 2>/dev/null || true)" # lxcpath parameter if [ -z "$lxcpath" ]; then - user="$(cat "$__object/parameter/user")" + user="$(cat "$__object/parameter/user")" - # gather default value from config - if [ "$user" != "$USER" ]; then - su -s "$(which -- lxc-config)" -- "$user" lxc.lxcpath - else - lxc-config lxc.lxcpath - fi + # gather default value from config + if [ "$user" != "$USER" ]; then + su -s "$(which -- lxc-config)" -- "$user" lxc.lxcpath + else + lxc-config lxc.lxcpath + fi else - # output the parameter - echo "$lxcpath" + # output the parameter + echo "$lxcpath" fi diff --git a/cdist/conf/type/__lxc_container/explorer/state b/cdist/conf/type/__lxc_container/explorer/state index c3c7f30f..86831ce2 100755 --- a/cdist/conf/type/__lxc_container/explorer/state +++ b/cdist/conf/type/__lxc_container/explorer/state @@ -19,27 +19,27 @@ lxcpath="$(cat "$__object/parameter/lxcpath" 2>/dev/null || true)" # assemble optional parameters LXC_PARAM="" if [ "$lxcpath" ]; then - # shellcheck disable=SC2089 - LXC_PARAM="$LXC_PARAM -P \"$lxcpath\"" + # shellcheck disable=SC2089 + LXC_PARAM="$LXC_PARAM -P \"$lxcpath\"" fi # function to get information lxc_info() { - # shellcheck disable=SC2090 disable=SC2086 - if [ "$user" != "$USER" ]; then - su -s "$(which -- lxc-info)" -- "$user" $LXC_PARAM -n "$name" -H "$@" - else - lxc-info $LXC_PARAM -n "$name" -H "$@" - fi + # shellcheck disable=SC2090 disable=SC2086 + if [ "$user" != "$USER" ]; then + su -s "$(which -- lxc-info)" -- "$user" $LXC_PARAM -n "$name" -H "$@" + else + lxc-info $LXC_PARAM -n "$name" -H "$@" + fi } # the lxc-info command will exit non-zero if container not exist if ! lxc_info -S >/dev/null 2>&1; then - # not exist - echo "absent" + # not exist + echo "absent" else - # print state (command output matches to type states) - lxc_info -s | tr '[:upper:]' '[:lower:]' + # print state (command output matches to type states) + lxc_info -s | tr '[:upper:]' '[:lower:]' fi diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index 480d7d41..f9e4dceb 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -44,31 +44,31 @@ fi # shortcut for checking config changes # returns success (0) if there are changes config_changes() { - if [ -s "$__object/files/config.add" ] || [ -s "$__object/files/config.del" ]; then - return 0 - else - return 1 - fi + if [ -s "$__object/files/config.add" ] || [ -s "$__object/files/config.del" ]; then + return 0 + else + return 1 + fi } # shortcut to add bdev parameters if available # $1: $__object parameter name without "bdev-" # $2: target parameter flag (like --foo), else "--$1" will be used bdev_add_if_available() { - _param_path="$__object/parameter/bdev-$1" - if [ -f "$_param_path" ]; then - backingstore_opts="$backingstore_opts ${2:---$1} '$(cat "$_param_path")'" - fi + _param_path="$__object/parameter/bdev-$1" + if [ -f "$_param_path" ]; then + backingstore_opts="$backingstore_opts ${2:---$1} '$(cat "$_param_path")'" + fi } # shortcut to add template parameters if available # $1: $__object parameter # $2: target parameter flag (like --foo), else "--$1" will be used template_add_if_available() { - _param_path="$__object/parameter/$1" - if [ -f "$_param_path" ]; then - template_opts="$template_opts ${2:---$1} '$(cat "$_param_path")'" - fi + _param_path="$__object/parameter/$1" + if [ -f "$_param_path" ]; then + template_opts="$template_opts ${2:---$1} '$(cat "$_param_path")'" + fi } @@ -81,291 +81,291 @@ if [ "$state_is" = "$state_should" ] && ( ! config_changes ); then exit; fi # handle if the container should exist or not case "$state_should" in - # all states where the container should exist - present|running|stopped|frozen) - # only relevant if the container does not exist before - if [ "$state_is" = "absent" ]; then - # change privileges (too complex to make exceptions) - cat </dev/null || true)" + # check, if the container should be created or cloned + if [ -f "$__object/parameter/clone" ]; then + copy_from="$(cat "$__object/parameter/clone")" + copypath="$(cat "$__object/parameter/clonepath" 2>/dev/null || true)" - # assemble own optional lxc options - lxc_opts="" - if [ -n "$copypath" ]; then - # this is set as the default $lxcpath, because it is the origin - lxc_opts="$lxc_opts -P \"$copypath\"" - fi - if [ -n "$lxcpath" ]; then - # this is set as the newpath, because it is the destination - lxc_opts="$lxc_opts -p \"$lxcpath\"" - fi + # assemble own optional lxc options + lxc_opts="" + if [ -n "$copypath" ]; then + # this is set as the default $lxcpath, because it is the origin + lxc_opts="$lxc_opts -P \"$copypath\"" + fi + if [ -n "$lxcpath" ]; then + # this is set as the newpath, because it is the destination + lxc_opts="$lxc_opts -p \"$lxcpath\"" + fi - # print lxc-copy code (because of the lxcpath thing, $LXC_PARAM conflicts) - cat <> "$__messages_out" - fi - ;; + # write to the message system + echo "create" >> "$__messages_out" + fi + ;; - # list other states to get a correct error message in the wildcard case - absent) - ;; + # list other states to get a correct error message in the wildcard case + absent) + ;; - # error handling: invalid state - *) - printf "Container '%s' in unknown state %s\n" "$name" "$state_should" >&2 - exit 2 - ;; + # error handling: invalid state + *) + printf "Container '%s' in unknown state %s\n" "$name" "$state_should" >&2 + exit 2 + ;; esac # Check the configurations only if the container exists and there are changes if config_changes; then - # generate config path - container_config="$(cat "$__object/explorer/lxcpath")/$name/config" - # create remote tmpfile for config - cat < $file' will not work (> opens before command reads it) - # will create extended regex pattern for grep with malformed spaces - if [ -s "$__object/files/config.del" ]; then - cat < $file' will not work (> opens before command reads it) + # will create extended regex pattern for grep with malformed spaces + if [ -s "$__object/files/config.del" ]; then + cat < "\$tmpconfig" $(awk -v FS=' = ' -v OFS=' = ' -v blank='[[:blank:]]*' ' function ntostring(n) { ret=""; for(i=n; i<=NF; i++) ret=ret $i (i> "\$tmpconfig" $(cat "$__object/files/config.add") PRESENT DONE - fi + fi - # apply all changes - cat <> "$__messages_out" + echo "config" >> "$__messages_out" - # restart container only if it is running - # do not echo messages start/stop or melt/start/stop/freeze; only restart to avoid junk - case "$state_is" in - running|frozen) - # only do it if the container will run again - case "$state_should" in - present|running|frozen) - # su stuff - cat <> "$__messages_out" - fi - fi + else + # correct current state + state_is="running" + echo "melt" >> "$__messages_out" + fi + fi - # ending - echo "restart" >> "$__messages_out" - echo "SU" - ;; - esac - ;; - esac + # ending + echo "restart" >> "$__messages_out" + echo "SU" + ;; + esac + ;; + esac fi # Check if there is a difference within the states if [ "$state_is" != "$state_should" ] && [ "$state_should" != "present" ]; then - # change privileges (too complex to make exceptions) - cat <> "$__messages_out" - fi + echo "melt" >> "$__messages_out" + fi - # handle if the container should exist or not - case "$state_should" in - running) - # already running if unfreezed - if [ "$state_is" != "frozen" ]; then - cat <> "$__messages_out" - fi - ;; + echo "start" >> "$__messages_out" + fi + ;; - # stop the container if it should be removed - stopped) - cat <> "$__messages_out" - ;; + echo "stop" >> "$__messages_out" + ;; - # container should be stopped if not already done - absent) - if [ "$state_is" != "stopped" ]; then - cat <> "$__messages_out" - fi - cat <> "$__messages_out" + fi + cat <> "$__messages_out" - ;; + echo "freeze" >> "$__messages_out" + ;; - *) - # must be checked by previous case - ;; - esac + *) + # must be checked by previous case + ;; + esac - # end of su here-document - echo "SU" + # end of su here-document + echo "SU" fi # Check if the container needs to be removed if [ "$state_should" = "absent" ]; then - # change privileges (too complex to make exceptions) - # then, shutdown and delete the container - # we could force-delete, but better be polite - # snapshots are deleted, too - to keep everything clean. May someone does not want it? - cat <> "$__messages_out" + # write to the message system + echo "destroy" >> "$__messages_out" fi diff --git a/cdist/conf/type/__lxc_container/issue.txt b/cdist/conf/type/__lxc_container/issue.txt deleted file mode 100644 index f65f9780..00000000 --- a/cdist/conf/type/__lxc_container/issue.txt +++ /dev/null @@ -1 +0,0 @@ -$__object_id == name ? sperate parameter required?? multiple same names possible due to --lxcpath! diff --git a/cdist/conf/type/__lxc_container/manifest b/cdist/conf/type/__lxc_container/manifest index 99cfa1c0..0071c4fb 100755 --- a/cdist/conf/type/__lxc_container/manifest +++ b/cdist/conf/type/__lxc_container/manifest @@ -17,62 +17,62 @@ param="$__object/parameter/" # valid check if only --template or --clone given if [ -f "$param/template" ] && [ -f "$param/clone" ]; then - # error and exit - >&2 echo "error: can not create and clone a container at once!" - >&2 echo "error: --template and --clone can not work together" - exit 2 + # error and exit + >&2 echo "error: can not create and clone a container at once!" + >&2 echo "error: --template and --clone can not work together" + exit 2 fi # no clone option if --template given if [ -f "$param/template" ]; then - if [ -f "$param/clonepath" ] - then - >&2 echo "error: container will created by template, no clone options required!" - exit 2 - fi + if [ -f "$param/clonepath" ] + then + >&2 echo "error: container will created by template, no clone options required!" + exit 2 + fi fi # no template options if --clone given if [ -f "$param/clone" ]; then - if [ -f "$param/template-opts" ] \ - || [ -f "$param/default-config" ] \ - || [ -f "$param/no-default-config" ] \ - || [ -f "$param/release" ] \ - || [ -f "$param/arch" ] - then - >&2 echo "error: container will created by clone, no template options required!" - exit 2 - fi + if [ -f "$param/template-opts" ] \ + || [ -f "$param/default-config" ] \ + || [ -f "$param/no-default-config" ] \ + || [ -f "$param/release" ] \ + || [ -f "$param/arch" ] + then + >&2 echo "error: container will created by clone, no template options required!" + exit 2 + fi fi # check backingstore values if [ -f "$param/backingstore" ]; then - backingstore="$(cat "$param/backingstore")" + backingstore="$(cat "$param/backingstore")" - if [ "$backingstore" != "dir" ] && [ "$backingstore" != "none" ]; then - if [ -f "$param/bdev-dir" ] - then - >&2 echo "error: --bdev-dir is only possible for backingstore 'dir' or 'none'" - exit 2 - fi - fi + if [ "$backingstore" != "dir" ] && [ "$backingstore" != "none" ]; then + if [ -f "$param/bdev-dir" ] + then + >&2 echo "error: --bdev-dir is only possible for backingstore 'dir' or 'none'" + exit 2 + fi + fi - if [ "$backingstore" != "lvm" ] && [ "$backingstore" != "loop" ]; then - if [ -f "$param/bdev-fstype" ] \ - || [ -f "$param/bdev-fssize" ] - then - >&2 echo "error: --bdev-fstype and --bdev-fssize only available for backingstore 'lvm' or 'loop'" - exit 2 - fi - fi + if [ "$backingstore" != "lvm" ] && [ "$backingstore" != "loop" ]; then + if [ -f "$param/bdev-fstype" ] \ + || [ -f "$param/bdev-fssize" ] + then + >&2 echo "error: --bdev-fstype and --bdev-fssize only available for backingstore 'lvm' or 'loop'" + exit 2 + fi + fi - if [ "$backingstore" != "lvm" ]; then - if [ -f "$param/bdev-lvname" ] \ - || [ -f "$param/bdev-vgname" ] \ - || [ -f "$param/bdev-thinpool" ] - then - >&2 echo "error: --bdev-{lv,vg}name and --bdev-thinpool only available for backingstore 'lvm'" - exit 2 - fi - fi + if [ "$backingstore" != "lvm" ]; then + if [ -f "$param/bdev-lvname" ] \ + || [ -f "$param/bdev-vgname" ] \ + || [ -f "$param/bdev-thinpool" ] + then + >&2 echo "error: --bdev-{lv,vg}name and --bdev-thinpool only available for backingstore 'lvm'" + exit 2 + fi + fi fi diff --git a/cdist/conf/type/__lxc_container/todo.txt b/cdist/conf/type/__lxc_container/todo.txt index e5f8f471..41822842 100644 --- a/cdist/conf/type/__lxc_container/todo.txt +++ b/cdist/conf/type/__lxc_container/todo.txt @@ -8,6 +8,10 @@ auto.. (lxc autostart): - group - start -If config already created, it's considered the container is already created - -> first create; then setup - detection if template changed?? +config: + - remove whole sections + - keep prettier config files? + + +if multi-valued object ids come to be a thing, following pattern is also used internal at lxc: + $lxcpath:$name From 3965c7f73844873aabb1d839b2298eed70a6b35c Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Tue, 21 Jul 2020 19:42:40 +0200 Subject: [PATCH 029/411] [type/__user] Install user{add,mod,del} packages on OpenWrt --- cdist/conf/type/__user/manifest | 42 +++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/cdist/conf/type/__user/manifest b/cdist/conf/type/__user/manifest index 8f10b38c..b9fad65b 100644 --- a/cdist/conf/type/__user/manifest +++ b/cdist/conf/type/__user/manifest @@ -1,6 +1,7 @@ #!/bin/sh -e # # 2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -17,16 +18,37 @@ # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # -# # Manage users. +# -os=$(cat "$__global/explorer/os") - -case "$os" in - alpine) - __package shadow - ;; - *) - : - ;; +case $(cat "${__global}/explorer/os") +in + (alpine) + __package shadow + ;; + (openwrt) + case $(cat "${__object}/parameter/state") + in + (present) + if test -s "${__object}/explorer/passwd" + then + # NOTE: The package might not be required if no changes + # are required, but determining if changes are required is + # out of scope here, and 40k should be okay, I hope. + __package shadow-usermod + else + __package shadow-useradd + fi + ;; + (absent) + if test -s "${__object}/explorer/passwd" + then + __package shadow-userdel + fi + ;; + esac + ;; + (*) + : + ;; esac From d8b5c733f6cec871ceb1933807f4877a4ee77ffa Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 22 Jul 2020 06:36:27 +0200 Subject: [PATCH 030/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index dac9cbce..040de9d8 100644 --- a/docs/changelog +++ b/docs/changelog @@ -10,6 +10,7 @@ next: * Core: Make emulator-part code consistent; remove faulty warning (Darko Poljak) * Types __file, __directory: Support setuid, setguid, sticky bits (Dennis Camera) * Type __postfix_master: Fix --option parameter and option expansion (Daniel Fancsali) + * Type __user: Install user packages on OpenWRT (Dennis Camera) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From fdef468f1ab6f2163da22a477df154a2082b57b4 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 22 Jul 2020 18:28:41 +0200 Subject: [PATCH 031/411] Fix OpenWrt spelling --- docs/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog b/docs/changelog index 040de9d8..4c17ee58 100644 --- a/docs/changelog +++ b/docs/changelog @@ -10,7 +10,7 @@ next: * Core: Make emulator-part code consistent; remove faulty warning (Darko Poljak) * Types __file, __directory: Support setuid, setguid, sticky bits (Dennis Camera) * Type __postfix_master: Fix --option parameter and option expansion (Daniel Fancsali) - * Type __user: Install user packages on OpenWRT (Dennis Camera) + * Type __user: Install user packages on OpenWrt (Dennis Camera) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From 595e43b8d5f06641179c13de8ac04be46c1b2820 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 23 Jul 2020 09:41:53 +0200 Subject: [PATCH 032/411] [type/{__file,__directory}] Fix incorrect interpretation of strings with leading 0s as octal --- cdist/conf/type/__directory/gencode-remote | 4 +++- cdist/conf/type/__file/gencode-remote | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__directory/gencode-remote b/cdist/conf/type/__directory/gencode-remote index 2c2c56fd..d9c00b56 100755 --- a/cdist/conf/type/__directory/gencode-remote +++ b/cdist/conf/type/__directory/gencode-remote @@ -99,7 +99,9 @@ case "$state_should" in # format mode in four digits => same as stat returns if [ "$attribute" = mode ]; then - value_should=$(printf '%04u' "${value_should}") + # Convert to four-digit octal number (printf interprets + # strings with leading 0s as octal!) + value_should=$(printf '%04o' "0${value_should}") fi if [ "$set_attributes" = 1 ] || [ "$value_should" != "$value_is" ]; then diff --git a/cdist/conf/type/__file/gencode-remote b/cdist/conf/type/__file/gencode-remote index a69154df..35356b13 100755 --- a/cdist/conf/type/__file/gencode-remote +++ b/cdist/conf/type/__file/gencode-remote @@ -70,7 +70,9 @@ case "$state_should" in # format mode in four digits => same as stat returns if [ "$attribute" = mode ]; then - value_should=$(printf '%04u' "${value_should}") + # Convert to four-digit octal number (printf interprets + # strings with leading 0s as octal!) + value_should=$(printf '%04o' "0${value_should}") fi value_is="$(get_current_value "$attribute" "$value_should")" From ae5f0bba0b103aabcfbad0f105c69c0b403697ac Mon Sep 17 00:00:00 2001 From: fnux Date: Fri, 24 Jul 2020 12:26:35 +0200 Subject: [PATCH 033/411] Add Alpine support to __openldap_server --- cdist/conf/type/__openldap_server/man.rst | 4 +-- cdist/conf/type/__openldap_server/manifest | 42 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst index fbad21d8..a96c7dad 100644 --- a/cdist/conf/type/__openldap_server/man.rst +++ b/cdist/conf/type/__openldap_server/man.rst @@ -103,8 +103,8 @@ syncrepl-host Set once per host that will replicate the directory. module - LDAP module to load. See `slapd.conf(5)`. - Default value is OS-dependent, see manifest. + LDAP module to load. See `slapd.conf(5)`. Some dependencies might have to + be installed beforehand. Default value is OS-dependent, see manifest. schema Name of LDAP schema to load. Must be the name without extension of a diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest index 84ba176f..2aeece26 100644 --- a/cdist/conf/type/__openldap_server/manifest +++ b/cdist/conf/type/__openldap_server/manifest @@ -25,6 +25,7 @@ case "${os}" in SLAPD_DATA_DIR="/var/db/openldap-data" SLAPD_RUN_DIR="/var/run/openldap" SLAPD_MODULE_PATH="/usr/local/libexec/openldap" + SLAPD_MODULE_TYPE="la" if [ -z "${slapd_modules}" ]; then # It looks like ppolicy and syncprov must be compiled slapd_modules="back_mdb back_monitor" @@ -43,13 +44,34 @@ case "${os}" in SLAPD_DATA_DIR="/var/lib/ldap" SLAPD_RUN_DIR="/var/run/slapd" SLAPD_MODULE_PATH="/usr/lib/ldap" + SLAPD_MODULE_TYPE="la" if [ -z "${slapd_modules}" ]; then slapd_modules="back_mdb ppolicy syncprov back_monitor" fi + CONF_OWNER="openldap" + CONF_GROUP="openldap" if [ -z "${tls_cipher_suite}" ]; then tls_cipher_suite="NORMAL" fi ;; + alpine) + PKGS="openldap openldap-clients" + ETC="/etc" + SLAPD_DIR="/etc/openldap" + SLAPD_DATA_DIR="/var/lib/openldap" + SLAPD_RUN_DIR="/var/run/openldap" + SLAPD_MODULE_PATH="/usr/lib/openldap" + SLAPD_MODULE_TYPE="so" + if [ -z "${slapd_modules}" ]; then + slapd_modules="back_mdb ppolicy syncprov back_monitor" + PKGS="$PKGS openldap-back-mdb openldap-back-monitor openldap-overlay-all" + fi + CONF_OWNER="ldap" + CONF_GROUP="$SLAPD_USER" + if [ -z "${tls_cipher_suite}" ]; then + tls_cipher_suite="DEFAULT" + fi + ;; *) echo "Don't know the openldap defaults for: $os" >&2 exit 1 @@ -156,6 +178,12 @@ case "${os}" in --line "SLAPD_SERVICES=\"${slapd_urls}\"" \ --state present ;; + alpine) + require="__package/${PKG_MAIN}" __line add_slapd_services \ + --file ${ETC}/conf.d/slapd \ + --line "command_args=\"-h '${slapd_urls}'\"" \ + --state present + ;; *) # Nothing to do here, move on. ;; @@ -170,20 +198,22 @@ if [ -z "${_skip_letsencrypt_cert}" ]; then fi # shellcheck disable=SC2086 - __letsencrypt_cert "${name}" --admin-email "${admin_email}" \ - --renew-hook "cp ${ETC}/letsencrypt/live/${name}/*.pem ${SLAPD_DIR}/sasl2 && chown -R openldap:openldap ${SLAPD_DIR}/sasl2 && service slapd restart" \ - --automatic-renewal ${staging} + __directory ${SLAPD_DIR}/sasl2 + require="__directory/${SLAPD_DIR}/sasl2" __letsencrypt_cert "${name}" \ + --admin-email "${admin_email}" \ + --renew-hook "cp ${ETC}/letsencrypt/live/${name}/*.pem ${SLAPD_DIR}/sasl2 && chown -R ${CONF_OWNER}:${CONF_GROUP} ${SLAPD_DIR}/sasl2 && service slapd restart" \ + --automatic-renewal "${staging}" fi require="__package/${PKG_MAIN}" __directory ${SLAPD_DIR}/slapd.d --state absent if [ -z "${_skip_letsencrypt_cert}" ]; then require="__package/${PKG_MAIN} __letsencrypt_cert/${name}" \ - __file ${SLAPD_DIR}/slapd.conf --owner ${CONF_OWNER} --group ${CONF_GROUP} --mode 644 \ + __file "${SLAPD_DIR}/slapd.conf" --owner "${CONF_OWNER}" --group "${CONF_GROUP}" --mode 644 \ --source "${ldapconf}" else require="__package/${PKG_MAIN}" \ - __file ${SLAPD_DIR}/slapd.conf --owner ${CONF_OWNER} --group ${CONF_GROUP} --mode 644 \ + __file "${SLAPD_DIR}/slapd.conf" --owner "${CONF_OWNER}" --group "${CONF_GROUP}" --mode 644 \ --source "${ldapconf}" fi @@ -210,7 +240,7 @@ done # Add specified modules echo "modulepath ${SLAPD_MODULE_PATH}" >> "${ldapconf}" for module in ${slapd_modules}; do - echo "moduleload ${module}.la" >> "${ldapconf}" + echo "moduleload ${module}.${SLAPD_MODULE_TYPE}" >> "${ldapconf}" done # Rest of the config From 8654cbe4661762f25cd75c484f28344ce91ec55b Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 24 Jul 2020 12:29:02 +0200 Subject: [PATCH 034/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 4c17ee58..0b9b8308 100644 --- a/docs/changelog +++ b/docs/changelog @@ -11,6 +11,7 @@ next: * Types __file, __directory: Support setuid, setguid, sticky bits (Dennis Camera) * Type __postfix_master: Fix --option parameter and option expansion (Daniel Fancsali) * Type __user: Install user packages on OpenWrt (Dennis Camera) + * Type __openldap_server: Add Alpine support (Timothée Floure) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From 8b53f35ffab4e7b74d3fd019e7602c8a05338173 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 24 Jul 2020 12:33:16 +0200 Subject: [PATCH 035/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 0b9b8308..2457e90b 100644 --- a/docs/changelog +++ b/docs/changelog @@ -12,6 +12,7 @@ next: * Type __postfix_master: Fix --option parameter and option expansion (Daniel Fancsali) * Type __user: Install user packages on OpenWrt (Dennis Camera) * Type __openldap_server: Add Alpine support (Timothée Floure) + * Type __pf_apply: Remove deprecated type (Darko Poljak) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From ee71cad047ba0c86343fe8ee9ea2bc79bf950256 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 25 Jul 2020 19:19:38 +0200 Subject: [PATCH 036/411] [type/__package_apt] Fix type for legacy APT versions --no-install-recommends was introduced with Debian 5. The APT::Install-Recommends option gets ignored by old versions and produces no error. --- cdist/conf/type/__package_apt/gencode-remote | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__package_apt/gencode-remote b/cdist/conf/type/__package_apt/gencode-remote index e02564a2..f3d91566 100755 --- a/cdist/conf/type/__package_apt/gencode-remote +++ b/cdist/conf/type/__package_apt/gencode-remote @@ -64,7 +64,7 @@ esac # Hint if we need to avoid questions at some point: # DEBIAN_PRIORITY=critical can reduce the number of questions -aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes --no-install-recommends -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" +aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes -o APT::Install-Recommends=0 -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"" if [ "$state_is" = "$state_should" ]; then if [ -z "$version" ] || [ "$version" = "$version_is" ]; then From 46d09392f08b0659557048c02e109f189ffd85f3 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 19:36:34 +0200 Subject: [PATCH 037/411] [type/__key_value] Get AWK from POSIX PATH This is required here, because Solaris /usr/bin/awk does not support the sub() function. So xpg4 AWK needs to be used. --- cdist/conf/type/__key_value/explorer/state | 4 +++- cdist/conf/type/__key_value/files/remote_script.sh | 5 ++++- cdist/conf/type/__key_value/gencode-remote | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cdist/conf/type/__key_value/explorer/state b/cdist/conf/type/__key_value/explorer/state index 7b2de1df..d24600af 100755 --- a/cdist/conf/type/__key_value/explorer/state +++ b/cdist/conf/type/__key_value/explorer/state @@ -40,7 +40,9 @@ else fi export key state delimiter value exact_delimiter -awk -f - "$file" <<"AWK_EOF" +awk_bin=$(PATH=$(getconf PATH 2>/dev/null) && command -v awk || echo awk) + +"${awk_bin}" -f - "$file" <<"AWK_EOF" BEGIN { state=ENVIRON["state"] key=ENVIRON["key"] diff --git a/cdist/conf/type/__key_value/files/remote_script.sh b/cdist/conf/type/__key_value/files/remote_script.sh index f7a1add5..faf080cb 100644 --- a/cdist/conf/type/__key_value/files/remote_script.sh +++ b/cdist/conf/type/__key_value/files/remote_script.sh @@ -24,7 +24,10 @@ if [ -f "$file" ]; then else touch "$file" fi -awk -f - "$file" >"$tmpfile" <<"AWK_EOF" + +awk_bin=$(PATH=$(getconf PATH 2>/dev/null) && command -v awk || echo awk) + +"${awk_bin}" -f - "$file" >"$tmpfile" <<"AWK_EOF" BEGIN { # import variables in a secure way .. state=ENVIRON["state"] diff --git a/cdist/conf/type/__key_value/gencode-remote b/cdist/conf/type/__key_value/gencode-remote index 13cc27c7..1174400e 100755 --- a/cdist/conf/type/__key_value/gencode-remote +++ b/cdist/conf/type/__key_value/gencode-remote @@ -25,7 +25,7 @@ state_should="$(cat "$__object/parameter/state")" state_is="$(cat "$__object/explorer/state")" fire_onchange='' -if [ "$state_is" = "$state_should" ]; then +if [ "$state_is" = "$state_should" ]; then exit 0 fi From a5905044365e0f28e793f01e0be0cac8e6b2b379 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 24 Jul 2020 10:19:10 +0200 Subject: [PATCH 038/411] [type/__locale_system] RedHat systems on systemd use /etc/locale.conf --- cdist/conf/type/__locale_system/manifest | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 4a1fdeed..22531a40 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -3,6 +3,7 @@ # 2012-2016 Steven Armstrong (steven-cdist at armstrong.cc) # 2016 Carlos Ortigoza (carlos.ortigoza at ungleich.ch) # 2016 Nico Schottelius (nico.schottelius at ungleich.ch) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -32,8 +33,25 @@ case "$os" in archlinux) locale_conf="/etc/locale.conf" ;; - redhat|centos) - locale_conf="/etc/sysconfig/i18n" + centos|redhat|scientific) + # shellcheck source=/dev/null + version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") + if expr "${version_id}" '>=' 7 >/dev/null + then + locale_conf="/etc/locale.conf" + else + locale_conf="/etc/sysconfig/i18n" + fi + ;; + fedora) + # shellcheck source=/dev/null + version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") + if expr "${version_id}" '>=' 18 >/dev/null + then + locale_conf="/etc/locale.conf" + else + locale_conf="/etc/sysconfig/i18n" + fi ;; *) echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2 @@ -47,9 +65,9 @@ __file "$locale_conf" \ --state exists require="__file/$locale_conf" \ - __key_value "$locale_conf:$__object_id" \ +__key_value "$locale_conf:$__object_id" \ --file "$locale_conf" \ --key "$__object_id" \ - --delimiter = \ + --delimiter '=' --exact_delimiter \ --state "$(cat "$__object/parameter/state")" \ --value "$(cat "$__object/parameter/value")" From 47e28fc441187b5deb869f53396eac1ee0f8cbe7 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 12:07:38 +0200 Subject: [PATCH 039/411] [type/__locale_system] Support old Debian derivatives --- cdist/conf/type/__locale_system/manifest | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 22531a40..b9991fa3 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -27,9 +27,29 @@ os=$(cat "$__global/explorer/os") case "$os" in - debian|devuan|ubuntu) + debian) + os_version=$(cat "${__global}/explorer/os_version") + if expr "${os_version}" '>=' 4 >/dev/null + then + # Debian 4 (etch) and later + locale_conf="/etc/default/locale" + else + locale_conf="/etc/environment" + fi + ;; + devuan) locale_conf="/etc/default/locale" ;; + ubuntu) + os_version=$(cat "${__global}/explorer/os_version") + if expr "${os_version}" '>=' 6.10 >/dev/null + then + # Ubuntu 6.10 (edgy) and later + locale_conf="/etc/default/locale" + else + locale_conf="/etc/environment" + fi + ;; archlinux) locale_conf="/etc/locale.conf" ;; @@ -61,7 +81,7 @@ case "$os" in esac __file "$locale_conf" \ - --owner root --group root --mode 644 \ + --owner root --group root --mode 0644 \ --state exists require="__file/$locale_conf" \ From 0ef54a721d6f540f70959df2b7f1321a5688a594 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 12:17:30 +0200 Subject: [PATCH 040/411] [type/__locale_system] Add support for Gentoo Linux --- cdist/conf/type/__locale_system/manifest | 45 ++++++++++++++++++------ 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index b9991fa3..0049ed5f 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -24,9 +24,19 @@ # Configure system-wide locale by modifying i18n file. # +onchange_cmd= # none, by default +quote_value=false + +catval() { + # shellcheck disable=SC2059 + printf "$($quote_value && echo '"%s"' || echo '%s')" "$(cat "$1")" +} + + os=$(cat "$__global/explorer/os") -case "$os" in +case $os +in debian) os_version=$(cat "${__global}/explorer/os_version") if expr "${os_version}" '>=' 4 >/dev/null @@ -69,10 +79,24 @@ case "$os" in if expr "${version_id}" '>=' 18 >/dev/null then locale_conf="/etc/locale.conf" + quote_value=false else locale_conf="/etc/sysconfig/i18n" fi ;; + gentoo) + case $(cat "${__global}/explorer/init") + in + (*openrc*) + locale_conf="/etc/env.d/02locale" + onchange_cmd="env-update --no-ldconfig" + quote_value=true + ;; + (systemd) + locale_conf="/etc/locale.conf" + ;; + esac + ;; *) 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 @@ -80,14 +104,13 @@ case "$os" in ;; esac -__file "$locale_conf" \ - --owner root --group root --mode 0644 \ - --state exists +__file "${locale_conf}" --state exists --owner root --group root --mode 0644 -require="__file/$locale_conf" \ -__key_value "$locale_conf:$__object_id" \ - --file "$locale_conf" \ - --key "$__object_id" \ - --delimiter '=' --exact_delimiter \ - --state "$(cat "$__object/parameter/state")" \ - --value "$(cat "$__object/parameter/value")" +require="__file/${locale_conf}" \ +__key_value "${locale_conf}:${__object_id}" \ + --file "${locale_conf}" \ + --key "${__object_id}" \ + --delimiter '=' --exact_delimiter \ + --state "$(cat "${__object}/parameter/state")" \ + --value "$(catval "${__object}/parameter/value")" \ + --onchange "${onchange_cmd}" From 630d987d5f5a40ae783fd9d4ff0a10653fcab04c Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 12:28:20 +0200 Subject: [PATCH 041/411] [type/__locale_system] Add support for Void Linux --- cdist/conf/type/__locale_system/manifest | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 0049ed5f..ff0a8c23 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -97,6 +97,9 @@ in ;; esac ;; + voidlinux) + locale_conf="/etc/locale.conf" + ;; *) 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 From 0ae0935afafd6b10516e9689c19000ef729d1b9b Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 14:05:36 +0200 Subject: [PATCH 042/411] [type/__locale_system] Add support for SuSE --- cdist/conf/type/__locale_system/manifest | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index ff0a8c23..26d4f7b5 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -24,6 +24,7 @@ # Configure system-wide locale by modifying i18n file. # +key=$__object_id onchange_cmd= # none, by default quote_value=false @@ -97,6 +98,25 @@ in ;; esac ;; + suse) + os_version=$(cat "${__global}/explorer/os_version") + os_major=$(expr "${os_version}" : '\([0-9]\{1,\}\)') + + # https://documentation.suse.com/sles/15-SP2/html/SLES-all/cha-suse.html#sec-suse-l10n + if expr "${os_major}" '>=' 15 \& "${os_major}" != 42 + then + # It seems that starting with SuSE 15 the systemd /etc/locale.conf + # is the preferred way to set locales, although + # /etc/sysconfig/language is still available. + # Older documentation doesn't mention /etc/locale.conf, even though + # is it created when localectl is used. + locale_conf="/etc/locale.conf" + else + locale_conf="/etc/sysconfig/language" + quote_value=true + key="RC_${__object_id}" + fi + ;; voidlinux) locale_conf="/etc/locale.conf" ;; @@ -110,9 +130,9 @@ esac __file "${locale_conf}" --state exists --owner root --group root --mode 0644 require="__file/${locale_conf}" \ -__key_value "${locale_conf}:${__object_id}" \ +__key_value "${locale_conf}:${key}" \ --file "${locale_conf}" \ - --key "${__object_id}" \ + --key "${key}" \ --delimiter '=' --exact_delimiter \ --state "$(cat "${__object}/parameter/state")" \ --value "$(catval "${__object}/parameter/value")" \ From cbf22f3b2c8b9d0fef8f6b7b0bf16508f96675b3 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 15:23:55 +0200 Subject: [PATCH 043/411] [type/__locale_system] Add support for Solaris --- cdist/conf/type/__locale_system/manifest | 41 ++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 26d4f7b5..71491fe5 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -33,6 +33,7 @@ catval() { printf "$($quote_value && echo '"%s"' || echo '%s')" "$(cat "$1")" } +state_should=$(cat "${__object}/parameter/state") os=$(cat "$__global/explorer/os") @@ -98,6 +99,39 @@ in ;; esac ;; + solaris) + locale_conf="/etc/default/init" + locale_conf_group="sys" + + if expr "$(cat "${__global}/explorer/os_version")" '>=' 5.11 >/dev/null + then + # mode on Oracle Solaris 11 is actually 0444, + # but the write bit makes sense, IMO + locale_conf_mode=0644 + + # Oracle Solaris 11.2 and later uses SMF to store environment info. + # This is a hack, but I didn't feel like modifying the whole type + # just for some Oracle nonsense. + # 11.3 apparently added nlsadm(1m), but it is missing from 11.2. + # Illumos continues to use /etc/default/init + # NOTE: Remember not to use "cool" POSIX features like -q or -e with + # Solaris grep. + release_regex='Oracle Solaris 11.[2-9][0-9]*' + case $state_should + in + (present) + svccfg_cmd="svccfg -s svc:/system/environment:init setprop environment/${key} = astring: '$(cat "${__object}/parameter/value")'" + ;; + (absent) + svccfg_cmd="svccfg -s svc:/system/environment:init delprop environment/${key}" + ;; + esac + refresh_cmd='svcadm refresh svc:/system/environment' + onchange_cmd="grep '${release_regex}' /etc/release >&- || exit 0; ${svccfg_cmd:-:} && ${refresh_cmd}" + else + locale_conf_mode=0555 + fi + ;; suse) os_version=$(cat "${__global}/explorer/os_version") os_major=$(expr "${os_version}" : '\([0-9]\{1,\}\)') @@ -127,13 +161,16 @@ in ;; esac -__file "${locale_conf}" --state exists --owner root --group root --mode 0644 +__file "${locale_conf}" --state exists \ + --owner "${locale_conf_owner:-0}" \ + --group "${locale_conf_group:-0}" \ + --mode "${locale_conf_mode:-0644}" require="__file/${locale_conf}" \ __key_value "${locale_conf}:${key}" \ --file "${locale_conf}" \ --key "${key}" \ --delimiter '=' --exact_delimiter \ - --state "$(cat "${__object}/parameter/state")" \ + --state "${state_should}" \ --value "$(catval "${__object}/parameter/value")" \ --onchange "${onchange_cmd}" From a923e75d9b0054212031507986d3b935d74d52bf Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 18:29:14 +0200 Subject: [PATCH 044/411] [type/__locale_system] Add support for NetBSD --- cdist/conf/type/__locale_system/manifest | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 71491fe5..92af852f 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -99,6 +99,15 @@ in ;; esac ;; + netbsd) + # NetBSD doesn't have a separate configuration file to set locales. + # So the shell login file will have to do. + # "Non-POSIX" shells like csh will not be updated here. + + locale_conf="/etc/profile" + quote_value=true + value="$(catval "${__object}/parameter/value"); export ${key}" + ;; solaris) locale_conf="/etc/default/init" locale_conf_group="sys" @@ -172,5 +181,5 @@ __key_value "${locale_conf}:${key}" \ --key "${key}" \ --delimiter '=' --exact_delimiter \ --state "${state_should}" \ - --value "$(catval "${__object}/parameter/value")" \ + --value "${value:-$(catval "${__object}/parameter/value")}" \ --onchange "${onchange_cmd}" From 511d8c96aa9201049eaafc459a2de9694fe2a4e4 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 19:23:17 +0200 Subject: [PATCH 045/411] [type/__locale_system] Add support for Slackware --- cdist/conf/type/__locale_system/manifest | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 92af852f..180788e6 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -141,6 +141,12 @@ in locale_conf_mode=0555 fi ;; + slackware) + # NOTE: lang.csh (csh config) is ignored here. + locale_conf="/etc/profile.d/lang.sh" + locale_conf_mode=0755 + key="export ${__object_id}" + ;; suse) os_version=$(cat "${__global}/explorer/os_version") os_major=$(expr "${os_version}" : '\([0-9]\{1,\}\)') @@ -176,7 +182,7 @@ __file "${locale_conf}" --state exists \ --mode "${locale_conf_mode:-0644}" require="__file/${locale_conf}" \ -__key_value "${locale_conf}:${key}" \ +__key_value "${locale_conf}:${key#export }" \ --file "${locale_conf}" \ --key "${key}" \ --delimiter '=' --exact_delimiter \ From 70d1228dc0c6a3af105f0864b46d7dea806aedc2 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 19:26:45 +0200 Subject: [PATCH 046/411] [type/__locale_system] Add support for FreeBSD --- cdist/conf/type/__locale_system/manifest | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 180788e6..e4286ef6 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -99,9 +99,10 @@ in ;; esac ;; - netbsd) - # NetBSD doesn't have a separate configuration file to set locales. - # So the shell login file will have to do. + freebsd|netbsd) + # NetBSD doesn't have a separate configuration file to set locales. + # In FreeBSD locales could be configured via /etc/login.conf but parsing + # that would be annoying, so the shell login file will have to do. # "Non-POSIX" shells like csh will not be updated here. locale_conf="/etc/profile" From 73f1937636bfa59eea0432e3625c0a27cc8171b5 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Mon, 27 Jul 2020 06:20:21 +0200 Subject: [PATCH 047/411] [__unpack] no mkdir by default, because destination can be file, but tar needs mkdir andrar needs slash at the end --- cdist/conf/type/__unpack/explorer/state | 37 +++++++++ cdist/conf/type/__unpack/gencode-remote | 75 ++++++++++++++++++ cdist/conf/type/__unpack/man.rst | 79 +++++++++++++++++++ cdist/conf/type/__unpack/manifest | 41 ++++++++++ cdist/conf/type/__unpack/parameter/boolean | 2 + cdist/conf/type/__unpack/parameter/optional | 2 + cdist/conf/type/__unpack/parameter/required | 1 + cdist/conf/type/__unpack/test/README | 3 + .../type/__unpack/test/make-init-manifest.sh | 22 ++++++ .../type/__unpack/test/make-test-files.sh | 44 +++++++++++ 10 files changed, 306 insertions(+) create mode 100755 cdist/conf/type/__unpack/explorer/state create mode 100755 cdist/conf/type/__unpack/gencode-remote create mode 100644 cdist/conf/type/__unpack/man.rst create mode 100755 cdist/conf/type/__unpack/manifest create mode 100644 cdist/conf/type/__unpack/parameter/boolean create mode 100644 cdist/conf/type/__unpack/parameter/optional create mode 100644 cdist/conf/type/__unpack/parameter/required create mode 100644 cdist/conf/type/__unpack/test/README create mode 100755 cdist/conf/type/__unpack/test/make-init-manifest.sh create mode 100755 cdist/conf/type/__unpack/test/make-test-files.sh diff --git a/cdist/conf/type/__unpack/explorer/state b/cdist/conf/type/__unpack/explorer/state new file mode 100755 index 00000000..38bc0978 --- /dev/null +++ b/cdist/conf/type/__unpack/explorer/state @@ -0,0 +1,37 @@ +#!/bin/sh -e + +src="/$__object_id" + +if [ -f "$__object/parameter/sum-file" ] +then + src_sum_was_file="$( cat "$__object/parameter/sum-file" )" +else + src_sum_was_file="$src.cdist__unpack_sum" +fi + +if [ ! -f "$src" ] +then + if [ -n "$__cdist_dry_run" ] + then + echo 'mismatch' + else + echo 'missing' + fi +else + if [ ! -f "$src_sum_was_file" ] + then + echo 'mismatch' + exit 0 + fi + + src_sum_was="$( cat "$src_sum_was_file" )" + + src_sum_is="$( cksum "$src" | awk '{ print $1$2 }' )" + + if [ "$src_sum_was" = "$src_sum_is" ] + then + echo 'match' + else + echo 'mismatch' + fi +fi diff --git a/cdist/conf/type/__unpack/gencode-remote b/cdist/conf/type/__unpack/gencode-remote new file mode 100755 index 00000000..45c7173a --- /dev/null +++ b/cdist/conf/type/__unpack/gencode-remote @@ -0,0 +1,75 @@ +#!/bin/sh -e + +if grep -Eq '^(missing|match)$' "$__object/explorer/state" +then + exit 0 +fi + +os="$( cat "$__global/explorer/os" )" + +src="/$__object_id" + +dst="$( sed 's/\/$//' "$__object/parameter/destination" )" + +cmd='' + +case "$src" in + *.tar|*.tgz|*.tar.*) + cmd="mkdir -p '$dst' && tar --directory='$dst' --extract --file='$src'" + + if [ -f "$__object/parameter/tar-strip" ] + then + tar_strip="$( cat "$__object/parameter/tar-strip" )" + + cmd="$cmd --strip-components=$tar_strip" + fi + ;; + *.7z) + case "$os" in + centos|fedora|redhat) + cmd='7za' + ;; + *) + cmd='7zr' + ;; + esac + + cmd="$cmd e -aoa -o'$dst' '$src'" + ;; + *.bz2) + cmd="bunzip2 --stdout '$src' > '$dst'" + ;; + *.gz) + cmd="gunzip --stdout '$src' > '$dst'" + ;; + *.lzma|*.xz) + cmd="xz --uncompress --stdout '$src' > '$dst'" + ;; + *.rar) + cmd="unrar x -o+ '$src' '$dst/'" + ;; + *.zip) + cmd="unzip -o '$src' -d '$dst'" + ;; +esac + +if [ -f "$__object/parameter/backup-destination" ] +then + echo "if [ -e '$dst' ]; then mv '$dst' '$dst.cdist__unpack_backup_$( date +%s )'; fi" +fi + +echo "$cmd" + +if [ -f "$__object/parameter/sum-file" ] +then + sum_file="$( cat "$__object/parameter/sum-file" )" +else + sum_file="$src.cdist__unpack_sum" +fi + +echo "cksum '$src' | awk '{ print \$1\$2 }' > '$sum_file'" + +if [ ! -f "$__object/parameter/preserve-archive" ] +then + echo "rm -f '$src'" +fi diff --git a/cdist/conf/type/__unpack/man.rst b/cdist/conf/type/__unpack/man.rst new file mode 100644 index 00000000..8fe96e43 --- /dev/null +++ b/cdist/conf/type/__unpack/man.rst @@ -0,0 +1,79 @@ +cdist-type__unpack(7) +===================== + +NAME +---- +cdist-type__unpack - Unpack archives + + +DESCRIPTION +----------- +Unpack ``.tar``, ``.tgz``, ``.tar.*``, ``.7z``, ``.bz2``, ``.gz``, +``.lzma``, ``.xz``, ``.rar`` and ``.zip`` archives. Archive type is +detected by extension. + +To achieve idempotency, checksum file will be created in target. See +``--sum-file`` parameter for details. + + +REQUIRED PARAMETERS +------------------- +destination + Depending on archive format file or directory to where archive + contents will be written. + + +OPTIONAL PARAMETERS +------------------- +sum-file + Override archive's checksum file in target. By default + ``XXX.cdist__unpack_sum`` will be used, where ``XXX`` is source + archive path. This file must be kept in target's persistent storage. + +tar-strip + Tarball specific. See ``man tar`` for ``--strip-components``. + + +OPTIONAL BOOLEAN PARAMETERS +--------------------------- +backup-destination + By default destination file will be overwritten. In case destination + is directory, files from archive will be added to or overwritten in + directory. This parameter moves existing destination to + ``XXX.cdist__unpack_backup_YYY``, where ``XXX`` is destination and + ``YYY`` current UNIX timestamp. + +preserve-archive + Don't delete archive after unpacking. + + +EXAMPLES +-------- + +.. code-block:: sh + + __directory /opt/cpma + + require='__directory/opt/cpma' \ + __download /opt/cpma/cnq3.zip \ + --url https://cdn.playmorepromode.com/files/cnq3/cnq3-1.51.zip \ + --sum md5:46da3021ca9eace277115ec9106c5b46 + + require='__download/opt/cpma/cnq3.zip' \ + __unpack /opt/cpma/cnq3.zip \ + --backup-destination \ + --preserve-archive \ + --destination /opt/cpma/server + + +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/__unpack/manifest b/cdist/conf/type/__unpack/manifest new file mode 100755 index 00000000..6bdf5a10 --- /dev/null +++ b/cdist/conf/type/__unpack/manifest @@ -0,0 +1,41 @@ +#!/bin/sh -e + +os="$( cat "$__global/explorer/os" )" + +src="/$__object_id" + +case "$src" in + *.7z) + __package p7zip + ;; + *.bz2) + case "$os" in + freebsd) + # bzip2 is part of freebsd base system + ;; + *) + __package bzip2 + ;; + esac + ;; + *.lzma|*.xz|*.txz) + case "$os" in + debian|ubuntu|devuan) + __package xz-utils + ;; + alpine|centos) + __package xz + ;; + esac + ;; + *.rar) + case "$os" in + debian|ubuntu|devuan|alpine|freebsd) + __package unrar + ;; + esac + ;; + *.zip) + __package unzip + ;; +esac diff --git a/cdist/conf/type/__unpack/parameter/boolean b/cdist/conf/type/__unpack/parameter/boolean new file mode 100644 index 00000000..99dca934 --- /dev/null +++ b/cdist/conf/type/__unpack/parameter/boolean @@ -0,0 +1,2 @@ +backup-destination +preserve-archive diff --git a/cdist/conf/type/__unpack/parameter/optional b/cdist/conf/type/__unpack/parameter/optional new file mode 100644 index 00000000..d136dd0c --- /dev/null +++ b/cdist/conf/type/__unpack/parameter/optional @@ -0,0 +1,2 @@ +sum-file +tar-strip diff --git a/cdist/conf/type/__unpack/parameter/required b/cdist/conf/type/__unpack/parameter/required new file mode 100644 index 00000000..ac459b09 --- /dev/null +++ b/cdist/conf/type/__unpack/parameter/required @@ -0,0 +1 @@ +destination diff --git a/cdist/conf/type/__unpack/test/README b/cdist/conf/type/__unpack/test/README new file mode 100644 index 00000000..54f3972a --- /dev/null +++ b/cdist/conf/type/__unpack/test/README @@ -0,0 +1,3 @@ +./make-test-files.sh +./make-init-manifest.sh | cdist config -i - localhost +sudo find /tmp/cdist__unpack_test/ -type f -exec cat {} \; | sort diff --git a/cdist/conf/type/__unpack/test/make-init-manifest.sh b/cdist/conf/type/__unpack/test/make-init-manifest.sh new file mode 100755 index 00000000..404bc106 --- /dev/null +++ b/cdist/conf/type/__unpack/test/make-init-manifest.sh @@ -0,0 +1,22 @@ +#!/bin/sh -e + +p="$( pwd )" +d=/tmp/cdist__unpack_test + +echo 'export CDIST_ORDER_DEPENDENCY=1' + +echo "__directory $d" + +find "$p" -name 'test.*' -and -not -name '*.cdist__unpack_sum' \ + | sort \ + | while read -r l +do + n="$( basename "$l" )" + + printf '__unpack %s --destination %s/%s\n' \ + "$l" \ + "$d" \ + "$n" +done + +echo "__clean_path $p --pattern '.+/test\..+'" diff --git a/cdist/conf/type/__unpack/test/make-test-files.sh b/cdist/conf/type/__unpack/test/make-test-files.sh new file mode 100755 index 00000000..d18e9e9f --- /dev/null +++ b/cdist/conf/type/__unpack/test/make-test-files.sh @@ -0,0 +1,44 @@ +#!/bin/sh -ex + +echo test.7z > test +7z a test.7z test > /dev/null + +echo test.bz2 > test +bzip2 test + +echo test.gz > test +gzip test + +echo test.lzma > test +lzma test + +echo test.rar > test +rar a test.rar test > /dev/null + +echo test.tar.bz2 > test +tar cf test.tar test +bzip2 test.tar + +echo test.tar.xz > test +tar cf test.tar test +xz test.tar + +echo test.tgz > test +tar cf test.tar test +gzip test.tar +mv test.tar.gz test.tgz + +echo test.tar.gz > test +tar cf test.tar test +gzip test.tar + +echo test.tar > test +tar cf test.tar test + +echo test.xz > test +xz test + +echo test.zip > test +zip test.zip test > /dev/null + +rm test From 463b6cd6b52da8918d2803721164748c2a632696 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 27 Jul 2020 06:22:25 +0200 Subject: [PATCH 048/411] ++changelog --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index 2457e90b..8d26e767 100644 --- a/docs/changelog +++ b/docs/changelog @@ -13,6 +13,9 @@ next: * Type __user: Install user packages on OpenWrt (Dennis Camera) * Type __openldap_server: Add Alpine support (Timothée Floure) * Type __pf_apply: Remove deprecated type (Darko Poljak) + * Type __package_apt: Fix for legacy APT versions that do not support --no-install-recommends (Dennis Camera) + * Type __key_value: Get awk from POSIX PATH (Dennis Camera) + * New type: __unpack (Ander Punnar) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From d26c36914a4fa9889af57f549cb2854968663a0b Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 27 Jul 2020 10:55:28 +0200 Subject: [PATCH 049/411] [__timezone] Make type singleton --- cdist/conf/type/__timezone/gencode-remote | 2 +- cdist/conf/type/__timezone/man.rst | 22 ++++++++++++------- cdist/conf/type/__timezone/manifest | 2 +- cdist/conf/type/__timezone/parameter/required | 1 + cdist/conf/type/__timezone/singleton | 0 5 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 cdist/conf/type/__timezone/parameter/required create mode 100644 cdist/conf/type/__timezone/singleton diff --git a/cdist/conf/type/__timezone/gencode-remote b/cdist/conf/type/__timezone/gencode-remote index 5299f548..b685c990 100755 --- a/cdist/conf/type/__timezone/gencode-remote +++ b/cdist/conf/type/__timezone/gencode-remote @@ -22,7 +22,7 @@ # This type allows to configure the desired localtime timezone. timezone_is=$(cat "$__object/explorer/timezone_is") -timezone_should="$__object_id" +timezone_should=$(cat "$__object/parameter/tz") os=$(cat "$__global/explorer/os") if [ "$timezone_is" = "$timezone_should" ]; then diff --git a/cdist/conf/type/__timezone/man.rst b/cdist/conf/type/__timezone/man.rst index 8a945c16..6012c552 100644 --- a/cdist/conf/type/__timezone/man.rst +++ b/cdist/conf/type/__timezone/man.rst @@ -14,7 +14,8 @@ This type creates a symlink (/etc/localtime) to the selected timezone REQUIRED PARAMETERS ------------------- -None. +tz + The name of timezone to set. OPTIONAL PARAMETERS @@ -27,19 +28,24 @@ EXAMPLES .. code-block:: sh - #Set up Europe/Andorra as our timezone. - __timezone Europe/Andorra + # Set up Europe/Andorra as our timezone. + __timezone --tz Europe/Andorra - #Set up US/Central as our timezone. - __timezone US/Central + # Set up US/Central as our timezone. + __timezone --tz US/Central AUTHORS ------- -Ramon Salvadó +| Steven Armstrong +| Nico Schottelius +| Ramon Salvadó +| Dennis Camera COPYING ------- -Free use of this software is -granted under the terms of the GNU General Public License version 3 (GPLv3). +Copyright \(C) 2012-2020 the `AUTHORS`_. 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/__timezone/manifest b/cdist/conf/type/__timezone/manifest index 3d28ccba..0eb7fb9c 100755 --- a/cdist/conf/type/__timezone/manifest +++ b/cdist/conf/type/__timezone/manifest @@ -22,7 +22,7 @@ # # This type allows to configure the desired localtime timezone. -timezone="$__object_id" +timezone=$(cat "$__object/parameter/tz") os=$(cat "$__global/explorer/os") case "$os" in diff --git a/cdist/conf/type/__timezone/parameter/required b/cdist/conf/type/__timezone/parameter/required new file mode 100644 index 00000000..975445e4 --- /dev/null +++ b/cdist/conf/type/__timezone/parameter/required @@ -0,0 +1 @@ +tz diff --git a/cdist/conf/type/__timezone/singleton b/cdist/conf/type/__timezone/singleton new file mode 100644 index 00000000..e69de29b From 627d215b637f1893e48a4a04c7e60686b960a698 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 27 Jul 2020 13:09:53 +0200 Subject: [PATCH 050/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 8d26e767..e3711be2 100644 --- a/docs/changelog +++ b/docs/changelog @@ -16,6 +16,7 @@ next: * Type __package_apt: Fix for legacy APT versions that do not support --no-install-recommends (Dennis Camera) * Type __key_value: Get awk from POSIX PATH (Dennis Camera) * New type: __unpack (Ander Punnar) + * Type __locale_system: Support more OSes (Dennis Camera) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From 5dfc996febd085e4592fe590c4837bd4802ef4c3 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 22:53:34 +0200 Subject: [PATCH 051/411] Fix global explorers for NetBSD On NetBSD sysctl is at /sbin/sysctl, but the default PATH does not contain /sbin. --- cdist/conf/explorer/cpu_cores | 1 + cdist/conf/explorer/disks | 5 ++--- cdist/conf/explorer/memory | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cdist/conf/explorer/cpu_cores b/cdist/conf/explorer/cpu_cores index c6744142..81e5294e 100755 --- a/cdist/conf/explorer/cpu_cores +++ b/cdist/conf/explorer/cpu_cores @@ -33,6 +33,7 @@ case "$os" in ;; "freebsd"|"netbsd") + PATH=$(getconf PATH) sysctl -n hw.ncpu ;; diff --git a/cdist/conf/explorer/disks b/cdist/conf/explorer/disks index 24540601..56d62d10 100755 --- a/cdist/conf/explorer/disks +++ b/cdist/conf/explorer/disks @@ -30,9 +30,8 @@ case $uname_s in 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]+/' + PATH=$(getconf PATH) + sysctl -n hw.disknames | awk -v RS=' ' '/^[lsw]d[0-9]+/' ;; Linux) # list of major device numbers toexclude: diff --git a/cdist/conf/explorer/memory b/cdist/conf/explorer/memory index 302b4cda..5ea15ada 100755 --- a/cdist/conf/explorer/memory +++ b/cdist/conf/explorer/memory @@ -30,6 +30,7 @@ case "$os" in ;; *"bsd") + PATH=$(getconf PATH) echo "$(sysctl -n hw.physmem) / 1048576" | bc ;; From 3a87a447d00ef12eb6ace7c240926568aec2a042 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 26 Jul 2020 23:37:48 +0200 Subject: [PATCH 052/411] [type/__sysctl] Fix on NetBSD --- cdist/conf/type/__sysctl/explorer/value | 9 +++++++-- cdist/conf/type/__sysctl/gencode-remote | 2 ++ cdist/conf/type/__sysctl/man.rst | 7 +++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__sysctl/explorer/value b/cdist/conf/type/__sysctl/explorer/value index fc85b3d8..3e93c151 100755 --- a/cdist/conf/type/__sysctl/explorer/value +++ b/cdist/conf/type/__sysctl/explorer/value @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -e # # 2014 Steven Armstrong (steven-cdist at armstrong.cc) # @@ -18,5 +18,10 @@ # along with cdist. If not, see . # +if test "$(uname -s)" = NetBSD +then + PATH=$(getconf PATH) +fi + # get the current runtime value -sysctl -n "$__object_id" || true +sysctl -n "${__object_id}" || true diff --git a/cdist/conf/type/__sysctl/gencode-remote b/cdist/conf/type/__sysctl/gencode-remote index 711d54e5..f0f6deef 100755 --- a/cdist/conf/type/__sysctl/gencode-remote +++ b/cdist/conf/type/__sysctl/gencode-remote @@ -44,6 +44,8 @@ case "$os" in flag='-w' ;; netbsd) + # shellcheck disable=SC2016 + echo 'PATH=$(getconf PATH)' flag='-w' ;; freebsd|openbsd) diff --git a/cdist/conf/type/__sysctl/man.rst b/cdist/conf/type/__sysctl/man.rst index 6873003e..dbb9a1ac 100644 --- a/cdist/conf/type/__sysctl/man.rst +++ b/cdist/conf/type/__sysctl/man.rst @@ -26,6 +26,13 @@ EXAMPLES __sysctl net.ipv4.ip_forward --value 1 + # On some operating systems, e.g. NetBSD, to prevent an error if the + # MIB style name does not exist (e.g. optional kernel components), + # name and value can be separated by `?=`. The same effect can be achieved + # in cdist by appending a `?` to the key: + + __sysctl ddb.onpanic? --value -1 + AUTHORS ------- From 76bb214b5300707426030649cf03f35808e43256 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 27 Jul 2020 15:31:38 +0200 Subject: [PATCH 053/411] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index e3711be2..8fef4653 100644 --- a/docs/changelog +++ b/docs/changelog @@ -17,6 +17,8 @@ next: * Type __key_value: Get awk from POSIX PATH (Dennis Camera) * New type: __unpack (Ander Punnar) * Type __locale_system: Support more OSes (Dennis Camera) + * Explorers cpu_cores, disks, memory: Fix for NetBSD (Dennis Camera) + * Type __sysctl: Fix for NetBSD (Dennis Camera) 6.6.0: 2020-06-17 * Type __ssh_authorized_keys: Add option for removing undefined keys (Ander Punnar) From f5b367dfdbf60e75cfb2be038a05b6f226a1c010 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Tue, 28 Jul 2020 07:14:26 +0200 Subject: [PATCH 054/411] Release 6.7.0 --- docs/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog b/docs/changelog index 8fef4653..269a2049 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,7 +1,8 @@ Changelog --------- -next: +6.7.0: 2020-07-28 + * Delete deprecated type: __pf_apply (Darko Poljak) * New type: __download (Ander Punnar) * Type __locale_system: Add devuan support (Dennis Camera) * Type __package_opkg: Add locking (Dennis Camera) @@ -12,7 +13,6 @@ next: * Type __postfix_master: Fix --option parameter and option expansion (Daniel Fancsali) * Type __user: Install user packages on OpenWrt (Dennis Camera) * Type __openldap_server: Add Alpine support (Timothée Floure) - * Type __pf_apply: Remove deprecated type (Darko Poljak) * Type __package_apt: Fix for legacy APT versions that do not support --no-install-recommends (Dennis Camera) * Type __key_value: Get awk from POSIX PATH (Dennis Camera) * New type: __unpack (Ander Punnar) From c053a2c4a000b0c15df186ef2e067ea68ec9499c Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 29 Jul 2020 11:31:12 +0200 Subject: [PATCH 055/411] Fix building man pages Resolves #830. --- Makefile | 4 ++-- cdist/conf/type/__openldap_server/man.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f89ac1e7..3712511c 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ version: } # Manpages #3: generic part -man: version $(MANTYPES) $(DOCSREF) +man: version configskel $(MANTYPES) $(DOCSREF) $(DOCSTYPESREF) $(SPHINXM) html: version configskel $(MANTYPES) $(DOCSREF) $(DOCSTYPESREF) @@ -104,7 +104,7 @@ DOTMANTYPES=$(subst /man.rst,.rst,$(DOTMANTYPEPREFIX)) $(DOTMAN7DSTDIR)/cdist-type%.rst: $(DOTTYPEDIR)/%/man.rst ln -sf "$^" $@ -dotman: version $(DOTMANTYPES) +dotman: version configskel $(DOTMANTYPES) $(DOCSREF) $(DOCSTYPESREF) $(SPHINXM) ################################################################################ diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst index a96c7dad..fa714ec0 100644 --- a/cdist/conf/type/__openldap_server/man.rst +++ b/cdist/conf/type/__openldap_server/man.rst @@ -31,8 +31,8 @@ manager-password-hash Generate e.g. with: `slappasswd -s weneedgoodsecurity`. See `slappasswd(8C)`, `slapd.conf(5)`. TODO: implement this: http://blog.adamsbros.org/2015/06/09/openldap-ssha-salted-hashes-by-hand/ - to derive from the manager-password parameter and ensure idempotency (care with salts). - At that point, manager-password-hash should be deprecated and ignored. + to derive from the manager-password parameter and ensure idempotency (care with salts). + At that point, manager-password-hash should be deprecated and ignored. serverid The server for the directory. From d37d2dc307d066f4d5f1bbbb93e0480965dfe3b8 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 2 Aug 2020 13:53:38 +0300 Subject: [PATCH 056/411] [__unpack] add parameter --tar-extra-args --- cdist/conf/type/__unpack/gencode-remote | 7 +++++++ cdist/conf/type/__unpack/man.rst | 11 +++++++++++ cdist/conf/type/__unpack/parameter/optional | 1 + 3 files changed, 19 insertions(+) diff --git a/cdist/conf/type/__unpack/gencode-remote b/cdist/conf/type/__unpack/gencode-remote index 45c7173a..3b7a19a7 100755 --- a/cdist/conf/type/__unpack/gencode-remote +++ b/cdist/conf/type/__unpack/gencode-remote @@ -23,6 +23,13 @@ case "$src" in cmd="$cmd --strip-components=$tar_strip" fi + + if [ -f "$__object/parameter/tar-extra-args" ] + then + tar_extra_args="$( cat "$__object/parameter/tar-extra-args" )" + + cmd="$cmd $tar_extra_args" + fi ;; *.7z) case "$os" in diff --git a/cdist/conf/type/__unpack/man.rst b/cdist/conf/type/__unpack/man.rst index 8fe96e43..bd0603cf 100644 --- a/cdist/conf/type/__unpack/man.rst +++ b/cdist/conf/type/__unpack/man.rst @@ -33,6 +33,10 @@ sum-file tar-strip Tarball specific. See ``man tar`` for ``--strip-components``. +tar-extra-args + Tarball sepcific. Append additional arguments to ``tar`` command. + See ``man tar`` for possible arguments. + OPTIONAL BOOLEAN PARAMETERS --------------------------- @@ -65,6 +69,13 @@ EXAMPLES --preserve-archive \ --destination /opt/cpma/server + # example usecase for --tar-* args + __unpack /root/strelaysrv.tar.gz \ + --preserve-archive \ + --destination /usr/local/bin \ + --tar-strip 1 \ + --tar-extra-args '--wildcards "*/strelaysrv"' + AUTHORS ------- diff --git a/cdist/conf/type/__unpack/parameter/optional b/cdist/conf/type/__unpack/parameter/optional index d136dd0c..da26ca63 100644 --- a/cdist/conf/type/__unpack/parameter/optional +++ b/cdist/conf/type/__unpack/parameter/optional @@ -1,2 +1,3 @@ sum-file tar-strip +tar-extra-args From 935f2395bc8f02d373f06d1e22acad813403ead2 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 2 Aug 2020 13:54:30 +0300 Subject: [PATCH 057/411] [__locale_system] fix for debian and ubuntu ubuntu 6.10 and debian etch are 10+ years old and EOL. rather than preserving compatibility I'll just remove it. while /etc/environment works too, correct place is /etc/default/locale (as it was before breaking change). also /etc/debian_version (os_version explorer) may contain minor version with dot (10.5) or string (bullseye/sid). --- cdist/conf/type/__locale_system/manifest | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index e4286ef6..f7d75387 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -40,27 +40,13 @@ os=$(cat "$__global/explorer/os") case $os in debian) - os_version=$(cat "${__global}/explorer/os_version") - if expr "${os_version}" '>=' 4 >/dev/null - then - # Debian 4 (etch) and later - locale_conf="/etc/default/locale" - else - locale_conf="/etc/environment" - fi + locale_conf="/etc/default/locale" ;; devuan) locale_conf="/etc/default/locale" ;; ubuntu) - os_version=$(cat "${__global}/explorer/os_version") - if expr "${os_version}" '>=' 6.10 >/dev/null - then - # Ubuntu 6.10 (edgy) and later - locale_conf="/etc/default/locale" - else - locale_conf="/etc/environment" - fi + locale_conf="/etc/default/locale" ;; archlinux) locale_conf="/etc/locale.conf" From 885d5a58f40e5adfd6aa616712e4c7246eca7880 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 2 Aug 2020 16:49:01 +0200 Subject: [PATCH 058/411] [type/__locale_system] Fix floating point version comparison --- cdist/conf/type/__locale_system/manifest | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index e4286ef6..521f1007 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -24,6 +24,9 @@ # Configure system-wide locale by modifying i18n file. # +bccmp() { test "$(bc)" -gt 0; } + + key=$__object_id onchange_cmd= # none, by default quote_value=false @@ -41,7 +44,7 @@ case $os in debian) os_version=$(cat "${__global}/explorer/os_version") - if expr "${os_version}" '>=' 4 >/dev/null + if printf '%f >= 4\n' "${os_version}" | bccmp then # Debian 4 (etch) and later locale_conf="/etc/default/locale" @@ -54,7 +57,7 @@ in ;; ubuntu) os_version=$(cat "${__global}/explorer/os_version") - if expr "${os_version}" '>=' 6.10 >/dev/null + if printf '%f >= 6.10\n' "${os_version}" | bccmp then # Ubuntu 6.10 (edgy) and later locale_conf="/etc/default/locale" @@ -68,7 +71,7 @@ in centos|redhat|scientific) # shellcheck source=/dev/null version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") - if expr "${version_id}" '>=' 7 >/dev/null + if printf '%f >= 7\n' "${version_id}" | bccmp then locale_conf="/etc/locale.conf" else @@ -78,7 +81,7 @@ in fedora) # shellcheck source=/dev/null version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") - if expr "${version_id}" '>=' 18 >/dev/null + if printf '%f >= 18\n' "${version_id}" | bccmp then locale_conf="/etc/locale.conf" quote_value=false @@ -113,7 +116,8 @@ in locale_conf="/etc/default/init" locale_conf_group="sys" - if expr "$(cat "${__global}/explorer/os_version")" '>=' 5.11 >/dev/null + os_version=$(cat "${__global}/explorer/os_version") + if printf '%f >= 5.11\n' "${os_version}" | bccmp then # mode on Oracle Solaris 11 is actually 0444, # but the write bit makes sense, IMO From 71710fa00a86e3dcda6be82b959956cb88ba9902 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 2 Aug 2020 20:17:00 +0200 Subject: [PATCH 059/411] [type/__locale_system] Implement "proper" version comparison Proper in the sense that it can handle all numeric version numbers even if they are not floating point (e.g. 16.04.6). --- cdist/conf/type/__locale_system/manifest | 28 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 521f1007..88eadb31 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -24,7 +24,20 @@ # Configure system-wide locale by modifying i18n file. # -bccmp() { test "$(bc)" -gt 0; } +version_ge() { + awk -F '[^0-9.]' -v target="${1:?}" ' + function max(x, y) { return x > y ? x : y } + BEGIN { + getline + nx = split($1, x, ".") + ny = split(target, y, ".") + for (i = 1; i <= max(nx, ny); ++i) { + diff = int(x[i]) - int(y[i]) + if (diff == 0) continue + exit (diff < 0) + } + }' +} key=$__object_id @@ -43,8 +56,7 @@ os=$(cat "$__global/explorer/os") case $os in debian) - os_version=$(cat "${__global}/explorer/os_version") - if printf '%f >= 4\n' "${os_version}" | bccmp + if version_ge 4 <"${__global}/explorer/os_version" then # Debian 4 (etch) and later locale_conf="/etc/default/locale" @@ -56,8 +68,7 @@ in locale_conf="/etc/default/locale" ;; ubuntu) - os_version=$(cat "${__global}/explorer/os_version") - if printf '%f >= 6.10\n' "${os_version}" | bccmp + if version_ge 6.10 <"${__global}/explorer/os_version" then # Ubuntu 6.10 (edgy) and later locale_conf="/etc/default/locale" @@ -71,7 +82,7 @@ in centos|redhat|scientific) # shellcheck source=/dev/null version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") - if printf '%f >= 7\n' "${version_id}" | bccmp + if echo "${version_id}" | version_ge 7 then locale_conf="/etc/locale.conf" else @@ -81,7 +92,7 @@ in fedora) # shellcheck source=/dev/null version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") - if printf '%f >= 18\n' "${version_id}" | bccmp + if echo "${version_id}" | version_ge 18 then locale_conf="/etc/locale.conf" quote_value=false @@ -116,8 +127,7 @@ in locale_conf="/etc/default/init" locale_conf_group="sys" - os_version=$(cat "${__global}/explorer/os_version") - if printf '%f >= 5.11\n' "${os_version}" | bccmp + if version_ge 5.11 <"${__global}/explorer/os_version" then # mode on Oracle Solaris 11 is actually 0444, # but the write bit makes sense, IMO From 7b480f4293b84a97850430a9436e28c66ccf5736 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 2 Aug 2020 22:08:14 +0200 Subject: [PATCH 060/411] [type/__locale_system] Fix version extraction for SuSE --- cdist/conf/type/__locale_system/manifest | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__locale_system/manifest b/cdist/conf/type/__locale_system/manifest index 88eadb31..4b996ebc 100755 --- a/cdist/conf/type/__locale_system/manifest +++ b/cdist/conf/type/__locale_system/manifest @@ -163,7 +163,13 @@ in key="export ${__object_id}" ;; suse) - os_version=$(cat "${__global}/explorer/os_version") + if test -s "${__global}/explorer/os_release" + then + # shellcheck source=/dev/null + os_version=$(. "${__global}/explorer/os_release" && echo "${VERSION}") + else + os_version=$(sed -n 's/^VERSION\ *=\ *//p' "${__global}/explorer/os_version") + fi os_major=$(expr "${os_version}" : '\([0-9]\{1,\}\)') # https://documentation.suse.com/sles/15-SP2/html/SLES-all/cha-suse.html#sec-suse-l10n From b370b70ff4ccc1c6efca97f61f220a5ce0b191da Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 2 Aug 2020 22:13:41 +0200 Subject: [PATCH 061/411] [explorer/os] Fix OS detection for openSUSE All distros with ID_LIKE suse should be treated as "suse". My openSUSE Leap 15.1 installation has: ID_LIKE="suse opensuse" This patch doesn't require a strict "suse" value but only the word suse to be in the list. --- cdist/conf/explorer/os | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cdist/conf/explorer/os b/cdist/conf/explorer/os index 2d2aede6..8f54d9c8 100755 --- a/cdist/conf/explorer/os +++ b/cdist/conf/explorer/os @@ -144,7 +144,8 @@ esac if [ -f /etc/os-release ]; then # after sles15, suse don't provide an /etc/SuSE-release anymore, but there is almost no difference between sles and opensuse leap, so call it suse - if grep -q ^ID_LIKE=\"suse\" /etc/os-release 2>/dev/null; then + if (. /etc/os-release && echo "${ID_LIKE}" | grep -q '\(^\|\ \)suse\($\|\ \)') + then echo suse exit 0 fi From 17ab4bd80c9c9dda2fa4f8ccde5ee454f7b5ba2d Mon Sep 17 00:00:00 2001 From: Joachim Desroches Date: Thu, 6 Aug 2020 11:45:05 +0200 Subject: [PATCH 062/411] Add Alpine Linux as supported for __filesystem. --- cdist/conf/type/__filesystem/explorer/lsblk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__filesystem/explorer/lsblk b/cdist/conf/type/__filesystem/explorer/lsblk index 9ae544ac..9be3c575 100644 --- a/cdist/conf/type/__filesystem/explorer/lsblk +++ b/cdist/conf/type/__filesystem/explorer/lsblk @@ -18,16 +18,16 @@ # along with cdist. If not, see . # -os=$("$__explorer/os") +os=$("${__explorer:?}/os") -if [ -f "$__object/parameter/device" ]; then +if [ -f "${__object:?}/parameter/device" ]; then blkdev="$(cat "$__object/parameter/device")" else - blkdev="$__object_id" + blkdev="${__object_id:?}" fi case "$os" in - centos|fedora|redhat|suse|gentoo) + alpine|centos|fedora|redhat|suse|gentoo) if [ ! -x "$(command -v lsblk)" ]; then echo "lsblk is required for __filesystem type" >&2 exit 1 From 74dd47c8c352cc3de3b5684bbe90520f61d95f37 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Aug 2020 21:11:43 +0200 Subject: [PATCH 063/411] ++changelog --- docs/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changelog b/docs/changelog index 269a2049..2c09bfea 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,6 +1,12 @@ Changelog --------- +next: + * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) + * Type __unpack: Add --tar-extra-args parameter (Ander Punnar) + * Explorer os: Fix OS detection for openSUSE (Dennis Camera) + * Type __filesystem: Support Alpine Linux (Joachim Desroches) + 6.7.0: 2020-07-28 * Delete deprecated type: __pf_apply (Darko Poljak) * New type: __download (Ander Punnar) From 8f94a226c7f0b875987e25e57682414204380fa2 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 15 Aug 2020 21:54:07 +0200 Subject: [PATCH 064/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 2c09bfea..9e44cc4d 100644 --- a/docs/changelog +++ b/docs/changelog @@ -6,6 +6,7 @@ next: * Type __unpack: Add --tar-extra-args parameter (Ander Punnar) * Explorer os: Fix OS detection for openSUSE (Dennis Camera) * Type __filesystem: Support Alpine Linux (Joachim Desroches) + * Type __locale_system: Fix version comparison (Dennis Camera) 6.7.0: 2020-07-28 * Delete deprecated type: __pf_apply (Darko Poljak) From 6fed1785298eb506e7ea6cd177efe7d96658769f Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Mon, 17 Aug 2020 09:27:48 +0200 Subject: [PATCH 065/411] [explorer/os_version] Convert Debian sid to version number. Conversion of Debian sid to versions is done based on Debian codenames. The version number is the version number of the final release - 0.01. It is unknown if Debian < 4.0 has any sort of version information available (apart from maybe checking base-files package version). But I don't think any of these systems are still alive, so I think going with 3.99 is fine for those. --- cdist/conf/explorer/os_version | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/cdist/conf/explorer/os_version b/cdist/conf/explorer/os_version index 1d54ea60..a7b1d3bc 100755 --- a/cdist/conf/explorer/os_version +++ b/cdist/conf/explorer/os_version @@ -31,7 +31,32 @@ case "$("$__explorer/os")" in cat /etc/arch-release ;; debian) - cat /etc/debian_version + debian_version=$(cat /etc/debian_version) + case $debian_version + in + testing/unstable) + # previous to Debian 4.0 testing/unstable was used + # cf. https://metadata.ftp-master.debian.org/changelogs/main/b/base-files/base-files_11_changelog + echo 3.99 + ;; + */sid) + # sid versions don't have a number, so we decode by codename: + case $(expr "$debian_version" : '\([a-z]\{1,\}\)/') + in + bullseye) echo 10.99 ;; + buster) echo 9.99 ;; + stretch) echo 8.99 ;; + jessie) echo 7.99 ;; + wheezy) echo 6.99 ;; + squeeze) echo 5.99 ;; + lenny) echo 4.99 ;; + *) exit 1 + esac + ;; + *) + echo "$debian_version" + ;; + esac ;; devuan) cat /etc/devuan_version @@ -73,4 +98,4 @@ case "$("$__explorer/os")" in alpine) cat /etc/alpine-release ;; -esac \ No newline at end of file +esac From 502d75304707704d3ba73374701394b98d259506 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Tue, 18 Aug 2020 00:46:07 +0300 Subject: [PATCH 066/411] [__unpack] add --onchange --- cdist/conf/type/__unpack/gencode-remote | 5 +++++ cdist/conf/type/__unpack/man.rst | 3 +++ cdist/conf/type/__unpack/parameter/optional | 1 + 3 files changed, 9 insertions(+) diff --git a/cdist/conf/type/__unpack/gencode-remote b/cdist/conf/type/__unpack/gencode-remote index 3b7a19a7..c4451f73 100755 --- a/cdist/conf/type/__unpack/gencode-remote +++ b/cdist/conf/type/__unpack/gencode-remote @@ -80,3 +80,8 @@ if [ ! -f "$__object/parameter/preserve-archive" ] then echo "rm -f '$src'" fi + +if [ -f "$__object/parameter/onchange" ] +then + cat "$__object/parameter/onchange" +fi diff --git a/cdist/conf/type/__unpack/man.rst b/cdist/conf/type/__unpack/man.rst index bd0603cf..daa03814 100644 --- a/cdist/conf/type/__unpack/man.rst +++ b/cdist/conf/type/__unpack/man.rst @@ -50,6 +50,9 @@ backup-destination preserve-archive Don't delete archive after unpacking. +onchange + Execute this command after unpack. + EXAMPLES -------- diff --git a/cdist/conf/type/__unpack/parameter/optional b/cdist/conf/type/__unpack/parameter/optional index da26ca63..d846ac75 100644 --- a/cdist/conf/type/__unpack/parameter/optional +++ b/cdist/conf/type/__unpack/parameter/optional @@ -1,3 +1,4 @@ sum-file tar-strip tar-extra-args +onchange From d239169c4f91a4ce33be170ed29b08299c51234f Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Tue, 18 Aug 2020 00:48:58 +0300 Subject: [PATCH 067/411] [__download] fix manual: onchange parameter in wrong section --- cdist/conf/type/__download/man.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index 6ec0b19a..eb3ac971 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -30,9 +30,6 @@ sum By default output of ``cksum`` without filename is expected. Other hash formats supported with prefixes: ``md5:``, ``sha1:`` and ``sha256:``. -onchange - Execute this command after download. - OPTIONAL PARAMETERS ------------------- @@ -54,6 +51,9 @@ cmd-sum format specification ``%s`` which will become destination. For example: ``md5sum '%s' | awk '{print $1}'``. +onchange + Execute this command after download. + EXAMPLES -------- From ba26a437be4d8034037e7a6eb42382aee01f829e Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Tue, 18 Aug 2020 11:06:19 +0200 Subject: [PATCH 068/411] ++changelog --- docs/changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog b/docs/changelog index 9e44cc4d..a3e4167a 100644 --- a/docs/changelog +++ b/docs/changelog @@ -7,6 +7,9 @@ next: * Explorer os: Fix OS detection for openSUSE (Dennis Camera) * Type __filesystem: Support Alpine Linux (Joachim Desroches) * Type __locale_system: Fix version comparison (Dennis Camera) + * Type __unpack: Add --onchange parameter (Ander Punnar) + * Type __download: Fix manual (Ander Punnar) + * Explorer os_version: Convert Debian sid to version number (Dennis Camera) 6.7.0: 2020-07-28 * Delete deprecated type: __pf_apply (Darko Poljak) From c17541f24cf118b0989a5899cab3a439ed534a46 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sat, 22 Aug 2020 19:53:42 +0200 Subject: [PATCH 069/411] Expand and split by consecutive require delimiters Resolves #832. --- cdist/emulator.py | 6 +++++- cdist/test/emulator/__init__.py | 10 ++++++++++ docs/src/cdist-manifest.rst | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cdist/emulator.py b/cdist/emulator.py index 9fe84056..60b94880 100644 --- a/cdist/emulator.py +++ b/cdist/emulator.py @@ -25,6 +25,7 @@ import argparse import logging import os import sys +import re import cdist from cdist import core @@ -389,12 +390,15 @@ class Emulator: if "require" in self.env: requirements = self.env['require'] self.log.debug("reqs = " + requirements) - for requirement in requirements.split(" "): + for requirement in self._parse_require(requirements): # Ignore empty fields - probably the only field anyway if len(requirement) == 0: continue self.record_requirement(requirement) + def _parse_require(self, require): + return re.split(r'[ \t\n]+', require) + def record_auto_requirements(self): """An object shall automatically depend on all objects that it defined in it's type manifest. diff --git a/cdist/test/emulator/__init__.py b/cdist/test/emulator/__init__.py index e375676c..befd7b57 100644 --- a/cdist/test/emulator/__init__.py +++ b/cdist/test/emulator/__init__.py @@ -685,6 +685,16 @@ class EmulatorAlreadyExistingRequirementsWarnTestCase(test.CdistTestCase): self.env['require'] = '__directory/spam' emu = emulator.Emulator(argv, env=self.env) + def test_parse_require(self): + require = " \t \n \t\t\n\t\na\tb\nc d \te\t\nf\ng\t " + expected = ['', 'a', 'b', 'c', 'd', 'e', 'f', 'g', '', ] + + argv = ['__directory', 'spam'] + emu = emulator.Emulator(argv, env=self.env) + requirements = emu._parse_require(require) + + self.assertEqual(expected, requirements) + if __name__ == '__main__': import unittest diff --git a/docs/src/cdist-manifest.rst b/docs/src/cdist-manifest.rst index 5dbca479..2e49a721 100644 --- a/docs/src/cdist-manifest.rst +++ b/docs/src/cdist-manifest.rst @@ -95,7 +95,8 @@ Dependencies ------------ If you want to describe that something requires something else, just setup the variable "require" to contain the requirements. Multiple -requirements can be added white space separated. +requirements can be added separated with (optionally consecutive) +delimiters including space, tab and newline. :: From b5a40eb0d1c8990f0feb8e918a95e54e4fd35d98 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 27 Aug 2020 12:25:11 +0200 Subject: [PATCH 070/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index a3e4167a..eda77a12 100644 --- a/docs/changelog +++ b/docs/changelog @@ -10,6 +10,7 @@ next: * Type __unpack: Add --onchange parameter (Ander Punnar) * Type __download: Fix manual (Ander Punnar) * Explorer os_version: Convert Debian sid to version number (Dennis Camera) + * Core: Expand require delimiter characters, split by consecutive delimiters (Darko Poljak) 6.7.0: 2020-07-28 * Delete deprecated type: __pf_apply (Darko Poljak) From b1375464cc7507b38dd02f2df52c75489837d129 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sun, 6 Sep 2020 13:24:58 +0200 Subject: [PATCH 071/411] __systemd_service: fix manpage typos --- cdist/conf/type/__systemd_service/man.rst | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/cdist/conf/type/__systemd_service/man.rst b/cdist/conf/type/__systemd_service/man.rst index 7eca398b..cd14c985 100644 --- a/cdist/conf/type/__systemd_service/man.rst +++ b/cdist/conf/type/__systemd_service/man.rst @@ -1,9 +1,10 @@ -cdist-type__systemd-service(7) +cdist-type__systemd_service(7) ============================== NAME ---- -cdist-type__systemd-service - Controls a systemd service state +cdist-type__systemd_service - Controls a systemd service state + DESCRIPTION ----------- @@ -14,11 +15,12 @@ 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 ------------------- @@ -31,12 +33,12 @@ state running Service should run (default) - stoppend - Service should stopped + stopped + Service should be 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: + service keeps the state ``running``. There are following actions, where: reload Reloads the service @@ -48,11 +50,12 @@ 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 + Only execute the action if at 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 -------- @@ -68,12 +71,14 @@ restart reload Reloaded the service + ABORTS ------ Aborts in following cases: systemd or the service does not exist + EXAMPLES -------- .. code-block:: sh @@ -95,13 +100,15 @@ EXAMPLES # 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 \ + require="__file/etc/foo.conf" __systemd_service foo \ --action reload --if-required + AUTHORS ------- Matthias Stecher + COPYRIGHT --------- Copyright \(C) 2020 Matthias Stecher. You can redistribute it From 6b262a61c19234f6450cef11f715020dcd5f40d5 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 10 Sep 2020 13:24:58 +0200 Subject: [PATCH 072/411] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index eda77a12..e4ec3fdd 100644 --- a/docs/changelog +++ b/docs/changelog @@ -11,6 +11,8 @@ next: * Type __download: Fix manual (Ander Punnar) * Explorer os_version: Convert Debian sid to version number (Dennis Camera) * Core: Expand require delimiter characters, split by consecutive delimiters (Darko Poljak) + * Type __timezone: Make singleton (Dennis Camera) + * Type __systemd_service: Fix manpage typos (Matthias Stecher) 6.7.0: 2020-07-28 * Delete deprecated type: __pf_apply (Darko Poljak) From 53b91adbd8be4d858f1f4da3389b63babc85db0c Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 11 Sep 2020 14:19:45 +0200 Subject: [PATCH 073/411] Fix shellcheck --- cdist/conf/explorer/os | 1 + 1 file changed, 1 insertion(+) diff --git a/cdist/conf/explorer/os b/cdist/conf/explorer/os index 8f54d9c8..46d87f3e 100755 --- a/cdist/conf/explorer/os +++ b/cdist/conf/explorer/os @@ -144,6 +144,7 @@ esac if [ -f /etc/os-release ]; then # after sles15, suse don't provide an /etc/SuSE-release anymore, but there is almost no difference between sles and opensuse leap, so call it suse + # shellcheck disable=SC1091 if (. /etc/os-release && echo "${ID_LIKE}" | grep -q '\(^\|\ \)suse\($\|\ \)') then echo suse From 2885c6a24838956167ae6c33ebf87067e8790083 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 11 Sep 2020 14:15:26 +0200 Subject: [PATCH 074/411] Release 6.8.0 --- docs/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog b/docs/changelog index e4ec3fdd..7a0d050d 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,7 +1,7 @@ Changelog --------- -next: +6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) * Type __unpack: Add --tar-extra-args parameter (Ander Punnar) * Explorer os: Fix OS detection for openSUSE (Dennis Camera) From decc0ad54dffbafcd7d3644c28ae4d149926e612 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 18 Sep 2020 19:33:36 +0300 Subject: [PATCH 075/411] [__package_pip] detect pip binary --- cdist/conf/type/__package_pip/explorer/pip | 10 ++++++++++ cdist/conf/type/__package_pip/explorer/state | 2 +- cdist/conf/type/__package_pip/gencode-remote | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100755 cdist/conf/type/__package_pip/explorer/pip diff --git a/cdist/conf/type/__package_pip/explorer/pip b/cdist/conf/type/__package_pip/explorer/pip new file mode 100755 index 00000000..cf9fae89 --- /dev/null +++ b/cdist/conf/type/__package_pip/explorer/pip @@ -0,0 +1,10 @@ +#!/bin/sh -e + +for bin in pip3 pip +do + if check="$( command -v "$bin" )" + then + echo "$check" + break + fi +done diff --git a/cdist/conf/type/__package_pip/explorer/state b/cdist/conf/type/__package_pip/explorer/state index 5be07280..3cc98ab9 100644 --- a/cdist/conf/type/__package_pip/explorer/state +++ b/cdist/conf/type/__package_pip/explorer/state @@ -32,7 +32,7 @@ pipparam="$__object/parameter/pip" if [ -f "$pipparam" ]; then pip=$(cat "$pipparam") else - pip="pip" + pip="$( "$__type_explorer/pip" )" fi # If there is no pip, it may get created from somebody else. diff --git a/cdist/conf/type/__package_pip/gencode-remote b/cdist/conf/type/__package_pip/gencode-remote index dcc4fdf9..9c5eb0d1 100755 --- a/cdist/conf/type/__package_pip/gencode-remote +++ b/cdist/conf/type/__package_pip/gencode-remote @@ -38,7 +38,12 @@ pipparam="$__object/parameter/pip" if [ -f "$pipparam" ]; then pip=$(cat "$pipparam") else - pip="pip" + pip="$( cat "$__object/explorer/pip" )" + if [ -z "$pip" ] + then + echo 'pip not found in path' >&2 + exit 1 + fi fi runasparam="$__object/parameter/runas" From 89b621511561105cfcfcf12bbf820b74ab03396d Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 21 Sep 2020 09:04:05 +0200 Subject: [PATCH 076/411] Clarify stdin input Resolve #836. --- cdist/argparse.py | 36 ++++++-------------------- cdist/config.py | 6 +++-- cdist/inventory.py | 4 +-- cdist/test/inventory/__init__.py | 3 +-- docs/src/man1/cdist.rst | 44 ++++++++++---------------------- 5 files changed, 29 insertions(+), 64 deletions(-) diff --git a/cdist/argparse.py b/cdist/argparse.py index 77303591..1d16bb25 100644 --- a/cdist/argparse.py +++ b/cdist/argparse.py @@ -273,8 +273,7 @@ def get_parsers(): '-f', '--file', help=('Read specified file for a list of additional hosts to ' 'operate on or if \'-\' is given, read stdin (one host per ' - 'line). If no host or host file is specified then, by ' - 'default, read hosts from stdin.'), + 'line).'), dest='hostfile', required=False) parser['config_args'].add_argument( '-p', '--parallel', nargs='?', metavar='HOST_MAX', @@ -326,9 +325,7 @@ def get_parsers(): parser['add-host'].add_argument( '-f', '--file', help=('Read additional hosts to add from specified file ' - 'or from stdin if \'-\' (each host on separate line). ' - 'If no host or host file is specified then, by default, ' - 'read from stdin.'), + 'or from stdin if \'-\' (each host on separate line). '), dest='hostfile', required=False) parser['add-tag'] = parser['invsub'].add_parser( @@ -342,20 +339,12 @@ def get_parsers(): parser['add-tag'].add_argument( '-f', '--file', help=('Read additional hosts to add tags from specified file ' - 'or from stdin if \'-\' (each host on separate line). ' - 'If no host or host file is specified then, by default, ' - 'read from stdin. If no tags/tagfile nor hosts/hostfile' - ' are specified then tags are read from stdin and are' - ' added to all hosts.'), + 'or from stdin if \'-\' (each host on separate line). '), dest='hostfile', required=False) parser['add-tag'].add_argument( '-T', '--tag-file', help=('Read additional tags to add from specified file ' - 'or from stdin if \'-\' (each tag on separate line). ' - 'If no tag or tag file is specified then, by default, ' - 'read from stdin. If no tags/tagfile nor hosts/hostfile' - ' are specified then tags are read from stdin and are' - ' added to all hosts.'), + 'or from stdin if \'-\' (each tag on separate line). '), dest='tagfile', required=False) parser['add-tag'].add_argument( '-t', '--taglist', @@ -376,9 +365,7 @@ def get_parsers(): parser['del-host'].add_argument( '-f', '--file', help=('Read additional hosts to delete from specified file ' - 'or from stdin if \'-\' (each host on separate line). ' - 'If no host or host file is specified then, by default, ' - 'read from stdin.'), + 'or from stdin if \'-\' (each host on separate line). '), dest='hostfile', required=False) parser['del-tag'] = parser['invsub'].add_parser( @@ -396,20 +383,13 @@ def get_parsers(): parser['del-tag'].add_argument( '-f', '--file', help=('Read additional hosts to delete tags for from specified ' - 'file or from stdin if \'-\' (each host on separate line). ' - 'If no host or host file is specified then, by default, ' - 'read from stdin. If no tags/tagfile nor hosts/hostfile' - ' are specified then tags are read from stdin and are' - ' deleted from all hosts.'), + 'file or from stdin if \'-\' (each host on separate ' + 'line). '), dest='hostfile', required=False) parser['del-tag'].add_argument( '-T', '--tag-file', help=('Read additional tags from specified file ' - 'or from stdin if \'-\' (each tag on separate line). ' - 'If no tag or tag file is specified then, by default, ' - 'read from stdin. If no tags/tagfile nor' - ' hosts/hostfile are specified then tags are read from' - ' stdin and are added to all hosts.'), + 'or from stdin if \'-\' (each tag on separate line). '), dest='tagfile', required=False) parser['del-tag'].add_argument( '-t', '--taglist', diff --git a/cdist/config.py b/cdist/config.py index 30416008..e84f6f84 100644 --- a/cdist/config.py +++ b/cdist/config.py @@ -175,9 +175,11 @@ class Config: raise cdist.Error(("Cannot read both, manifest and host file, " "from stdin")) - # if no host source is specified then read hosts from stdin if not (args.hostfile or args.host): - args.hostfile = '-' + if args.tag or args.all_tagged_hosts: + raise cdist.Error(("Target host tag(s) missing")) + else: + raise cdist.Error(("Target host(s) missing")) if args.manifest == '-': # read initial manifest from stdin diff --git a/cdist/inventory.py b/cdist/inventory.py index 6ab20fa7..0387f326 100644 --- a/cdist/inventory.py +++ b/cdist/inventory.py @@ -299,7 +299,7 @@ class InventoryHost(Inventory): self.all = all if not self.hosts and not self.hostfile: - self.hostfile = "-" + raise cdist.Error("Host(s) missing") def _new_hostpath(self, hostpath): # create empty file @@ -355,7 +355,7 @@ class InventoryTag(Inventory): else: self.allhosts = False if not self.tags and not self.tagfile: - self.tagfile = "-" + raise cdist.Error("Tag(s) missing") if self.hostfile == "-" and self.tagfile == "-": raise cdist.Error("Cannot read both, hosts and tags, from stdin") diff --git a/cdist/test/inventory/__init__.py b/cdist/test/inventory/__init__.py index 287c855c..a8cd8bf8 100644 --- a/cdist/test/inventory/__init__.py +++ b/cdist/test/inventory/__init__.py @@ -307,11 +307,10 @@ class InventoryTestCase(test.CdistTestCase): raise e # InventoryTag + @unittest.expectedFailure def test_inventory_tag_init(self): invTag = inventory.InventoryTag(db_basedir=inventory_dir, action="add") - self.assertTrue(invTag.allhosts) - self.assertEqual(invTag.tagfile, "-") def test_inventory_tag_stdin_multiple_hosts(self): try: diff --git a/docs/src/man1/cdist.rst b/docs/src/man1/cdist.rst index aa2607f8..0ecb4a61 100644 --- a/docs/src/man1/cdist.rst +++ b/docs/src/man1/cdist.rst @@ -177,10 +177,8 @@ Install command is currently in beta. **-f HOSTFILE, --file HOSTFILE** Read specified file for a list of additional hosts to operate on - or if '-' is given, read stdin (one host per line). - If no host or host file is specified then, by default, - read hosts from stdin. For the file format see - :strong:`HOSTFILE FORMAT` below. + or if '-' is given, read stdin (one host per line). For the file + format see :strong:`HOSTFILE FORMAT` below. **-g CONFIG_FILE, --config-file CONFIG_FILE** Use specified custom configuration file. @@ -299,9 +297,8 @@ Add host(s) to inventory database. **-f HOSTFILE, --file HOSTFILE** Read additional hosts to add from specified file or - from stdin if '-' (each host on separate line). If no - host or host file is specified then, by default, read - from stdin. Hostfile format is the same as config hostfile format. + from stdin if '-' (each host on separate line). + Hostfile format is the same as config hostfile format. **-g CONFIG_FILE, --config-file CONFIG_FILE** Use specified custom configuration file. @@ -327,11 +324,8 @@ Add tag(s) to inventory database. **-f HOSTFILE, --file HOSTFILE** Read additional hosts to add tags from specified file - or from stdin if '-' (each host on separate line). If - no host or host file is specified then, by default, - read from stdin. If no tags/tagfile nor hosts/hostfile - are specified then tags are read from stdin and are - added to all hosts. Hostfile format is the same as config hostfile format. + or from stdin if '-' (each host on separate line). + Hostfile format is the same as config hostfile format. **-g CONFIG_FILE, --config-file CONFIG_FILE** Use specified custom configuration file. @@ -346,11 +340,8 @@ Add tag(s) to inventory database. **-T TAGFILE, --tag-file TAGFILE** Read additional tags to add from specified file or - from stdin if '-' (each tag on separate line). If no - tag or tag file is specified then, by default, read - from stdin. If no tags/tagfile nor hosts/hostfile are - specified then tags are read from stdin and are added - to all hosts. Tagfile format is the same as config hostfile format. + from stdin if '-' (each tag on separate line). + Tagfile format is the same as config hostfile format. **-t TAGLIST, --taglist TAGLIST** Tag list to be added for specified host(s), comma @@ -372,9 +363,8 @@ Delete host(s) from inventory database. **-f HOSTFILE, --file HOSTFILE** Read additional hosts to delete from specified file or - from stdin if '-' (each host on separate line). If no - host or host file is specified then, by default, read - from stdin. Hostfile format is the same as config hostfile format. + from stdin if '-' (each host on separate line). + Hostfile format is the same as config hostfile format. **-g CONFIG_FILE, --config-file CONFIG_FILE** Use specified custom configuration file. @@ -404,11 +394,8 @@ Delete tag(s) from inventory database. **-f HOSTFILE, --file HOSTFILE** Read additional hosts to delete tags for from specified file or from stdin if '-' (each host on - separate line). If no host or host file is specified - then, by default, read from stdin. If no tags/tagfile - nor hosts/hostfile are specified then tags are read - from stdin and are deleted from all hosts. Hostfile - format is the same as config hostfile format. + separate line). Hostfile format is the same as + config hostfile format. **-g CONFIG_FILE, --config-file CONFIG_FILE** Use specified custom configuration file. @@ -423,11 +410,8 @@ Delete tag(s) from inventory database. **-T TAGFILE, --tag-file TAGFILE** Read additional tags from specified file or from stdin - if '-' (each tag on separate line). If no tag or tag - file is specified then, by default, read from stdin. - If no tags/tagfile nor hosts/hostfile are specified - then tags are read from stdin and are added to all - hosts. Tagfile format is the same as config hostfile format. + if '-' (each tag on separate line). + Tagfile format is the same as config hostfile format. **-t TAGLIST, --taglist TAGLIST** Tag list to be deleted for specified host(s), comma From 89a0080e133052b82ce19e7fdbaf045dcc833da7 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 21 Sep 2020 09:09:26 +0200 Subject: [PATCH 077/411] ++changelog --- docs/changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog b/docs/changelog index 7a0d050d..260b4fe4 100644 --- a/docs/changelog +++ b/docs/changelog @@ -1,6 +1,10 @@ Changelog --------- +next: + * Core: Clarify stdin input (Darko Poljak) + * Type __package_pip: Detect pip binary (Ander Punnar) + 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) * Type __unpack: Add --tar-extra-args parameter (Ander Punnar) From 0fc10749edc698d1f70f826603d009fba943d252 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 21 Sep 2020 09:11:35 +0200 Subject: [PATCH 078/411] Fix shellcheck --- cdist/conf/type/__package_pip/gencode-remote | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__package_pip/gencode-remote b/cdist/conf/type/__package_pip/gencode-remote index 9c5eb0d1..a1375c2d 100755 --- a/cdist/conf/type/__package_pip/gencode-remote +++ b/cdist/conf/type/__package_pip/gencode-remote @@ -60,7 +60,7 @@ case "$state_should" in then echo "su -c '$pip install -q $name' $runas" else - echo $pip install -q "$name" + echo "$pip" install -q "$name" fi echo "installed" >> "$__messages_out" ;; @@ -69,7 +69,7 @@ case "$state_should" in then echo "su -c '$pip uninstall -q -y $name' $runas" else - echo $pip uninstall -q -y "$name" + echo "$pip" uninstall -q -y "$name" fi echo "removed" >> "$__messages_out" ;; From b6922508b9e07834009a6bfae2d3933b5ea62fbf Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 21 Sep 2020 09:17:34 +0200 Subject: [PATCH 079/411] Update helper script --- bin/build-helper | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/build-helper b/bin/build-helper index ed41e438..d4d603ed 100755 --- a/bin/build-helper +++ b/bin/build-helper @@ -371,7 +371,6 @@ eof Manual steps post release: - cdist-web - send generated mailinglist.tmp mail - - twitter eof ;; From 84a7818121047cf6bb23d8bd3c055d09bb033d32 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Wed, 23 Sep 2020 20:29:47 +0200 Subject: [PATCH 080/411] docs: make varaibles environment-aware There are all overwriting the environment, even the comment states otherwise. Fixes it. --- docs/src/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/Makefile b/docs/src/Makefile index 2ecf7a32..ba87d170 100644 --- a/docs/src/Makefile +++ b/docs/src/Makefile @@ -2,10 +2,10 @@ # # You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = ../dist +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +PAPER ?= +BUILDDIR ?= ../dist # for cache, etc. _BUILDDIR = _build From 73d6c9d469d1429999ea2e980b3ac4c63a3e0dd4 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sun, 27 Sep 2020 10:17:35 +0200 Subject: [PATCH 081/411] Add custom remote copy/exec examples --- docs/src/cdist-remote-exec-copy.rst | 389 +++++++++++++++++++++++++++- 1 file changed, 388 insertions(+), 1 deletion(-) diff --git a/docs/src/cdist-remote-exec-copy.rst b/docs/src/cdist-remote-exec-copy.rst index bb818310..e7b7b226 100644 --- a/docs/src/cdist-remote-exec-copy.rst +++ b/docs/src/cdist-remote-exec-copy.rst @@ -10,7 +10,7 @@ By default this is accomplished with ssh and scp respectively. The default implementations used by cdist are:: __remote_exec: ssh -o User=root - __remote_copy: scp -o User=root + __remote_copy: scp -o User=root -q The user can override these defaults by providing custom implementations and passing them to cdist with the --remote-exec and/or --remote-copy arguments. @@ -26,3 +26,390 @@ specified by enclosed in square brackets (see :strong:`ssh`\ (1) and With this simple interface the user can take total control of how cdist interacts with the target when required, while the default implementation remains as simple as possible. + + +Examples +-------- + +Here are examples of using alternative __remote_copy and __remote_exec scripts. + +All scripts from below are present in cdist sources in `other/examples/remote` +directory. + +ssh +~~~ + +Same as cdist default. + +**copy** + +Usage: cdist config --remote-copy "/path/to/this/script" target_host + +.. code-block:: sh + + #echo "$@" | logger -t "cdist-ssh-copy" + scp -o User=root -q $@ + +**exec** + +Usage: cdist config --remote-exec "/path/to/this/script" target_host + +.. code-block:: sh + + #echo "$@" | logger -t "cdist-ssh-exec" + ssh -o User=root $@ + +local +~~~~~ + +This effectively turns remote calling into local calling. Probably most useful +for the unit testing. + +**copy** + +.. code-block:: sh + + code="$(echo "$@" | sed "s|\([[:space:]]\)$__target_host:|\1|g")" + cp -L $code + +**exec** + +.. code-block:: sh + + target_host=$1; shift + echo "$@" | /bin/sh + +chroot +~~~~~~ + +**copy** + +Usage: cdist config --remote-copy "/path/to/this/script /path/to/your/chroot" target-id + +.. code-block:: sh + + log() { + #echo "$@" | logger -t "cdist-chroot-copy" + : + } + + chroot="$1"; shift + target_host="$__target_host" + + # replace target_host with chroot location + code="$(echo "$@" | sed "s|$target_host:|$chroot|g")" + + log "target_host: $target_host" + log "chroot: $chroot" + log "$@" + log "$code" + + # copy files into chroot + cp $code + + log "-----" + +**exec** + +Usage: cdist config --remote-exec "/path/to/this/script /path/to/your/chroot" target-id + +.. code-block:: sh + + log() { + #echo "$@" | logger -t "cdist-chroot-exec" + : + } + + chroot="$1"; shift + target_host="$1"; shift + + script=$(mktemp "${chroot}/tmp/chroot-${0##*/}.XXXXXXXXXX") + trap cleanup INT TERM EXIT + cleanup() { + [ $__cdist_debug ] || rm "$script" + } + + log "target_host: $target_host" + log "script: $script" + log "@: $@" + echo "#!/bin/sh -l" > "$script" + echo "$@" >> "$script" + chmod +x "$script" + + relative_script="${script#$chroot}" + log "relative_script: $relative_script" + + # run in chroot + chroot "$chroot" "$relative_script" + + log "-----" + +rsync +~~~~~ + +**copy** + +Usage: cdist config --remote-copy /path/to/this/script target_host + +.. code-block:: sh + + # For rsync to do the right thing, the source has to end with "/" if it is + # a directory. The below preprocessor loop takes care of that. + + # second last argument is the source + source_index=$(($#-1)) + index=0 + for arg in $@; do + if [ $index -eq 0 ]; then + # reset $@ + set -- + fi + index=$((index+=1)) + if [ $index -eq $source_index -a -d "$arg" ]; then + arg="${arg%/}/" + fi + set -- "$@" "$arg" + done + + rsync --backup --suffix=~cdist -e 'ssh -o User=root' $@ + +schroot +~~~~~~~ + +__remote_copy and __remote_exec scripts to run cdist against a chroot on the +target host over ssh. + +**copy** + +Usage: cdist config --remote-copy "/path/to/this/script schroot-chroot-name" target_host + + +.. code-block:: sh + + log() { + #echo "$@" | logger -t "cdist-schroot-copy" + : + } + + chroot_name="$1"; shift + target_host="$__target_host" + + # get directory for given chroot_name + chroot="$(ssh -o User=root -q $target_host schroot -c $chroot_name --config | awk -F = '/directory=/ {print $2}')" + + # prefix destination with chroot + code="$(echo "$@" | sed "s|$target_host:|$target_host:$chroot|g")" + + log "target_host: $target_host" + log "chroot_name: $chroot_name" + log "chroot: $chroot" + log "@: $@" + log "code: $code" + + # copy files into remote chroot + scp -o User=root -q $code + + log "-----" + +**exec** + +Usage: cdist config --remote-exec "/path/to/this/script schroot-chroot-name" target_host + +.. code-block:: sh + + log() { + #echo "$@" | logger -t "cdist-schroot-exec" + : + } + + chroot_name="$1"; shift + target_host="$1"; shift + + code="ssh -o User=root -q $target_host schroot -c $chroot_name -- $@" + + log "target_host: $target_host" + log "chroot_name: $chroot_name" + log "@: $@" + log "code: $code" + + # run in remote chroot + $code + + log "-----" + +schroot-uri +~~~~~~~~~~~ + +__remote_exec/__remote_copy script to run cdist against a schroot target URI. + +Usage:: + + cdist config \ + --remote-exec "/path/to/this/script exec" \ + --remote-copy "/path/to/this/script copy" \ + target_uri + + # target_uri examples: + schroot:///chroot-name + schroot://foo.ethz.ch/chroot-name + schroot://user-name@foo.ethz.ch/chroot-name + + # and how to match them in .../manifest/init + case "$target_host" in + schroot://*) + # any schroot + ;; + schroot://foo.ethz.ch/*) + # any schroot on specific host + ;; + schroot://foo.ethz.ch/chroot-name) + # specific schroot on specific host + ;; + schroot:///chroot-name) + # specific schroot on localhost + ;; + esac + +**copy/exec** + +.. code-block:: sh + + my_name="${0##*/}" + mode="$1"; shift + + log() { + # uncomment me for debugging + #echo "$@" | logger -t "cdist-$my_name-$mode" + : + } + + die() { + echo "$@" >&2 + exit 1 + } + + + uri="$__target_host" + + scheme="${uri%%:*}"; rest="${uri#$scheme:}"; rest="${rest#//}" + authority="${rest%%/*}"; rest="${rest#$authority}" + path="${rest%\?*}"; rest="${rest#$path}" + schroot_name="${path#/}" + + [ "$scheme" = "schroot" ] || die "Failed to parse scheme from __target_host ($__target_host). Expected 'schroot', got '$scheme'" + [ -n "$schroot_name" ] || die "Failed to parse schroot name from __target_host: $__target_host" + + case "$authority" in + '') + # authority is empty, neither user nor host given + user="" + host="" + ;; + *@*) + # authority contains @, take user from authority + user="${authority%@*}" + host="${authority#*@}" + ;; + *) + # no user in authority, default to root + user="root" + host="$authority" + ;; + esac + + log "mode: $mode" + log "@: $@" + log "uri: $uri" + log "scheme: $scheme" + log "authority: $authority" + log "user: $user" + log "host: $host" + log "path: $path" + log "schroot_name: $schroot_name" + + exec_prefix="" + copy_prefix="" + if [ -n "$host" ]; then + # we are working on a remote host + exec_prefix="ssh -o User=$user -q $host" + copy_prefix="scp -o User=$user -q" + copy_destination_prefix="$host:" + else + # working on local machine + copy_prefix="cp" + copy_destination_prefix="" + fi + log "exec_prefix: $exec_prefix" + log "copy_prefix: $copy_prefix" + log "copy_destination_prefix: $copy_destination_prefix" + + case "$mode" in + exec) + # In exec mode the first argument is the __target_host which we already got from env. Get rid of it. + shift + code="$exec_prefix schroot -c $schroot_name -- sh -c '$@'" + ;; + copy) + # get directory for given chroot_name + schroot_directory="$($exec_prefix schroot -c $schroot_name --config | awk -F = '/directory=/ {print $2}')" + [ -n "$schroot_directory" ] || die "Failed to retreive schroot directory for schroot: $schroot_name" + log "schroot_directory: $schroot_directory" + # prefix destination with chroot + code="$copy_prefix $(echo "$@" | sed "s|$uri:|${copy_destination_prefix}${schroot_directory}|g")" + ;; + *) die "Unknown mode: $mode";; + esac + + log "code: $code" + + # Run the code + $code + + log "-----" + +sudo +~~~~ + +**copy** + +Use rsync over ssh to copy files. Uses the "--rsync-path" option +to run the remote rsync instance with sudo. + +This command assumes your ssh configuration is already set up in ~/.ssh/config. + +Usage: cdist config --remote-copy /path/to/this/script target_host + +.. code-block:: sh + + # For rsync to do the right thing, the source has to end with "/" if it is + # a directory. The below preprocessor loop takes care of that. + + # second last argument is the source + source_index=$(($#-1)) + index=0 + for arg in $@; do + if [ $index -eq 0 ]; then + # reset $@ + set -- + fi + index=$((index+=1)) + if [ $index -eq $source_index -a -d "$arg" ]; then + arg="${arg%/}/" + fi + set -- "$@" "$arg" + done + + rsync --copy-links --rsync-path="sudo rsync" -e 'ssh' "$@" + +**exec** + +Prefixes all remote commands with sudo. + +This command assumes your ssh configuration is already set up in ~/.ssh/config. + +Usage: cdist config --remote-exec "/path/to/this/script" target_host + +.. code-block:: sh + + host="$1"; shift + ssh -q "$host" sudo sh -c \""$@"\" From 652c89185816526e5165ff9d5686a0d245ec3e5f Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Tue, 29 Sep 2020 05:57:54 +0200 Subject: [PATCH 082/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 260b4fe4..8d380524 100644 --- a/docs/changelog +++ b/docs/changelog @@ -4,6 +4,7 @@ Changelog next: * Core: Clarify stdin input (Darko Poljak) * Type __package_pip: Detect pip binary (Ander Punnar) + * Documentation: Add custom remote copy/exec examples (Darko Poljak) 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) From f994226d0e23b667309fd75116c0c8a14d15f34d Mon Sep 17 00:00:00 2001 From: Evilham Date: Tue, 29 Sep 2020 19:44:47 +0200 Subject: [PATCH 083/411] [__package_pkgng_freebsd] Bootstrap pkg if necessary In a pristine FreeBSD base installation, pkg is really a bootstrapper utility, in such cases the type used to fail instead of automatically bootstrapping pkg. --- .../type/__package_pkgng_freebsd/explorer/pkg_bootstrapped | 4 ++++ cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version | 5 +++++ cdist/conf/type/__package_pkgng_freebsd/gencode-remote | 5 +++++ 3 files changed, 14 insertions(+) create mode 100755 cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_bootstrapped diff --git a/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_bootstrapped b/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_bootstrapped new file mode 100755 index 00000000..429f15d3 --- /dev/null +++ b/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_bootstrapped @@ -0,0 +1,4 @@ +#!/bin/sh -e +if pkg -N >/dev/null 2>&1; then + echo "YES" +fi diff --git a/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version b/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version index 92ce0623..f0fb9127 100755 --- a/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version +++ b/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version @@ -21,6 +21,11 @@ # Retrieve the status of a package - parsed dpkg output # +if ! pkg -N >/dev/null 2>&1; then + # Nothing to do if pkg is not bootstrapped + exit +fi + if [ -f "$__object/parameter/name" ]; then name="$(cat "$__object/parameter/name")" else diff --git a/cdist/conf/type/__package_pkgng_freebsd/gencode-remote b/cdist/conf/type/__package_pkgng_freebsd/gencode-remote index dd36efda..b5944177 100755 --- a/cdist/conf/type/__package_pkgng_freebsd/gencode-remote +++ b/cdist/conf/type/__package_pkgng_freebsd/gencode-remote @@ -43,6 +43,7 @@ fi repo="$(cat "$__object/parameter/repo")" state="$(cat "$__object/parameter/state")" curr_version="$(cat "$__object/explorer/pkg_version")" +pkg_bootstrapped="$(cat "$__object/explorer/pkg_bootstrapped")" add_cmd="pkg install -y" rm_cmd="pkg delete -y" upg_cmd="pkg upgrade -y" @@ -73,6 +74,10 @@ execcmd(){ ;; esac + if [ -z "${pkg_bootstrapped}" ]; then + echo "pkg bootstrap -y >/dev/null 2>&1" + fi + echo "$_cmd >/dev/null 2>&1" # Silence the output of the command echo "status=\$?" echo "if [ \"\$status\" -ne \"0\" ]; then" From 52b5f05163416196403634cb9a52f746cdb96391 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 30 Sep 2020 08:56:31 +0200 Subject: [PATCH 084/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 8d380524..34c97d67 100644 --- a/docs/changelog +++ b/docs/changelog @@ -5,6 +5,7 @@ next: * Core: Clarify stdin input (Darko Poljak) * Type __package_pip: Detect pip binary (Ander Punnar) * Documentation: Add custom remote copy/exec examples (Darko Poljak) + * Type __package_pkgng_freebsd: Bootstrap pkg if necessary (Evil Ham) 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) From 3fa74b454a9512319e3559a53dd477f38724fd9b Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Wed, 30 Sep 2020 15:43:32 +0200 Subject: [PATCH 085/411] Fix typo --- cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version b/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version index f0fb9127..1c6ba5e5 100755 --- a/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version +++ b/cdist/conf/type/__package_pkgng_freebsd/explorer/pkg_version @@ -18,7 +18,7 @@ # along with cdist. If not, see . # # -# Retrieve the status of a package - parsed dpkg output +# Retrieve the status of a package - parsed pkgng output # if ! pkg -N >/dev/null 2>&1; then From 5aeed14b1b8b022f952680cceb12a5099a099558 Mon Sep 17 00:00:00 2001 From: Mark Verboom Date: Thu, 8 Oct 2020 16:15:20 +0200 Subject: [PATCH 086/411] Fixed calling of __systemd_service type with correct arguments. --- cdist/conf/type/__service/manifest | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__service/manifest b/cdist/conf/type/__service/manifest index cb5af234..beb0713c 100644 --- a/cdist/conf/type/__service/manifest +++ b/cdist/conf/type/__service/manifest @@ -7,7 +7,9 @@ action="$(cat "$__object/parameter/action")" case "$manager" in systemd) - __systemd_service "$name" --action "$action" + test "$action" = "start" && action="running" + test "$action" = "stop" && action="stopped" + __systemd_service "$name" --state "$action" ;; *) # Unknown: handled by `service $NAME $action` in gencode-remote. From c030deea3dbccfe73637b730f0d545db7f8d5f35 Mon Sep 17 00:00:00 2001 From: Evil Ham Date: Fri, 9 Oct 2020 06:51:44 +0200 Subject: [PATCH 087/411] [__line] Add support for '--state replace' It is currently counter-intuitive that something like: # File '/thing' contents #SomeSetting WrongValue # Manifest __line '/thing' \ --line 'SomeSeting GoodValue' \ --regex '^(#[[:space:]]*)?SomeSetting[[:space:]]' Produces: # Resulting '/thing' contents #SomeSetting WrongValue This makes sense given the implementation, but it masks a very common use-case. Changing the default behaviour for such a base type is not really an option, so instead we add a `replace` as a valid value for `--state`, which would result in: # Resulting '/thing' contents with: --state replace SomeSetting GoodValue For compatibility, if the regex is missing, `--state replace` behaves just as `--state present`. --- cdist/conf/type/__line/explorer/state | 12 +++++++++++- cdist/conf/type/__line/gencode-remote | 10 +++++++--- cdist/conf/type/__line/man.rst | 13 +++++++++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/cdist/conf/type/__line/explorer/state b/cdist/conf/type/__line/explorer/state index e8fc3630..9d480b19 100755 --- a/cdist/conf/type/__line/explorer/state +++ b/cdist/conf/type/__line/explorer/state @@ -53,8 +53,10 @@ function _find(_text, _pattern) { BEGIN { getline anchor < (ENVIRON["__object"] "/parameter/" position) getline pattern < (ENVIRON["__object"] "/parameter/" needle) + getline line < (ENVIRON["__object"] "/parameter/line") found_line = 0 + correct_line = 0 correct_pos = (position != "after" && position != "before") } { @@ -63,15 +65,18 @@ BEGIN { getline if (_find($0, pattern)) { found_line++ + if (index($0, line) == 1) { correct_line++ } correct_pos = 1 exit 0 } } else if (_find($0, pattern)) { found_line++ + if (index($0, line) == 1) { correct_line++ } } } else if (position == "before") { if (_find($0, pattern)) { found_line++ + if (index($0, line) == 1) { correct_line++ } getline if (match($0, anchor)) { correct_pos = 1 @@ -81,13 +86,18 @@ BEGIN { } else { if (_find($0, pattern)) { found_line++ + if (index($0, line) == 1) { correct_line++ } exit 0 } } } END { if (found_line && correct_pos) { - print "present" + if (correct_line) { + print "present" + } else { + print "matching" + } } else if (found_line) { print "wrongposition" } else { diff --git a/cdist/conf/type/__line/gencode-remote b/cdist/conf/type/__line/gencode-remote index 88cae68b..a89886da 100755 --- a/cdist/conf/type/__line/gencode-remote +++ b/cdist/conf/type/__line/gencode-remote @@ -38,7 +38,11 @@ if [ -z "$state_is" ]; then exit 1 fi -if [ "$state_should" = "$state_is" ]; then +if [ "$state_should" = "$state_is" ] || \ + { [ "$state_should" = "present" ] && [ "$state_is" = "matching" ] ;} || \ + { [ "$state_should" = "replace" ] && [ "$state_is" = "present" ] ;} ; then + # If state matches already, or 'present' is used and regex matches + # or 'replace' is used and the exact line is present, then there is # nothing to do exit 0 fi @@ -61,8 +65,8 @@ fi add=0 remove=0 case "$state_should" in - present) - if [ "$state_is" = "wrongposition" ]; then + present|replace) + if [ "$state_is" = "wrongposition" ] || [ "$state_is" = "matching" ]; then echo updated >> "$__messages_out" remove=1 else diff --git a/cdist/conf/type/__line/man.rst b/cdist/conf/type/__line/man.rst index f76cab64..70490f68 100644 --- a/cdist/conf/type/__line/man.rst +++ b/cdist/conf/type/__line/man.rst @@ -31,7 +31,7 @@ file line Specifies the line which should be absent or present. - Must be present, if state is 'present'. + Must be present, if state is 'present' or 'replace'. Ignored if regex is given and state is 'absent'. regex @@ -41,10 +41,13 @@ regex If state is 'absent', ensure all lines matching the regular expression are absent. + If state is 'replace', ensure all lines matching the regular expression + are exactly 'line'. + The regular expression is interpreted by awk's match function. state - 'present' or 'absent', defaults to 'present' + 'present', 'absent' or 'replace', defaults to 'present'. onchange The code to run if line is added, removed or updated. @@ -99,6 +102,12 @@ EXAMPLES --line '-session required pam_exec.so debug log=/tmp/classify.log /usr/local/libexec/classify' \ --after '^session[[:space:]]+include[[:space:]]+password-auth-ac$' + # Uncomment as needed and set a value in a configuration file. + __line /etc/example.conf \ + --line 'SomeSetting SomeValue' \ + --regex '^(#[[:space:]]*)?SomeSetting[[:space:]]' \ + --state replace + SEE ALSO -------- From 4df5c91912edf9f31a6716d7cbe0adaedbc2b0e3 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Fri, 9 Oct 2020 06:52:52 +0200 Subject: [PATCH 088/411] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index 34c97d67..6d237449 100644 --- a/docs/changelog +++ b/docs/changelog @@ -6,6 +6,8 @@ next: * Type __package_pip: Detect pip binary (Ander Punnar) * Documentation: Add custom remote copy/exec examples (Darko Poljak) * Type __package_pkgng_freebsd: Bootstrap pkg if necessary (Evil Ham) + * Type __service: Fix calling __systemd_service (Mark Verboom) + * Type __line: Add 'replace' state (Evil Ham) 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) From 8ecae42199f27693eec771513174ce8143c8ca83 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 14 Oct 2020 02:00:11 +0300 Subject: [PATCH 089/411] remove bin/cdist script --- bin/cdist | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100755 bin/cdist diff --git a/bin/cdist b/bin/cdist deleted file mode 100755 index 645020a1..00000000 --- a/bin/cdist +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -# -*- coding: utf-8 -*- -# -# 2012 Nico Schottelius (nico-cdist at schottelius.org) -# -# 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 . -# -# - -# Wrapper for real script to allow execution from checkout -dir=${0%/*} - -# Ensure version is present - the bundled/shipped version contains a static version, -# the git version contains a dynamic version -"$dir/build-helper" version - -libdir=$(cd "${dir}/../" && pwd -P) -export PYTHONPATH="${libdir}" - -"$dir/../scripts/cdist" "$@" From 45d51c0e1553ce12fcea09b1b9e0d2fb9c0304c5 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 14 Oct 2020 02:00:44 +0300 Subject: [PATCH 090/411] rename build-helper -> cdist-build-helper --- bin/{build-helper => cdist-build-helper} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bin/{build-helper => cdist-build-helper} (100%) diff --git a/bin/build-helper b/bin/cdist-build-helper similarity index 100% rename from bin/build-helper rename to bin/cdist-build-helper From 3f1939716f4c4c2cdf538a22170a67fe181c675c Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 14 Oct 2020 02:02:45 +0300 Subject: [PATCH 091/411] enable running scripts/cdist directly and symlinked --- scripts/cdist | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/cdist b/scripts/cdist index b1d782ab..2ce40ae0 100755 --- a/scripts/cdist +++ b/scripts/cdist @@ -22,7 +22,15 @@ # import logging +import os import sys + +cdist_bin = os.path.abspath(__file__) +if os.path.islink(cdist_bin): + cdist_bin = os.readlink(cdist_bin) +cdist_dir = os.path.abspath(os.path.join(os.path.dirname(cdist_bin), os.pardir)) +sys.path.insert(0, cdist_dir) + import cdist import cdist.argparse import cdist.banner From fdc1ab93e968575b1d1f6f3b2a6cefa6ed6bb850 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 14 Oct 2020 02:03:11 +0300 Subject: [PATCH 092/411] move scripts/* to bin/ --- {scripts => bin}/cdist | 0 {scripts => bin}/cdist-dump | 0 {scripts => bin}/cdist-new-type | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {scripts => bin}/cdist (100%) rename {scripts => bin}/cdist-dump (100%) rename {scripts => bin}/cdist-new-type (100%) diff --git a/scripts/cdist b/bin/cdist similarity index 100% rename from scripts/cdist rename to bin/cdist diff --git a/scripts/cdist-dump b/bin/cdist-dump similarity index 100% rename from scripts/cdist-dump rename to bin/cdist-dump diff --git a/scripts/cdist-new-type b/bin/cdist-new-type similarity index 100% rename from scripts/cdist-new-type rename to bin/cdist-new-type From 86057cef19b10859cd66ceb4e3ebade5986aff89 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Wed, 14 Oct 2020 02:05:17 +0300 Subject: [PATCH 093/411] don't die if there is no version.py --- cdist/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cdist/__init__.py b/cdist/__init__.py index be573170..26e7d071 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -24,10 +24,13 @@ import os import hashlib import cdist.log -import cdist.version -VERSION = cdist.version.VERSION +try: + import cdist.version + VERSION = cdist.version.VERSION +except ModuleNotFoundError: + VERSION = 'from git' BANNER = """ .. . .x+=:. s From fd04c036139f150be79801e5fd3b49086e5d7263 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 13:42:16 +0300 Subject: [PATCH 094/411] add parent dir to module search path only when importing fails --- bin/cdist | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bin/cdist b/bin/cdist index 2ce40ae0..66ccbb5a 100755 --- a/bin/cdist +++ b/bin/cdist @@ -25,13 +25,19 @@ import logging import os import sys -cdist_bin = os.path.abspath(__file__) -if os.path.islink(cdist_bin): - cdist_bin = os.readlink(cdist_bin) -cdist_dir = os.path.abspath(os.path.join(os.path.dirname(cdist_bin), os.pardir)) -sys.path.insert(0, cdist_dir) +# try to import cdist and if that fails, then add this file's parent dir to +# module search path and try again. additionally check if this file is +# symlinked, so user can symlink this file to, for example, ~/.local/bin. +try: + import cdist +except ModuleNotFoundError: + cdist_bin = os.path.abspath(__file__) + if os.path.islink(cdist_bin): + cdist_bin = os.readlink(cdist_bin) + cdist_dir = os.path.abspath(os.path.join(os.path.dirname(cdist_bin), os.pardir)) + sys.path.insert(0, cdist_dir) + import cdist -import cdist import cdist.argparse import cdist.banner import cdist.config From 1614b62f702a82731b3b9c636894268b4310821b Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 13:48:28 +0300 Subject: [PATCH 095/411] fallback VERSION to "unknown version" --- cdist/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/__init__.py b/cdist/__init__.py index 26e7d071..350a2765 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -30,7 +30,7 @@ try: import cdist.version VERSION = cdist.version.VERSION except ModuleNotFoundError: - VERSION = 'from git' + VERSION = 'unknown version' BANNER = """ .. . .x+=:. s From 174aa7728065da611dc8887d9f33ead7e27c473a Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 14:11:00 +0300 Subject: [PATCH 096/411] __file__ already is absolute --- bin/cdist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cdist b/bin/cdist index 66ccbb5a..d7eae312 100755 --- a/bin/cdist +++ b/bin/cdist @@ -31,7 +31,7 @@ import sys try: import cdist except ModuleNotFoundError: - cdist_bin = os.path.abspath(__file__) + cdist_bin = __file__ if os.path.islink(cdist_bin): cdist_bin = os.readlink(cdist_bin) cdist_dir = os.path.abspath(os.path.join(os.path.dirname(cdist_bin), os.pardir)) From 65c8af4ba3751dddbfe07fd5077e5a99b5d240b8 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 14:11:12 +0300 Subject: [PATCH 097/411] overengineered version discovery --- cdist/__init__.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cdist/__init__.py b/cdist/__init__.py index 350a2765..f659506f 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -22,6 +22,7 @@ import os import hashlib +import subprocess import cdist.log @@ -30,7 +31,19 @@ try: import cdist.version VERSION = cdist.version.VERSION except ModuleNotFoundError: - VERSION = 'unknown version' + cdist_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) + if os.path.isdir(os.path.join(cdist_dir, '.git')): + run_git = subprocess.run( + ['git', 'describe', '--always'], + cwd=cdist_dir, + capture_output=True, + text=True) + if run_git.returncode == 0: + VERSION = str(run_git.stdout) + else: + VERSION = 'from git' + else: + VERSION = 'unknown version' BANNER = """ .. . .x+=:. s From 42d5d6c3e29f6500c3f6321b01c3b268e6886ec6 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 14:12:39 +0300 Subject: [PATCH 098/411] redundant str() --- cdist/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/__init__.py b/cdist/__init__.py index f659506f..c16562e7 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -39,7 +39,7 @@ except ModuleNotFoundError: capture_output=True, text=True) if run_git.returncode == 0: - VERSION = str(run_git.stdout) + VERSION = run_git.stdout else: VERSION = 'from git' else: From b41d80075a616a1c7ac3a361079c748424409995 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 14:16:04 +0300 Subject: [PATCH 099/411] update paths in setup.py --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 7b000041..002be19c 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ import subprocess # We have it only if it is a git cloned repo. -build_helper = os.path.join('bin', 'build-helper') +build_helper = os.path.join('bin', 'cdist-build-helper') # Version file path. version_file = os.path.join('cdist', 'version.py') # If we have build-helper we could be a git repo. @@ -56,7 +56,7 @@ setup( name="cdist", packages=["cdist", "cdist.core", "cdist.exec", "cdist.util", ], package_data={'cdist': package_data}, - scripts=["scripts/cdist", "scripts/cdist-dump", "scripts/cdist-new-type"], + scripts=["bin/cdist", "bin/cdist-dump", "bin/cdist-new-type"], version=cdist.version.VERSION, description="A Usable Configuration Management System", author="Nico Schottelius", From e55db1b427fcc7f750adfcb3646a3eeb446113de Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 15:41:38 +0300 Subject: [PATCH 100/411] use check_output for git describe execution and define fallback VERSION earlier --- cdist/__init__.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/cdist/__init__.py b/cdist/__init__.py index c16562e7..1c60ae0f 100644 --- a/cdist/__init__.py +++ b/cdist/__init__.py @@ -27,23 +27,21 @@ import subprocess import cdist.log +VERSION = 'unknown version' + try: import cdist.version VERSION = cdist.version.VERSION except ModuleNotFoundError: cdist_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) if os.path.isdir(os.path.join(cdist_dir, '.git')): - run_git = subprocess.run( - ['git', 'describe', '--always'], - cwd=cdist_dir, - capture_output=True, - text=True) - if run_git.returncode == 0: - VERSION = run_git.stdout - else: - VERSION = 'from git' - else: - VERSION = 'unknown version' + try: + VERSION = subprocess.check_output( + ['git', 'describe', '--always'], + cwd=cdist_dir, + universal_newlines=True) + except: + pass BANNER = """ .. . .x+=:. s From 54d83a62118ed3f0c6328c4b25a3b9ee56adf27a Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Fri, 16 Oct 2020 15:50:50 +0300 Subject: [PATCH 101/411] there is no single author anymore, also remove www. --- setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 002be19c..858c2c17 100644 --- a/setup.py +++ b/setup.py @@ -59,9 +59,8 @@ setup( scripts=["bin/cdist", "bin/cdist-dump", "bin/cdist-new-type"], version=cdist.version.VERSION, description="A Usable Configuration Management System", - author="Nico Schottelius", - author_email="nico-cdist-pypi@schottelius.org", - url="https://www.cdi.st/", + author="cdist contributors", + url="https://cdi.st", classifiers=[ "Development Status :: 6 - Mature", "Environment :: Console", From 507fa6fa93210959b52bb639a9394c8ac52b40e5 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 17 Oct 2020 17:05:09 +0200 Subject: [PATCH 102/411] __download: fix non-existent parameter of __unpack Probably happened due to renaming .. guess it's correct now. --- cdist/conf/type/__download/man.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index eb3ac971..d8814683 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -69,7 +69,7 @@ EXAMPLES require='__download/opt/cpma/cnq3.zip' \ __unpack /opt/cpma/cnq3.zip \ - --move-existing-destination \ + --backup-destination \ --destination /opt/cpma/server From d20fb743243f0341820a5b41a5725fb705eb5aae Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sat, 17 Oct 2020 23:16:42 +0300 Subject: [PATCH 103/411] use os.path.realpath instead, because it eliminates any symbolic links encountered in the path --- bin/cdist | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bin/cdist b/bin/cdist index d7eae312..1f92f157 100755 --- a/bin/cdist +++ b/bin/cdist @@ -25,16 +25,16 @@ import logging import os import sys -# try to import cdist and if that fails, then add this file's parent dir to -# module search path and try again. additionally check if this file is -# symlinked, so user can symlink this file to, for example, ~/.local/bin. +# try to import cdist and if that fails, +# then add this file's parent dir to +# module search path and try again. try: import cdist except ModuleNotFoundError: - cdist_bin = __file__ - if os.path.islink(cdist_bin): - cdist_bin = os.readlink(cdist_bin) - cdist_dir = os.path.abspath(os.path.join(os.path.dirname(cdist_bin), os.pardir)) + cdist_dir = os.path.realpath( + os.path.join( + os.path.dirname(os.path.realpath(__file__)), + os.pardir)) sys.path.insert(0, cdist_dir) import cdist From b2e6afb57e6799b934a2eaa387cea337d65d8aac Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Sat, 17 Oct 2020 23:01:36 +0200 Subject: [PATCH 104/411] __download: adapt download+unpack example in manpage --- cdist/conf/type/__download/man.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/cdist/conf/type/__download/man.rst b/cdist/conf/type/__download/man.rst index d8814683..54503470 100644 --- a/cdist/conf/type/__download/man.rst +++ b/cdist/conf/type/__download/man.rst @@ -70,6 +70,7 @@ EXAMPLES require='__download/opt/cpma/cnq3.zip' \ __unpack /opt/cpma/cnq3.zip \ --backup-destination \ + --preserve-archive \ --destination /opt/cpma/server From 955b84727611caa5aa05e4521af326c94c649e89 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Sun, 18 Oct 2020 15:55:14 +0200 Subject: [PATCH 105/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index 6d237449..8ad2c624 100644 --- a/docs/changelog +++ b/docs/changelog @@ -8,6 +8,7 @@ next: * Type __package_pkgng_freebsd: Bootstrap pkg if necessary (Evil Ham) * Type __service: Fix calling __systemd_service (Mark Verboom) * Type __line: Add 'replace' state (Evil Ham) + * Type __download: Fix man page (Matthias Stecher) 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) From 6964070282a6c5d09a458017623012fc17e3008d Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Sun, 18 Oct 2020 17:13:22 +0300 Subject: [PATCH 106/411] s/build-helper/cdist-build-helper/ --- .gitlab-ci.yml | 8 ++++---- README-maintainers | 2 +- bin/cdist-build-helper | 2 +- docs/src/cdist-install.rst | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e215652c..e48355ea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,15 +6,15 @@ image: code.ungleich.ch:5050/ungleich-public/cdist/cdist-ci:latest unit_tests: stage: test script: - - ./bin/build-helper version - - ./bin/build-helper test + - ./bin/cdist-build-helper version + - ./bin/cdist-build-helper test pycodestyle: stage: test script: - - ./bin/build-helper pycodestyle + - ./bin/cdist-build-helper pycodestyle shellcheck: stage: test script: - - ./bin/build-helper shellcheck + - ./bin/cdist-build-helper shellcheck diff --git a/README-maintainers b/README-maintainers index af57f475..5766dd7d 100644 --- a/README-maintainers +++ b/README-maintainers @@ -1,4 +1,4 @@ -Maintainers should use ./bin/build-helper script. +Maintainers should use ./bin/cdist-build-helper script. Makefile is intended for end users. It can be used for non-maintaining targets that can be run from pure source (without git repository). diff --git a/bin/cdist-build-helper b/bin/cdist-build-helper index d4d603ed..bdef0dbb 100755 --- a/bin/cdist-build-helper +++ b/bin/cdist-build-helper @@ -495,7 +495,7 @@ eof ;; shellcheck-build-helper) - ${SHELLCHECKCMD} ./bin/build-helper + ${SHELLCHECKCMD} ./bin/cdist-build-helper ;; check-shellcheck) diff --git a/docs/src/cdist-install.rst b/docs/src/cdist-install.rst index 6f4f14d7..18863145 100644 --- a/docs/src/cdist-install.rst +++ b/docs/src/cdist-install.rst @@ -49,7 +49,7 @@ create version.py: .. code-block:: sh - ./bin/build-helper version + ./bin/cdist-build-helper version Then you install it with: @@ -70,7 +70,7 @@ Or directly with distutils: python setup.py install -Note that `bin/build-helper` script is intended for cdist maintainers. +Note that `bin/cdist-build-helper` script is intended for cdist maintainers. Available versions in git From e3d906a85fe5e0c9f254d3620e8568437c93d97c Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Tue, 15 Sep 2020 00:55:26 +0300 Subject: [PATCH 107/411] [__acl] remove deprecated parameters, fix some bugs and improve manual --- cdist/conf/type/__acl/explorer/checks | 39 ------------------- cdist/conf/type/__acl/explorer/getent | 4 ++ cdist/conf/type/__acl/gencode-remote | 36 ++++++++--------- cdist/conf/type/__acl/man.rst | 12 +++--- .../conf/type/__acl/parameter/deprecated/acl | 1 - .../type/__acl/parameter/deprecated/group | 1 - .../conf/type/__acl/parameter/deprecated/mask | 1 - .../type/__acl/parameter/deprecated/other | 1 - .../conf/type/__acl/parameter/deprecated/user | 1 - cdist/conf/type/__acl/parameter/optional | 2 - .../type/__acl/parameter/optional_multiple | 3 -- 11 files changed, 26 insertions(+), 75 deletions(-) delete mode 100755 cdist/conf/type/__acl/explorer/checks create mode 100755 cdist/conf/type/__acl/explorer/getent delete mode 100644 cdist/conf/type/__acl/parameter/deprecated/acl delete mode 100644 cdist/conf/type/__acl/parameter/deprecated/group delete mode 100644 cdist/conf/type/__acl/parameter/deprecated/mask delete mode 100644 cdist/conf/type/__acl/parameter/deprecated/other delete mode 100644 cdist/conf/type/__acl/parameter/deprecated/user diff --git a/cdist/conf/type/__acl/explorer/checks b/cdist/conf/type/__acl/explorer/checks deleted file mode 100755 index 70bb0412..00000000 --- a/cdist/conf/type/__acl/explorer/checks +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -e -# -# 2019 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 . -# - -# TODO check if filesystem has ACL turned on etc - -if [ -f "$__object/parameter/acl" ] -then - grep -E '^(default:)?(user|group):' "$__object/parameter/acl" \ - | while read -r acl - do - param="$( echo "$acl" | awk -F: '{print $(NF-2)}' )" - check="$( echo "$acl" | awk -F: '{print $(NF-1)}' )" - - [ "$param" = 'user' ] && db=passwd || db="$param" - - if ! getent "$db" "$check" > /dev/null - then - echo "missing $param '$check'" >&2 - exit 1 - fi - done -fi diff --git a/cdist/conf/type/__acl/explorer/getent b/cdist/conf/type/__acl/explorer/getent new file mode 100755 index 00000000..7e6c2c30 --- /dev/null +++ b/cdist/conf/type/__acl/explorer/getent @@ -0,0 +1,4 @@ +#!/bin/sh -e + +getent passwd | awk -F: '{print "user:"$1}' +getent group | awk -F: '{print "group:"$1}' diff --git a/cdist/conf/type/__acl/gencode-remote b/cdist/conf/type/__acl/gencode-remote index e5404a9d..32318e91 100755 --- a/cdist/conf/type/__acl/gencode-remote +++ b/cdist/conf/type/__acl/gencode-remote @@ -22,8 +22,8 @@ file_is="$( cat "$__object/explorer/file_is" )" if [ "$file_is" = 'missing' ] \ && [ -z "$__cdist_dry_run" ] \ - && \( [ ! -f "$__object/parameter/file" ] \ - || [ ! -f "$__object/parameter/directory" ] \) + && [ ! -f "$__object/parameter/file" ] \ + && [ ! -f "$__object/parameter/directory" ] then exit 0 fi @@ -47,28 +47,26 @@ then 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 - [ -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 echo 'no parameters set' >&2 exit 1 fi +# instead of setfacl's non-helpful message "Option -m: Invalid argument near character X" +# let's check if target has necessary users and groups, since mistyped or missing +# users/groups in target is most common reason. +echo "$acl_should" \ + | grep -Po '(user|group):[^:]+' \ + | sort -u \ + | while read -r l + do + if ! grep "$l" -Fxq "$__object/explorer/getent" + then + echo "no $l' in target" | sed "s/:/ '/" >&2 + exit 1 + fi + done + if [ -f "$__object/parameter/default" ] then acl_should="$( echo "$acl_should" \ diff --git a/cdist/conf/type/__acl/man.rst b/cdist/conf/type/__acl/man.rst index 28412871..307be72b 100644 --- a/cdist/conf/type/__acl/man.rst +++ b/cdist/conf/type/__acl/man.rst @@ -12,11 +12,14 @@ Fully supported and tested on Linux (ext4 filesystem), partial support for FreeB See ``setfacl`` and ``acl`` manpages for more details. +One of ``--entry`` or ``--source`` must be used. -REQUIRED MULTIPLE PARAMETERS + +OPTIONAL MULTIPLE PARAMETERS ---------------------------- entry Set ACL entry following ``getfacl`` output syntax. + Must be used if ``--source`` is not used. OPTIONAL PARAMETERS @@ -25,6 +28,7 @@ source Read ACL entries from stdin or file. Ordering of entries is not important. When reading from file, comments and empty lines are ignored. + Must be used if ``--entry`` is not used. file Create/change file with ``__file`` using ``user:group:mode`` pattern. @@ -48,12 +52,6 @@ remove ``mask`` and ``other`` entries can't be removed, but only changed. -DEPRECATED PARAMETERS ---------------------- -Parameters ``acl``, ``user``, ``group``, ``mask`` and ``other`` are deprecated and they -will be removed in future versions. Please use ``entry`` parameter instead. - - EXAMPLES -------- diff --git a/cdist/conf/type/__acl/parameter/deprecated/acl b/cdist/conf/type/__acl/parameter/deprecated/acl deleted file mode 100644 index 94e14159..00000000 --- a/cdist/conf/type/__acl/parameter/deprecated/acl +++ /dev/null @@ -1 +0,0 @@ -see manual for details diff --git a/cdist/conf/type/__acl/parameter/deprecated/group b/cdist/conf/type/__acl/parameter/deprecated/group deleted file mode 100644 index 94e14159..00000000 --- a/cdist/conf/type/__acl/parameter/deprecated/group +++ /dev/null @@ -1 +0,0 @@ -see manual for details diff --git a/cdist/conf/type/__acl/parameter/deprecated/mask b/cdist/conf/type/__acl/parameter/deprecated/mask deleted file mode 100644 index 94e14159..00000000 --- a/cdist/conf/type/__acl/parameter/deprecated/mask +++ /dev/null @@ -1 +0,0 @@ -see manual for details diff --git a/cdist/conf/type/__acl/parameter/deprecated/other b/cdist/conf/type/__acl/parameter/deprecated/other deleted file mode 100644 index 94e14159..00000000 --- a/cdist/conf/type/__acl/parameter/deprecated/other +++ /dev/null @@ -1 +0,0 @@ -see manual for details diff --git a/cdist/conf/type/__acl/parameter/deprecated/user b/cdist/conf/type/__acl/parameter/deprecated/user deleted file mode 100644 index 94e14159..00000000 --- a/cdist/conf/type/__acl/parameter/deprecated/user +++ /dev/null @@ -1 +0,0 @@ -see manual for details diff --git a/cdist/conf/type/__acl/parameter/optional b/cdist/conf/type/__acl/parameter/optional index cdcbc0b8..5a0c29a3 100644 --- a/cdist/conf/type/__acl/parameter/optional +++ b/cdist/conf/type/__acl/parameter/optional @@ -1,5 +1,3 @@ -mask -other source file directory diff --git a/cdist/conf/type/__acl/parameter/optional_multiple b/cdist/conf/type/__acl/parameter/optional_multiple index c615d507..4c884f03 100644 --- a/cdist/conf/type/__acl/parameter/optional_multiple +++ b/cdist/conf/type/__acl/parameter/optional_multiple @@ -1,4 +1 @@ entry -acl -user -group From 716cd37281903aafd7d65df539265a6722e809b1 Mon Sep 17 00:00:00 2001 From: Ander Punnar Date: Mon, 21 Sep 2020 11:18:39 +0300 Subject: [PATCH 108/411] [__update_alternatives] rewrite and support --install --- .../explorer/alternatives | 4 ++ .../type/__update_alternatives/explorer/link | 40 +++++++++++++++++++ .../__update_alternatives/explorer/path_is | 12 ++++++ .../explorer/path_should_state | 8 ++++ .../type/__update_alternatives/explorer/state | 8 ---- .../type/__update_alternatives/gencode-remote | 37 ++++++++++++++--- cdist/conf/type/__update_alternatives/man.rst | 13 ++++-- .../__update_alternatives/parameter/boolean | 1 + 8 files changed, 107 insertions(+), 16 deletions(-) create mode 100755 cdist/conf/type/__update_alternatives/explorer/alternatives create mode 100755 cdist/conf/type/__update_alternatives/explorer/link create mode 100755 cdist/conf/type/__update_alternatives/explorer/path_is create mode 100755 cdist/conf/type/__update_alternatives/explorer/path_should_state delete mode 100755 cdist/conf/type/__update_alternatives/explorer/state create mode 100644 cdist/conf/type/__update_alternatives/parameter/boolean diff --git a/cdist/conf/type/__update_alternatives/explorer/alternatives b/cdist/conf/type/__update_alternatives/explorer/alternatives new file mode 100755 index 00000000..34aaca56 --- /dev/null +++ b/cdist/conf/type/__update_alternatives/explorer/alternatives @@ -0,0 +1,4 @@ +#!/bin/sh -e + +update-alternatives --display "$__object_id" 2>/dev/null \ + | awk -F ' - ' '/priority [0-9]+$/ { print $1 }' diff --git a/cdist/conf/type/__update_alternatives/explorer/link b/cdist/conf/type/__update_alternatives/explorer/link new file mode 100755 index 00000000..6519e7c2 --- /dev/null +++ b/cdist/conf/type/__update_alternatives/explorer/link @@ -0,0 +1,40 @@ +#!/bin/sh -e + +# fedora's (update-)alternatives --display output doesn't have +# "link is " line, but debian does. so, let's find +# out how they store this information. +# +# debian and friends: +# https://salsa.debian.org/dpkg-team/dpkg/-/blob/master/utils/update-alternatives.c +# see calls to altdb_print_line function +# +# fedora and friends: +# https://github.com/fedora-sysv/chkconfig/blob/master/alternatives.c +# see calls to parseLine function +# +# conclusion: it is safe to assume that (master) link is on second line + +for altdir in \ + /var/lib/dpkg/alternatives \ + /var/lib/alternatives +do + if [ ! -f "$altdir/$__object_id" ] + then + continue + fi + + link="$( awk 'NR==2' "$altdir/$__object_id" )" + + if [ -n "$link" ] + then + break + fi +done + +if [ -z "$link" ] +then + echo "unable to get link for $__object_id" >&2 + exit 1 +fi + +echo "$link" diff --git a/cdist/conf/type/__update_alternatives/explorer/path_is b/cdist/conf/type/__update_alternatives/explorer/path_is new file mode 100755 index 00000000..fc304d5d --- /dev/null +++ b/cdist/conf/type/__update_alternatives/explorer/path_is @@ -0,0 +1,12 @@ +#!/bin/sh -e + +path_is="$( update-alternatives --display "$__object_id" 2>/dev/null \ + | awk '/link currently points to/ {print $5}' )" + +if [ -z "$path_is" ] +then + echo "unable to get current path for $__object_id" >&2 + exit 1 +fi + +echo "$path_is" diff --git a/cdist/conf/type/__update_alternatives/explorer/path_should_state b/cdist/conf/type/__update_alternatives/explorer/path_should_state new file mode 100755 index 00000000..59e015c5 --- /dev/null +++ b/cdist/conf/type/__update_alternatives/explorer/path_should_state @@ -0,0 +1,8 @@ +#!/bin/sh -e + +if [ -f "$( cat "$__object/parameter/path" )" ] +then + echo 'present' +else + echo 'absent' +fi diff --git a/cdist/conf/type/__update_alternatives/explorer/state b/cdist/conf/type/__update_alternatives/explorer/state deleted file mode 100755 index 04a78aaa..00000000 --- a/cdist/conf/type/__update_alternatives/explorer/state +++ /dev/null @@ -1,8 +0,0 @@ -#!/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 c0b49814..e393cdef 100755 --- a/cdist/conf/type/__update_alternatives/gencode-remote +++ b/cdist/conf/type/__update_alternatives/gencode-remote @@ -1,6 +1,7 @@ #!/bin/sh -e # # 2013 Nico Schottelius (nico-cdist at schottelius.org) +# 2020 Ander Punnar (ander@kvlt.ee) # # This file is part of cdist. # @@ -16,12 +17,38 @@ # # You should have received a copy of the GNU General Public License # along with cdist. If not, see . -# -if [ "$(cat "$__object/explorer/state")" = 'present' ] -then exit 0 +path_is="$( cat "$__object/explorer/path_is" )" + +path_should="$( cat "$__object/parameter/path" )" + +if [ "$path_is" = "$path_should" ] +then + exit 0 +fi + +if [ "$( cat "$__object/explorer/path_should_state" )" = 'absent' ] && [ -z "$__cdist_dry_run" ] +then + echo "$path_should does not exist in target" >&2 + exit 1 fi -path="$(cat "$__object/parameter/path")" name="$__object_id" -echo "update-alternatives --quiet --set '$name' '$path'" + +alternatives="$( cat "$__object/explorer/alternatives" )" + +if ! echo "$alternatives" | grep -Fxq "$path_should" +then + if [ ! -f "$__object/parameter/install" ] + then + echo "$path_should is not in $name alternatives." >&2 + echo 'Please install missing packages or use --install to add path to alternatives.' >&2 + exit 1 + fi + + link="$( cat "$__object/explorer/link" )" + + echo "update-alternatives --install '$link' '$name' '$path_should' 1000" +fi + +echo "update-alternatives --set '$name' '$path_should'" diff --git a/cdist/conf/type/__update_alternatives/man.rst b/cdist/conf/type/__update_alternatives/man.rst index 73d82d11..0dc973f2 100644 --- a/cdist/conf/type/__update_alternatives/man.rst +++ b/cdist/conf/type/__update_alternatives/man.rst @@ -19,6 +19,12 @@ path Use this path for the given alternative +BOOLEAN PARAMETERS +------------------ +install + Add (``update-alternatives --install``) missing path to alternatives. + + EXAMPLES -------- @@ -36,11 +42,12 @@ SEE ALSO AUTHORS ------- Nico Schottelius +Ander Punnar COPYING ------- -Copyright \(C) 2013 Nico Schottelius. 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) 2013 Nico Schottelius and 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/__update_alternatives/parameter/boolean b/cdist/conf/type/__update_alternatives/parameter/boolean new file mode 100644 index 00000000..7c32f559 --- /dev/null +++ b/cdist/conf/type/__update_alternatives/parameter/boolean @@ -0,0 +1 @@ +install From 687c1d2dd9bed4130a65885d19ce31c87c9d79de Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Mon, 19 Oct 2020 06:57:00 +0200 Subject: [PATCH 109/411] ++changelog --- docs/changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog b/docs/changelog index 8ad2c624..a0f1ead2 100644 --- a/docs/changelog +++ b/docs/changelog @@ -9,6 +9,8 @@ next: * Type __service: Fix calling __systemd_service (Mark Verboom) * Type __line: Add 'replace' state (Evil Ham) * Type __download: Fix man page (Matthias Stecher) + * Type __acl: Remove deprecated parameters, fix bugs (Ander Punnar) + * Type __update_alternatives: Rewrite, support --install (Ander Punnar) 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) From e8aede1e912f24ec7fde1d087dcd06f249d7701a Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Mon, 19 Oct 2020 18:00:05 +0200 Subject: [PATCH 110/411] __lxc_container: do not call rm recusivly for a file --- cdist/conf/type/__lxc_container/gencode-remote | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index f9e4dceb..42e1e43e 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -168,7 +168,7 @@ LXC # remove empty tempfile if it was created if [ -f "$__object/parameter/no-default-config" ]; then cat <> "$__messages_out" From 4e06ea78166c181cad37a6f9e3b8880719d6d386 Mon Sep 17 00:00:00 2001 From: Matthias Stecher Date: Tue, 20 Oct 2020 17:03:14 +0200 Subject: [PATCH 111/411] __lxc_container: no grep ERE used, switching to BRE When checking for lxc configuration that should be removed, it says to grep to use extended regular expressions (ERE). But there are no characters not covered by basic regular expressions (BRE). So switching to to BRE, as it may not match user input as regex. --- cdist/conf/type/__lxc_container/gencode-remote | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__lxc_container/gencode-remote b/cdist/conf/type/__lxc_container/gencode-remote index 42e1e43e..6bef504e 100755 --- a/cdist/conf/type/__lxc_container/gencode-remote +++ b/cdist/conf/type/__lxc_container/gencode-remote @@ -207,10 +207,10 @@ DONE # check if smth. to be deleted # must be before adding, because it takes the content of the original file # because 'cat $file > $file' will not work (> opens before command reads it) - # will create extended regex pattern for grep with malformed spaces + # will create a basic regex pattern for grep to ignore malformed spaces if [ -s "$__object/files/config.del" ]; then cat < "\$tmpconfig" +grep -v -f - <<'ABSENT' "$container_config" > "\$tmpconfig" $(awk -v FS=' = ' -v OFS=' = ' -v blank='[[:blank:]]*' ' function ntostring(n) { ret=""; for(i=n; i<=NF; i++) ret=ret $i (i Date: Wed, 28 Oct 2020 18:18:24 +0100 Subject: [PATCH 112/411] [type/__file] Fix --state pre-exists --- cdist/conf/type/__file/gencode-remote | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cdist/conf/type/__file/gencode-remote b/cdist/conf/type/__file/gencode-remote index 35356b13..2675b03a 100755 --- a/cdist/conf/type/__file/gencode-remote +++ b/cdist/conf/type/__file/gencode-remote @@ -87,11 +87,6 @@ case "$state_should" in fi ;; - pre-exists) - # pre-exists should never reach gencode-remote… - exit 1 - ;; - absent) if [ "$type" = "file" ]; then echo "rm -f '$destination'" From 9277e0ba19c346189658712acf17a772967dfa32 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 29 Oct 2020 09:30:58 +0100 Subject: [PATCH 113/411] ++changelog --- docs/changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog b/docs/changelog index a0f1ead2..5977d80e 100644 --- a/docs/changelog +++ b/docs/changelog @@ -11,6 +11,7 @@ next: * Type __download: Fix man page (Matthias Stecher) * Type __acl: Remove deprecated parameters, fix bugs (Ander Punnar) * Type __update_alternatives: Rewrite, support --install (Ander Punnar) + * Type __file: Fix state pre-exists (Dennis Camera) 6.8.0: 2020-09-11 * Type __locale_system: Fix for debian and ubuntu (Ander Punnar) From 82a9aa79020ff2369b1f4d530a3a6d5ca41915f8 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 29 Oct 2020 10:39:42 +0100 Subject: [PATCH 114/411] [type/__apt_norecommends] Use 00InstallRecommends file as debian-installer does debian-installer can be preseeded with `base-installer/install-recommends` to disable installation of recommended packages already during OS installation. d-i will then create the file `/etc/apt/apt.conf.d/00InstallRecommends` (cf. https://salsa.debian.org/installer-team/base-installer/-/blob/master/library.sh). __apt_norecommends should use the same file to avoid having two config files effectively doing the same thing. --- cdist/conf/type/__apt_norecommends/man.rst | 9 +++-- cdist/conf/type/__apt_norecommends/manifest | 41 +++++++++++---------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/cdist/conf/type/__apt_norecommends/man.rst b/cdist/conf/type/__apt_norecommends/man.rst index 001fffe4..9297b518 100644 --- a/cdist/conf/type/__apt_norecommends/man.rst +++ b/cdist/conf/type/__apt_norecommends/man.rst @@ -32,11 +32,12 @@ EXAMPLES AUTHORS ------- Steven Armstrong +Dennis Camera COPYING ------- -Copyright \(C) 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 -License, or (at your option) any later version. +Copyright \(C) 2014 Steven Armstrong, 2020 Dennis Camera. +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_norecommends/manifest b/cdist/conf/type/__apt_norecommends/manifest index e737df89..fc187784 100755 --- a/cdist/conf/type/__apt_norecommends/manifest +++ b/cdist/conf/type/__apt_norecommends/manifest @@ -1,6 +1,7 @@ #!/bin/sh -e # # 2014 Steven Armstrong (steven-cdist at armstrong.cc) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -19,26 +20,28 @@ # -os=$(cat "$__global/explorer/os") +os=$(cat "${__global:?}/explorer/os") -case "$os" in - ubuntu|debian|devuan) - # No stinking recommends thank you very much. - # If I want something installed I will do so myself. - __file /etc/apt/apt.conf.d/99-no-recommends \ - --owner root --group root --mode 644 \ - --source - << DONE -APT::Install-Recommends "0"; -APT::Install-Suggests "0"; -APT::AutoRemove::RecommendsImportant "0"; -APT::AutoRemove::SuggestsImportant "0"; -DONE - ;; - *) - cat >&2 << DONE +case ${os} +in + (ubuntu|debian|devuan) + __file /etc/apt/apt.conf.d/00InstallRecommends --state present \ + --owner root --group root --mode 0644 --source - <<-'EOF' + APT::Install-Recommends "false"; + APT::Install-Suggests "false"; + APT::AutoRemove::RecommendsImportant "false"; + APT::AutoRemove::SuggestsImportant "false"; + EOF + + # TODO: Remove the following object after some time + require=__file/etc/apt/apt.conf.d/00InstallRecommends \ + __file /etc/apt/apt.conf.d/99-no-recommends --state absent + ;; + (*) + cat >&2 < Date: Thu, 29 Oct 2020 18:03:27 +0100 Subject: [PATCH 115/411] [scanner] begin scanner implementation - non invasive --- cdist/scan.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 cdist/scan.py diff --git a/cdist/scan.py b/cdist/scan.py new file mode 100644 index 00000000..fa1bf5de --- /dev/null +++ b/cdist/scan.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# +# 2020 Nico Schottelius (nico-cdist at schottelius.org) +# +# 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 . +# +# + +from scapy.all import * +from scapy.data import ETHER_TYPES + + +class Scanner(object): + def recv_msg_cpu(self, pkg): +# print(pkg.__repr__()) + if ICMPv6EchoReply in pkg: + host = pkg['IPv6'].src + print(f"Host {host} is alive") + + + def scan(self): + sniff(iface="wlan0", + filter="icmp6", + prn=self.recv_msg_cpu) + + +if __name__ == '__main__': + s = Scanner() + s.scan() From 87b46a622411362f441b62199972e71d85d7d2d6 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Thu, 29 Oct 2020 18:49:20 +0100 Subject: [PATCH 116/411] [scanner] finish prototype ping @poljakowski - it's your turn now --- cdist/scan.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 7 deletions(-) diff --git a/cdist/scan.py b/cdist/scan.py index fa1bf5de..e2100499 100644 --- a/cdist/scan.py +++ b/cdist/scan.py @@ -19,24 +19,148 @@ # # -from scapy.all import * -from scapy.data import ETHER_TYPES +# +# Interface to be implemented: +# - cdist scan --mode {scan, trigger, install, config}, --mode can be repeated +# scan: scan / listen for icmp6 replies +# trigger: send trigger to multicast +# config: configure newly detected hosts +# install: install newly detected hosts +# +# Scanner logic +# - save results to configdir: +# basedir = ~/.cdist/scan/ +# last_seen = ~/.cdist/scan//last_seen -- record unix time or similar +# last_configured = ~/.cdist/scan//last_configured -- record unix time or similar +# last_installed = ~/.cdist/scan//last_configured -- record unix time or similar +# +# +# +# +# cdist scan --list +# Show all known hosts including last seen flag +# +# Logic for reconfiguration: +# +# - record when configured last time +# - introduce a parameter --reconfigure-after that takes time argument +# - reconfigure if a) host alive and b) reconfigure-after time passed +# +from multiprocessing import Process +import os + +# FIXME: fail gracefully if non existent - i.e. "scapy required for scanner - please install python3-scapy" +from scapy.all import * + +# Datetime overwrites scapy.all.datetime - needs to be imported AFTER +import datetime + +class Trigger(object): + """ + Trigger an ICMPv6EchoReply from all hosts that are alive + """ + + def __init__(self, interfaces=None, verbose=False): + self.interfaces = interfaces + self.verbose = verbose + + # Wait 5 seconds before triggering again - FIXME: add parameter + self.sleeptime = 5 + + def start(self): + self.processes = [] + for interface in self.interfaces: + p = Process(target=self.run_interface, args=(interface,)) + self.processes.append(p) + p.start() + + def join(self): + for process in self.processes: + process.join() + + def run_interface(self, interface): + while True: + self.trigger(interface) + time.sleep(self.sleeptime) + + def trigger(self, interface): + packet = IPv6(dst=f"ff02::1%{interface}") / ICMPv6EchoRequest() + send(packet, verbose=self.verbose) + class Scanner(object): - def recv_msg_cpu(self, pkg): -# print(pkg.__repr__()) + """ + Scan for replies of hosts, maintain the up-to-date database + """ + + def __init__(self, interfaces=None, outdir=None): + self.interfaces = interfaces + + if outdir: + self.outdir = outdir + else: + self.outdir = "." + + def handle_pkg(self, pkg): if ICMPv6EchoReply in pkg: host = pkg['IPv6'].src print(f"Host {host} is alive") + dir = os.path.join(self.outdir, host) + fname = os.path.join(dir, "last_seen") + + now = datetime.datetime.now() + + os.makedirs(dir, exist_ok=True) + + # FIXME: maybe adjust the format so we can easily parse again + with open(fname, "w") as fd: + fd.write(f"{now}\n") + def scan(self): - sniff(iface="wlan0", + sniff(iface=self.interfaces, filter="icmp6", - prn=self.recv_msg_cpu) + prn=self.handle_pkg) if __name__ == '__main__': - s = Scanner() + t = Trigger(interfaces=["wlan0"]) + t.start() + + # Scanner can listen on many interfaces at the same time + s = Scanner(interfaces=["wlan0"]) s.scan() + + # Join back the trigger processes + t.join() + + # Test in my lan shows: + # [18:48] bridge:cdist% ls -1d fe80::* + # fe80::142d:f0a5:725b:1103 + # fe80::20d:b9ff:fe49:ac11 + # fe80::20d:b9ff:fe4c:547d + # fe80::219:d2ff:feb2:2e12 + # fe80::21b:fcff:feee:f446 + # fe80::21b:fcff:feee:f45c + # fe80::21b:fcff:feee:f4b1 + # fe80::21b:fcff:feee:f4ba + # fe80::21b:fcff:feee:f4bc + # fe80::21b:fcff:feee:f4c1 + # fe80::21d:72ff:fe86:46b + # fe80::42b0:34ff:fe6f:f6f0 + # fe80::42b0:34ff:fe6f:f863 + # fe80::42b0:34ff:fe6f:f9b2 + # fe80::4a5d:60ff:fea1:e55f + # fe80::77a3:5e3f:82cc:f2e5 + # fe80::9e93:4eff:fe6c:c1f4 + # fe80::ba69:f4ff:fec5:6041 + # fe80::ba69:f4ff:fec5:8db7 + # fe80::bad8:12ff:fe65:313d + # fe80::bad8:12ff:fe65:d9b1 + # fe80::ce2d:e0ff:fed4:2611 + # fe80::ce32:e5ff:fe79:7ea7 + # fe80::d66d:6dff:fe33:e00 + # fe80::e2ff:f7ff:fe00:20e6 + # fe80::f29f:c2ff:fe7c:275e From 91d99bf08accb3bde0da420294fc9fb68d3d4068 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Thu, 29 Oct 2020 21:22:36 +0100 Subject: [PATCH 117/411] [RFC] scanner documentation --- docs/dev/logs/2020-10-29.org | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs/dev/logs/2020-10-29.org diff --git a/docs/dev/logs/2020-10-29.org b/docs/dev/logs/2020-10-29.org new file mode 100644 index 00000000..718fd68c --- /dev/null +++ b/docs/dev/logs/2020-10-29.org @@ -0,0 +1,34 @@ +* The scanner, 2020-10-29, Hacking Villa Diesbach +** Motivation + - The purpose of cdist is to ensure systems are in a configured state + - If systems reboot into a clean (think: netboot) state they are + stuck in an unconfigured mode + - We can either trigger *from* those machines + - this is what cdist trigger is for + - Or we can regulary *scan* for machines + - This method does not need any modification to standard OS +** How it works + - cdist scan uses the all nodes multicast group ff02::1 + - It sends a ping packet there in regular intervals + - This even works in non-IPv6 networks, as all operating systems + are IPv6 capable and usually IPv6 enabled by default + - Link local is always accessible! + - cdist scan receives an answer from all alive hosts + - These results are stored in ~/.cdist/scan/${hostip} + - We record the last_seen date ~/.cdist/scan/${hostip}/last_seen + - After a host is detected, cdist *can* try to configure it + - It saves the result (+/- logging needs to be defined) in + ~/.cdist/scan/${hostip}/{config, install}_result + - If logging is saved: maybe in ~/.cdist/scan/${hostip}/{config, install}_log + - Final naming TBD +** Benefits from the scanning approach + - We know when a host is alive/dead + - We can use standard OS w/o trigger customisation + - Only requirement: we can ssh into it + - Can make use f.i. of Alpine Linux w/ ssh keys feeding in + - We can trigger regular reconfiguration + - If alive && last_config_time > 1d -> reconfigure + - Data can be exported to f.i. prometheus + - Record when configured (successfully) + - Record when seen + - Enables configurations in stateless environments From 09dfcfe81e0d9e6520d9bf98598037f86c84641e Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Thu, 29 Oct 2020 23:16:08 +0100 Subject: [PATCH 118/411] [scanner] add to beta commands --- cdist/argparse.py | 32 ++++++++++++++++++++- cdist/scan/commandline.py | 55 ++++++++++++++++++++++++++++++++++++ cdist/{ => scan}/scan.py | 20 +++++++++---- docs/dev/logs/2020-10-29.org | 23 +++++++++++++++ 4 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 cdist/scan/commandline.py rename cdist/{ => scan}/scan.py (90%) diff --git a/cdist/argparse.py b/cdist/argparse.py index 1d16bb25..ff195e8c 100644 --- a/cdist/argparse.py +++ b/cdist/argparse.py @@ -8,10 +8,11 @@ import cdist.configuration import cdist.log import cdist.preos import cdist.info +import cdist.scan.commandline # set of beta sub-commands -BETA_COMMANDS = set(('install', 'inventory', )) +BETA_COMMANDS = set(('install', 'inventory', 'scan', )) # set of beta arguments for sub-commands BETA_ARGS = { 'config': set(('tag', 'all_tagged_hosts', 'use_archiving', )), @@ -470,6 +471,35 @@ def get_parsers(): 'pattern', nargs='?', help='Glob pattern.') parser['info'].set_defaults(func=cdist.info.Info.commandline) + # Scan = config + further + parser['scan'] = parser['sub'].add_parser('scan', add_help=False, + parents=[parser['config']]) + + parser['scan'] = parser['sub'].add_parser( + 'scan', parents=[parser['loglevel'], + parser['beta'], + parser['colored_output'], + parser['common'], + parser['config_main']]) + + parser['scan'].add_argument( + '-m', '--mode', help='Which modes should run', + action='append', default=[], + choices=['scan', 'trigger']) + parser['scan'].add_argument( + '--config', + action='store_true', + help='Try to configure detected hosts') + parser['scan'].add_argument( + '-I', '--interfaces', + action='append', default=[], + help='On which interfaces to scan/trigger') + parser['scan'].add_argument( + '-d', '--delay', + action='store', default=3600, + help='How long to wait before reconfiguring after last try') + parser['scan'].set_defaults(func=cdist.scan.commandline.commandline) + for p in parser: parser[p].epilog = EPILOG diff --git a/cdist/scan/commandline.py b/cdist/scan/commandline.py new file mode 100644 index 00000000..0fb718e5 --- /dev/null +++ b/cdist/scan/commandline.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# +# 2020 Nico Schottelius (nico-cdist at schottelius.org) +# +# 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 . +# +# + +import logging + +log = logging.getLogger("scan") + + +# define this outside of the class to not handle scapy import errors by default +def commandline(args): + log.debug(args) + + try: + import cdist.scan.scan as scan + except ModuleNotFoundError: + print('cdist scan requires scapy to be installed') + + processes = [] + + if not args.mode: + # By default scan and trigger, but do not call any action + args.mode = ['scan', 'trigger' ] + + if 'trigger' in args.mode: + t = scan.Trigger(interfaces=args.interfaces) + t.start() + processes.append(t) + log.debug("Trigger started") + + if 'scan' in args.mode: + s = scan.Scanner(interfaces=args.interfaces, args=args) + s.start() + processes.append(s) + log.debug("Scanner started") + + for process in processes: + process.join() diff --git a/cdist/scan.py b/cdist/scan/scan.py similarity index 90% rename from cdist/scan.py rename to cdist/scan/scan.py index e2100499..fcbf1899 100644 --- a/cdist/scan.py +++ b/cdist/scan/scan.py @@ -50,13 +50,14 @@ from multiprocessing import Process import os - -# FIXME: fail gracefully if non existent - i.e. "scapy required for scanner - please install python3-scapy" +import logging from scapy.all import * # Datetime overwrites scapy.all.datetime - needs to be imported AFTER import datetime +log = logging.getLogger("scan") + class Trigger(object): """ Trigger an ICMPv6EchoReply from all hosts that are alive @@ -87,6 +88,7 @@ class Trigger(object): def trigger(self, interface): packet = IPv6(dst=f"ff02::1%{interface}") / ICMPv6EchoRequest() + log.debug(f"Sending request on {interface}") send(packet, verbose=self.verbose) class Scanner(object): @@ -94,18 +96,18 @@ class Scanner(object): Scan for replies of hosts, maintain the up-to-date database """ - def __init__(self, interfaces=None, outdir=None): + def __init__(self, interfaces=None, args=None, outdir=None): self.interfaces = interfaces if outdir: self.outdir = outdir else: - self.outdir = "." + self.outdir = os.path.join(os.environ['HOME'], '.cdist', 'scan') def handle_pkg(self, pkg): if ICMPv6EchoReply in pkg: host = pkg['IPv6'].src - print(f"Host {host} is alive") + log.verbose(f"Host {host} is alive") dir = os.path.join(self.outdir, host) fname = os.path.join(dir, "last_seen") @@ -118,13 +120,21 @@ class Scanner(object): with open(fname, "w") as fd: fd.write(f"{now}\n") + def start(self): + self.process = Process(target=self.scan) + self.process.start() + + def join(self): + self.process.join() def scan(self): + log.debug("Scanning - zzzzz") sniff(iface=self.interfaces, filter="icmp6", prn=self.handle_pkg) + if __name__ == '__main__': t = Trigger(interfaces=["wlan0"]) t.start() diff --git a/docs/dev/logs/2020-10-29.org b/docs/dev/logs/2020-10-29.org index 718fd68c..4461be8c 100644 --- a/docs/dev/logs/2020-10-29.org +++ b/docs/dev/logs/2020-10-29.org @@ -32,3 +32,26 @@ - Record when configured (successfully) - Record when seen - Enables configurations in stateless environments +** Sample output v2020-10-29 +23:14] bridge:~% sudo cdist scan -b -I wlan0 -vv +VERBOSE: cdist: version 6.8.0-36-g91d99bf0 +VERBOSE: scan: Host fe80::21d:72ff:fe86:46b is alive +VERBOSE: scan: Host fe80::ce2d:e0ff:fed4:2611 is alive +VERBOSE: scan: Host fe80::21b:fcff:feee:f4c1 is alive +VERBOSE: scan: Host fe80::e2ff:f7ff:fe00:20e6 is alive +VERBOSE: scan: Host fe80::20d:b9ff:fe49:ac11 is alive +VERBOSE: scan: Host fe80::9e93:4eff:fe6c:c1f4 is alive +VERBOSE: scan: Host fe80::ce32:e5ff:fe79:7ea7 is alive +VERBOSE: scan: Host fe80::219:d2ff:feb2:2e12 is alive +VERBOSE: scan: Host fe80::d66d:6dff:fe33:e00 is alive +VERBOSE: scan: Host fe80::21b:fcff:feee:f446 is alive +VERBOSE: scan: Host fe80::21b:fcff:feee:f4b1 is alive +VERBOSE: scan: Host fe80::20d:b9ff:fe4c:547d is alive +VERBOSE: scan: Host fe80::bad8:12ff:fe65:313d is alive +VERBOSE: scan: Host fe80::42b0:34ff:fe6f:f6f0 is alive +VERBOSE: scan: Host fe80::ba69:f4ff:fec5:6041 is alive +VERBOSE: scan: Host fe80::f29f:c2ff:fe7c:275e is alive +VERBOSE: scan: Host fe80::ba69:f4ff:fec5:8db7 is alive +VERBOSE: scan: Host fe80::42b0:34ff:fe6f:f863 is alive +VERBOSE: scan: Host fe80::21b:fcff:feee:f4bc is alive +... From e30ecdda535200ac75a6e774590d2e1b5e1b5b28 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 3 Jun 2020 13:05:40 +0200 Subject: [PATCH 119/411] Add __uci and __uci_commit types --- cdist/conf/type/__uci/explorer/state | 89 +++++++++++++++++++ cdist/conf/type/__uci/gencode-remote | 67 ++++++++++++++ cdist/conf/type/__uci/man.rst | 77 ++++++++++++++++ cdist/conf/type/__uci/manifest | 40 +++++++++ cdist/conf/type/__uci/parameter/default/state | 1 + .../type/__uci/parameter/default/transaction | 1 + cdist/conf/type/__uci/parameter/optional | 2 + .../type/__uci/parameter/required_multiple | 1 + cdist/conf/type/__uci_commit/gencode-remote | 21 +++++ cdist/conf/type/__uci_commit/man.rst | 58 ++++++++++++ cdist/conf/type/__uci_commit/nonparallel | 0 11 files changed, 357 insertions(+) create mode 100644 cdist/conf/type/__uci/explorer/state create mode 100755 cdist/conf/type/__uci/gencode-remote create mode 100644 cdist/conf/type/__uci/man.rst create mode 100755 cdist/conf/type/__uci/manifest create mode 100644 cdist/conf/type/__uci/parameter/default/state create mode 100644 cdist/conf/type/__uci/parameter/default/transaction create mode 100644 cdist/conf/type/__uci/parameter/optional create mode 100644 cdist/conf/type/__uci/parameter/required_multiple create mode 100755 cdist/conf/type/__uci_commit/gencode-remote create mode 100644 cdist/conf/type/__uci_commit/man.rst create mode 100644 cdist/conf/type/__uci_commit/nonparallel diff --git a/cdist/conf/type/__uci/explorer/state b/cdist/conf/type/__uci/explorer/state new file mode 100644 index 00000000..2e98b606 --- /dev/null +++ b/cdist/conf/type/__uci/explorer/state @@ -0,0 +1,89 @@ +#!/bin/sh +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# 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 . +# +# This explorer retrieves the current state of the configuration option +# The output of this explorer is one of these values: +# present +# The configuration option is present and has the value of the +# parameter --value. +# absent +# The configuration option is not defined. +# different +# The configuration option is present but has a different value than the +# parameter --value. +# rearranged +# The configuration option is present (a list) and has the same values as +# the parameter --value, but in a different order. + +RS=$(printf '\036') + +option=${__object_id:?} + +values_is=$(uci -s -N -d "${RS}" get "${option}" 2>/dev/null) || { + echo absent + exit 0 +} + +# strip off trailing newline +printf '%s' "${values_is}" \ +| awk ' +BEGIN { + state = "present" # assume all is fine +} +NR == FNR { + # memoize "should" state + should[FNR] = $0 + + # go to next line (important!) + next +} + +# compare "is" state +$0 == should[FNR] { next } + +FNR > length(should) { + # there are more "is" records than "should" -> definitely different + state = "different" + exit +} + +{ + # see if we can find the value somewhere in should + for (i in should) { + if ($0 == should[i]) { + # ... value found -> rearranged + # FIXME: Duplicate values are not properly handled here. Do they matter? + state = "rearranged" + next + } + } + + state = "different" + exit +} + +END { + if (FNR < length(should)) { + # "is" was shorter than "should" -> different + state = "different" + } + + print state +} +' "${__object:?}/parameter/value" RS="${RS}" - diff --git a/cdist/conf/type/__uci/gencode-remote b/cdist/conf/type/__uci/gencode-remote new file mode 100755 index 00000000..48f114fe --- /dev/null +++ b/cdist/conf/type/__uci/gencode-remote @@ -0,0 +1,67 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# 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 . +# + +in_list() { printf '%s\n' "$@" | { grep -qxF "$(read -r NDL; echo "${NDL}")"; } } + +config=${__object_id:?} + +state_is=$(cat "${__object:?}/explorer/state") +state_should=$(cat "${__object:?}/parameter/state") + +case ${state_should} +in + (present) + if in_list "${state_is}" 'present' 'rearranged' + then + # NOTE: order is ignored so rearranged is also fine. + exit 0 + fi + + if test "$(wc -l "${__object:?}/parameter/value")" -gt 1 + then + # "should" is a list + if test "${state_is}" != 'absent' + then + printf "uci delete '%s'\n" "${config}" + fi + + while read -r value + do + printf "uci add_list '%s'='%s'\n" "${config}" "${value}" + done <"${__object:?}/parameter/value" + else + # "should" is a scalar + value=$(cat "${__object:?}/parameter/value") + printf "uci set '%s'='%s'\n" "${config}" "${value}" + fi + ;; + (absent) + if in_list "${state_is}" 'absent' + then + exit 0 + fi + + printf "uci delete '%s'\n" "${config}" + ;; + (*) + printf 'Invalid --state: %s\n' "${state_should}" >&2 + exit 1 + ;; +esac diff --git a/cdist/conf/type/__uci/man.rst b/cdist/conf/type/__uci/man.rst new file mode 100644 index 00000000..d23d8b2b --- /dev/null +++ b/cdist/conf/type/__uci/man.rst @@ -0,0 +1,77 @@ +cdist-type__uci(7) +================== + +NAME +---- +cdist-type__uci - Manage configuration values in OpenWrt's +Unified Configuration Interface (UCI) + + +DESCRIPTION +----------- +This cdist type can be used to alter configuration options in OpenWrt's UCI +system. + +Options can be applied in batches if the `--transaction` parameter is used. +It is important to ensure that the `__uci_commit` object is executed before a +new transaction is started. + +REQUIRED PARAMETERS +------------------- +value + The value to be set. Can be used multiple times. + + Due to the way cdist handles arguments, values **must not** contain newline + characters. + + +OPTIONAL PARAMETERS +------------------- +state + `present` or `absent`, defaults to `present`. +transaction + The name of the transaction this option belongs to. + If none is given: "default" is used. + + +BOOLEAN PARAMETERS +------------------ +None. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Set the system hostname + __uci system.@system[0].hostname --value 'OpenWrt' + + # Enable NTP and NTPd (in one transaction) + __uci system.ntp.enabled --value 1 --transaction ntp + __uci system.ntp.enable_server --value 1 --transaction ntp + __uci system.ntp.server --transaction ntp \ + --value '0.openwrt.pool.ntp.org' \ + --value '1.openwrt.pool.ntp.org' \ + --value '2.openwrt.pool.ntp.org' \ + --value '3.openwrt.pool.ntp.org' + export require=__uci_commit/ntp + + +SEE ALSO +-------- +- https://openwrt.org/docs/guide-user/base-system/uci +- :strong:`cdist-type__uci_commit`\ (7) + + +AUTHORS +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2020 Dennis Camera. 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/__uci/manifest b/cdist/conf/type/__uci/manifest new file mode 100755 index 00000000..e5b0fb30 --- /dev/null +++ b/cdist/conf/type/__uci/manifest @@ -0,0 +1,40 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# 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 . +# + + +os=$(cat "${__global:?}/explorer/os") + +transaction_name=$(cat "${__object:?}/parameter/transaction") + +case ${os} +in + (openwrt) + # okay + ;; + (*) + printf "Your operating system (%s) is currently not supported by this type (%s)\n" "${os}" "${__type##*/}" >&2 + printf "Please contribute an implementation for it if you can.\n" >&2 + exit 1 + ;; +esac + + +# Make sure the changes are being commited +require=${__object_name:?} __uci_commit "${transaction_name}" diff --git a/cdist/conf/type/__uci/parameter/default/state b/cdist/conf/type/__uci/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__uci/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__uci/parameter/default/transaction b/cdist/conf/type/__uci/parameter/default/transaction new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/cdist/conf/type/__uci/parameter/default/transaction @@ -0,0 +1 @@ +default diff --git a/cdist/conf/type/__uci/parameter/optional b/cdist/conf/type/__uci/parameter/optional new file mode 100644 index 00000000..ddbbba16 --- /dev/null +++ b/cdist/conf/type/__uci/parameter/optional @@ -0,0 +1,2 @@ +state +transaction diff --git a/cdist/conf/type/__uci/parameter/required_multiple b/cdist/conf/type/__uci/parameter/required_multiple new file mode 100644 index 00000000..6d4e1507 --- /dev/null +++ b/cdist/conf/type/__uci/parameter/required_multiple @@ -0,0 +1 @@ +value diff --git a/cdist/conf/type/__uci_commit/gencode-remote b/cdist/conf/type/__uci_commit/gencode-remote new file mode 100755 index 00000000..bed0eefb --- /dev/null +++ b/cdist/conf/type/__uci_commit/gencode-remote @@ -0,0 +1,21 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera@ssrq-sds-fds.ch) +# +# 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 . +# + +echo 'uci commit' diff --git a/cdist/conf/type/__uci_commit/man.rst b/cdist/conf/type/__uci_commit/man.rst new file mode 100644 index 00000000..c55d06e5 --- /dev/null +++ b/cdist/conf/type/__uci_commit/man.rst @@ -0,0 +1,58 @@ +cdist-type__uci_commit(7) +========================= + +NAME +---- +cdist-type__uci_commit - Commit a UCI transaction. + + +DESCRIPTION +----------- +This type executes the "uci commit" command on the target. +It is usually not required to use this type. Use the `--transaction` parameter +of `cdist-type__uci`\ (7) instead. + + +REQUIRED PARAMETERS +------------------- +None. + + +OPTIONAL PARAMETERS +------------------- +None. + + +BOOLEAN PARAMETERS +------------------ +None. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Commit the default transaction + __uci_commit default + + # Commit another transaction + __uci_commit my_transaction + + +SEE ALSO +-------- +:strong:`cdist-type__uci`\ (7) + + +AUTHORS +------- +Dennis Camera + + +COPYING +------- +Copyright \(C) 2020 Dennis Camera. 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/__uci_commit/nonparallel b/cdist/conf/type/__uci_commit/nonparallel new file mode 100644 index 00000000..e69de29b From 55e7b32449c9a86e34054c321b20a49795c6652f Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 3 Jun 2020 14:00:29 +0200 Subject: [PATCH 120/411] [type/__uci] Only generate __uci_commit if changes are required --- cdist/conf/type/__uci/manifest | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__uci/manifest b/cdist/conf/type/__uci/manifest index e5b0fb30..74524513 100755 --- a/cdist/conf/type/__uci/manifest +++ b/cdist/conf/type/__uci/manifest @@ -18,9 +18,12 @@ # along with cdist. If not, see . # +in_list() { printf '%s\n' "$@" | { grep -qxF "$(read -r ndl; echo "${ndl}")"; } } os=$(cat "${__global:?}/explorer/os") +state_is=$(cat "${__object:?}/explorer/state") +state_should=$(cat "${__object:?}/parameter/state") transaction_name=$(cat "${__object:?}/parameter/transaction") case ${os} @@ -35,6 +38,25 @@ in ;; esac +changes_required=false -# Make sure the changes are being commited -require=${__object_name:?} __uci_commit "${transaction_name}" +case ${state_should} +in + (present) + # NOTE: order is ignored so rearranged is also fine. + in_list "${state_is}" 'present' 'rearranged' || changes_required=true + ;; + (absent) + in_list "${state_is}" 'absent' || changes_required=true + ;; + (*) + printf 'Invalid --state: %s\n' "${state_should}" >&2 + exit 1 + ;; +esac + +if ${changes_required} +then + # Make sure the changes are being committed + require=${__object_name:?} __uci_commit "${transaction_name}" +fi From a09120977f231fe3dda1c7c07073fc7e03fc5ea0 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 3 Jun 2020 14:07:10 +0200 Subject: [PATCH 121/411] [type/__uci] Allow omission of --value parameter if --state absent --- cdist/conf/type/__uci/explorer/state | 10 +++++++++- cdist/conf/type/__uci/man.rst | 1 + cdist/conf/type/__uci/manifest | 5 +++++ .../parameter/{required_multiple => optional_multiple} | 0 4 files changed, 15 insertions(+), 1 deletion(-) rename cdist/conf/type/__uci/parameter/{required_multiple => optional_multiple} (100%) diff --git a/cdist/conf/type/__uci/explorer/state b/cdist/conf/type/__uci/explorer/state index 2e98b606..6fb4b173 100644 --- a/cdist/conf/type/__uci/explorer/state +++ b/cdist/conf/type/__uci/explorer/state @@ -40,6 +40,14 @@ values_is=$(uci -s -N -d "${RS}" get "${option}" 2>/dev/null) || { exit 0 } +if test -f "${__object:?}/parameter/value" +then + should_file="${__object:?}/parameter/value" +else + should_file='/dev/null' +fi + + # strip off trailing newline printf '%s' "${values_is}" \ | awk ' @@ -86,4 +94,4 @@ END { print state } -' "${__object:?}/parameter/value" RS="${RS}" - +' "${should_file}" RS="${RS}" - diff --git a/cdist/conf/type/__uci/man.rst b/cdist/conf/type/__uci/man.rst index d23d8b2b..c6bb81ab 100644 --- a/cdist/conf/type/__uci/man.rst +++ b/cdist/conf/type/__uci/man.rst @@ -20,6 +20,7 @@ REQUIRED PARAMETERS ------------------- value The value to be set. Can be used multiple times. + This parameter is allowed to be omitted if `--state` is `absent`. Due to the way cdist handles arguments, values **must not** contain newline characters. diff --git a/cdist/conf/type/__uci/manifest b/cdist/conf/type/__uci/manifest index 74524513..e56462e5 100755 --- a/cdist/conf/type/__uci/manifest +++ b/cdist/conf/type/__uci/manifest @@ -43,6 +43,11 @@ changes_required=false case ${state_should} in (present) + test -s "${__object:?}/parameter/value" || { + echo 'The parameter --value is required.' >&2 + exit 1 + } + # NOTE: order is ignored so rearranged is also fine. in_list "${state_is}" 'present' 'rearranged' || changes_required=true ;; diff --git a/cdist/conf/type/__uci/parameter/required_multiple b/cdist/conf/type/__uci/parameter/optional_multiple similarity index 100% rename from cdist/conf/type/__uci/parameter/required_multiple rename to cdist/conf/type/__uci/parameter/optional_multiple From d8f20a6a204142360e7fb7afd6603c69ae613e2d Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 12 Jun 2020 19:39:19 +0200 Subject: [PATCH 122/411] [type/__uci] Implement "real" transactions using batch files --- .../__uci/{gencode-remote => gencode-local} | 22 ++++++++++++++++--- cdist/conf/type/__uci/man.rst | 3 +-- cdist/conf/type/__uci_commit/gencode-remote | 21 +++++++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) rename cdist/conf/type/__uci/{gencode-remote => gencode-local} (79%) diff --git a/cdist/conf/type/__uci/gencode-remote b/cdist/conf/type/__uci/gencode-local similarity index 79% rename from cdist/conf/type/__uci/gencode-remote rename to cdist/conf/type/__uci/gencode-local index 48f114fe..bba5944d 100755 --- a/cdist/conf/type/__uci/gencode-remote +++ b/cdist/conf/type/__uci/gencode-local @@ -20,11 +20,27 @@ in_list() { printf '%s\n' "$@" | { grep -qxF "$(read -r NDL; echo "${NDL}")"; } } +uci_cmd() { + printf 'printf "%s\n"' "$1" + shift + printf " '%s'" "$@" + printf " >>'%s'\n" "${tmpfile}" +} + config=${__object_id:?} state_is=$(cat "${__object:?}/explorer/state") state_should=$(cat "${__object:?}/parameter/state") +transaction_name=$(cat "${__object:?}/parameter/transaction") + +tmpdir="${__global:?}/tmp/__uci" +# HACK +mkdir -p "${tmpdir}" + +tmpfile="${tmpdir}/${transaction_name}.txt" + + case ${state_should} in (present) @@ -44,12 +60,12 @@ in while read -r value do - printf "uci add_list '%s'='%s'\n" "${config}" "${value}" + uci_cmd "add_list '%s'='%s'" "${config}" "${value}" done <"${__object:?}/parameter/value" else # "should" is a scalar value=$(cat "${__object:?}/parameter/value") - printf "uci set '%s'='%s'\n" "${config}" "${value}" + uci_cmd "set '%s'='%s'" "${config}" "${value}" fi ;; (absent) @@ -58,7 +74,7 @@ in exit 0 fi - printf "uci delete '%s'\n" "${config}" + uci_cmd "delete '%s'" "${config}" ;; (*) printf 'Invalid --state: %s\n' "${state_should}" >&2 diff --git a/cdist/conf/type/__uci/man.rst b/cdist/conf/type/__uci/man.rst index c6bb81ab..2f64355b 100644 --- a/cdist/conf/type/__uci/man.rst +++ b/cdist/conf/type/__uci/man.rst @@ -13,8 +13,7 @@ This cdist type can be used to alter configuration options in OpenWrt's UCI system. Options can be applied in batches if the `--transaction` parameter is used. -It is important to ensure that the `__uci_commit` object is executed before a -new transaction is started. + REQUIRED PARAMETERS ------------------- diff --git a/cdist/conf/type/__uci_commit/gencode-remote b/cdist/conf/type/__uci_commit/gencode-remote index bed0eefb..ac74e5e4 100755 --- a/cdist/conf/type/__uci_commit/gencode-remote +++ b/cdist/conf/type/__uci_commit/gencode-remote @@ -18,4 +18,23 @@ # along with cdist. If not, see . # -echo 'uci commit' +transaction_name=${__object_id:?} +batchfile="${__global:?}/tmp/__uci/${transaction_name}.txt" + +test -s "${batchfile}" || exit 0 + +cat <<'EOF' +rollback() { + uci changes \ + | sed -e 's/\..*$//' -e 's/^-//' \ + | while read -r package + do + uci revert "${package}" + done +} + +EOF + +echo "uci batch <<'EOF' && uci commit || rollback" +cat "${batchfile}" +echo 'EOF' From d3574b2d3e807ae436afd90aa1ed9d01b78ca6a3 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 20 Jun 2020 16:43:16 +0200 Subject: [PATCH 123/411] [type/__uci] Send messages when options are set to be altered --- cdist/conf/type/__uci/gencode-local | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cdist/conf/type/__uci/gencode-local b/cdist/conf/type/__uci/gencode-local index bba5944d..ba27dc5e 100755 --- a/cdist/conf/type/__uci/gencode-local +++ b/cdist/conf/type/__uci/gencode-local @@ -53,6 +53,8 @@ in if test "$(wc -l "${__object:?}/parameter/value")" -gt 1 then # "should" is a list + printf 'set_list %s\n' "${config}" >>"${__messages_out:?}" + if test "${state_is}" != 'absent' then printf "uci delete '%s'\n" "${config}" @@ -64,6 +66,8 @@ in done <"${__object:?}/parameter/value" else # "should" is a scalar + printf 'set %s\n' "${config}" >>"${__messages_out:?}" + value=$(cat "${__object:?}/parameter/value") uci_cmd "set '%s'='%s'" "${config}" "${value}" fi @@ -74,6 +78,7 @@ in exit 0 fi + printf 'delete %s\n' "${config}" >>"${__messages_out:?}" uci_cmd "delete '%s'" "${config}" ;; (*) From 3a3be3631010b1bf17d084c775e306f11429f5d9 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 12 Jun 2020 19:53:26 +0200 Subject: [PATCH 124/411] [type/__uci_commit] Send message on commit of a transaction --- cdist/conf/type/__uci_commit/gencode-remote | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cdist/conf/type/__uci_commit/gencode-remote b/cdist/conf/type/__uci_commit/gencode-remote index ac74e5e4..0332d7e0 100755 --- a/cdist/conf/type/__uci_commit/gencode-remote +++ b/cdist/conf/type/__uci_commit/gencode-remote @@ -23,6 +23,8 @@ batchfile="${__global:?}/tmp/__uci/${transaction_name}.txt" test -s "${batchfile}" || exit 0 +printf 'commit transaction %s\n' "${transaction_name}" >>"${__messages_out:?}" + cat <<'EOF' rollback() { uci changes \ From e7369a1f9957ac31830a69de8101c434666da5da Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Wed, 17 Jun 2020 13:00:24 +0200 Subject: [PATCH 125/411] [type/__uci_commit] Abort if uncommited changes are present on the target --- cdist/conf/type/__uci_commit/explorer/changes | 22 ++++++++++++++++ cdist/conf/type/__uci_commit/gencode-remote | 25 +++++++++++++------ 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 cdist/conf/type/__uci_commit/explorer/changes diff --git a/cdist/conf/type/__uci_commit/explorer/changes b/cdist/conf/type/__uci_commit/explorer/changes new file mode 100644 index 00000000..2690def7 --- /dev/null +++ b/cdist/conf/type/__uci_commit/explorer/changes @@ -0,0 +1,22 @@ +#!/bin/sh +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# 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 . +# +# This explorer outputs the uncommited UCI changes on the target. + +uci changes diff --git a/cdist/conf/type/__uci_commit/gencode-remote b/cdist/conf/type/__uci_commit/gencode-remote index 0332d7e0..dd1d839c 100755 --- a/cdist/conf/type/__uci_commit/gencode-remote +++ b/cdist/conf/type/__uci_commit/gencode-remote @@ -23,20 +23,29 @@ batchfile="${__global:?}/tmp/__uci/${transaction_name}.txt" test -s "${batchfile}" || exit 0 +if test -s "${__object:?}/explorer/changes" +then + echo 'Uncommited UCI changes were found on the target:' + cat "${__object:?}/explorer/changes" + echo + echo 'This can be caused by manual changes or due to a previous failed run.' + echo 'Please investigate the situation, revert or commit the changes, and try again.' + exit 1 +fi >&2 + printf 'commit transaction %s\n' "${transaction_name}" >>"${__messages_out:?}" -cat <<'EOF' +cat < Date: Sun, 5 Jul 2020 10:25:36 +0200 Subject: [PATCH 126/411] [type/__uci_commit] Move uncommited changes check from explorer to code-remote This is done to prevent false positives/negatives (see NOTE in code) --- cdist/conf/type/__uci_commit/explorer/changes | 22 ------------------- cdist/conf/type/__uci_commit/gencode-remote | 21 +++++++++++++----- 2 files changed, 15 insertions(+), 28 deletions(-) delete mode 100644 cdist/conf/type/__uci_commit/explorer/changes diff --git a/cdist/conf/type/__uci_commit/explorer/changes b/cdist/conf/type/__uci_commit/explorer/changes deleted file mode 100644 index 2690def7..00000000 --- a/cdist/conf/type/__uci_commit/explorer/changes +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# -# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) -# -# 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 . -# -# This explorer outputs the uncommited UCI changes on the target. - -uci changes diff --git a/cdist/conf/type/__uci_commit/gencode-remote b/cdist/conf/type/__uci_commit/gencode-remote index dd1d839c..504f7c3b 100755 --- a/cdist/conf/type/__uci_commit/gencode-remote +++ b/cdist/conf/type/__uci_commit/gencode-remote @@ -23,19 +23,28 @@ batchfile="${__global:?}/tmp/__uci/${transaction_name}.txt" test -s "${batchfile}" || exit 0 -if test -s "${__object:?}/explorer/changes" +printf 'commit transaction %s\n' "${transaction_name}" >>"${__messages_out:?}" + +# NOTE: Uncommited changes are checked in code-remote instead of in an explorer +# because in cdist there is no interlocking between explorers and code +# execution. +# Checking for uncommited changes in an explorer leaves a time slot in +# which changes made are not detected by the code. +# Furthermore an explorer running concurrently with another transactions +# code-remote could lead to a false positive. + +cat <&2 -printf 'commit transaction %s\n' "${transaction_name}" >>"${__messages_out:?}" - -cat < Date: Mon, 20 Jul 2020 12:12:15 +0200 Subject: [PATCH 127/411] [type/__uci_commit] Fail when uci(1) reports errors --- cdist/conf/type/__uci_commit/gencode-remote | 37 ++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/cdist/conf/type/__uci_commit/gencode-remote b/cdist/conf/type/__uci_commit/gencode-remote index 504f7c3b..e5c93966 100755 --- a/cdist/conf/type/__uci_commit/gencode-remote +++ b/cdist/conf/type/__uci_commit/gencode-remote @@ -45,16 +45,37 @@ then exit 1 fi >&2 -rollback() { - uci changes \\ - | sed -e 's/\..*\$//' -e 's/^-//' \\ - | while read -r package - do - uci revert "\${package}" - done +check_errors() { + # reads stdin and forwards non-empty lines to stderr. + # returns 0 if stdin is empty, else 1. + ! grep -e . >&2 } -uci batch <<'EOF' && uci commit || rollback +commit() { + uci commit +} + +rollback() { + echo >&2 + echo 'An error occurred when trying to commit transaction ${transaction_name}!' >&2 + + uci changes \\ + | sed -e 's/^-//' -e 's/\..*\$//' \\ + | sort -u \\ + | while read -r _package + do + uci revert "\${_package}" + echo "\${_package}" # for logging + done \\ + | awk ' + BEGIN { printf "Reverted changes in: " } + { printf "%s%s", (FNR > 1 ? ", " : ""), \$0 } + END { printf "\\n" }' >&2 + + return 1 +} + +uci batch <<'EOF' 2>&1 | check_errors && commit || rollback $(cat "${batchfile}") EOF CODE From 4da39681188493981ec3c55ea918787195655972 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 20 Jun 2020 20:04:04 +0200 Subject: [PATCH 128/411] [type/__uci_section] Add type --- cdist/conf/type/__uci_section/explorer/match | 68 ++++++++++ .../conf/type/__uci_section/explorer/options | 28 ++++ cdist/conf/type/__uci_section/explorer/type | 25 ++++ cdist/conf/type/__uci_section/man.rst | 76 +++++++++++ cdist/conf/type/__uci_section/manifest | 122 ++++++++++++++++++ .../__uci_section/parameter/default/state | 1 + .../parameter/default/transaction | 1 + .../type/__uci_section/parameter/optional | 4 + .../__uci_section/parameter/optional_multiple | 1 + 9 files changed, 326 insertions(+) create mode 100644 cdist/conf/type/__uci_section/explorer/match create mode 100644 cdist/conf/type/__uci_section/explorer/options create mode 100644 cdist/conf/type/__uci_section/explorer/type create mode 100644 cdist/conf/type/__uci_section/man.rst create mode 100755 cdist/conf/type/__uci_section/manifest create mode 100644 cdist/conf/type/__uci_section/parameter/default/state create mode 100644 cdist/conf/type/__uci_section/parameter/default/transaction create mode 100644 cdist/conf/type/__uci_section/parameter/optional create mode 100644 cdist/conf/type/__uci_section/parameter/optional_multiple diff --git a/cdist/conf/type/__uci_section/explorer/match b/cdist/conf/type/__uci_section/explorer/match new file mode 100644 index 00000000..9cf1ea3e --- /dev/null +++ b/cdist/conf/type/__uci_section/explorer/match @@ -0,0 +1,68 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# 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 . +# +# This explorer the "prefix" of the section matching --match. + +squote_values() { + sed -e '/=".*"$/{s/="/='\''/;s/"$/'\''/}' \ + -e "/='.*'$/"'!{s/=/='\''/;s/$/'\''/}' +} + +RS=$(printf '\036') + +if ! test -e "${__object:?}/parameter/match" +then + if echo "${__object_id:?}" | grep -qvE '^[^.]+\.[^.]+$' + then + echo 'Section identifiers are a package and section name separated by a "." (period).' >&2 + exit 1 + fi + + # If no --match is given, we take the __object_id as the section identifier. + echo "${__object_id:?}" + exit 0 +fi + +test -s "${__object:?}/parameter/match" \ +&& test -s "${__object:?}/parameter/type" \ +|| { + echo 'Parameters --match and --type must be used together.' >&2 + exit 1 +} + +# Find by match +match=$(cat "${__object:?}/parameter/match") +sect_type_filter=$(cat "${__object:?}/parameter/type") + +package_filter=${sect_type_filter%%.*} +section_filter=${sect_type_filter##*.} +regex="^${package_filter}\.@${section_filter}\[[0-9]\{1,\}\]\.${match%%=*}=" + +matched_sections=$( + uci -s -N -d "${RS}" show "${package_filter}" 2>/dev/null \ + | grep -e "${regex}" \ + | sed -e 's/\.[^.]*=.*$//') + +if test "$(echo "${matched_sections}" | wc -l)" -gt 1 +then + printf 'Found multiple matching sections:\n%s\n' "${matched_sections}" >&2 + exit 1 +fi + +echo "${matched_sections}" diff --git a/cdist/conf/type/__uci_section/explorer/options b/cdist/conf/type/__uci_section/explorer/options new file mode 100644 index 00000000..67b4f83f --- /dev/null +++ b/cdist/conf/type/__uci_section/explorer/options @@ -0,0 +1,28 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# 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 . +# +# This explorer retrieves the current options of the configuration section. + +RS=$(printf '\036') + +section=$("${__type_explorer:?}/match") +test -n "${section}" || exit 0 + +uci -s -N -d "${RS}" show "${section}" 2>/dev/null \ +| grep -v -e "^${section}=" || true diff --git a/cdist/conf/type/__uci_section/explorer/type b/cdist/conf/type/__uci_section/explorer/type new file mode 100644 index 00000000..1675c2e0 --- /dev/null +++ b/cdist/conf/type/__uci_section/explorer/type @@ -0,0 +1,25 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# 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 . +# +# This explorer retrieves the current section type. + +section=$("${__type_explorer:?}/match") +test -n "${section}" || exit 0 + +uci -s -N get "${section}" 2>/dev/null || true diff --git a/cdist/conf/type/__uci_section/man.rst b/cdist/conf/type/__uci_section/man.rst new file mode 100644 index 00000000..3468bfc3 --- /dev/null +++ b/cdist/conf/type/__uci_section/man.rst @@ -0,0 +1,76 @@ +cdist-type__uci_section(7) +========================== + +NAME +---- +cdist-type__uci_section - Manage configuration sections in OpenWrt's +Unified Configuration Interface (UCI) + + +DESCRIPTION +----------- +This cdist type can be used to replace whole configuration sections in OpenWrt's +UCI system. +It can be thought of as syntactic sugar for `cdist-type__uci`\ (7), as this type +will generate the required `__uci` objects to make the section contain exactly +the options specified via ``--option``. + +Since many default UCI sections are unnamed, this type allows to find the +matching section by one of its options using the ``--match`` parameter. + + +REQUIRED PARAMETERS +------------------- +None. + + +OPTIONAL PARAMETERS +------------------- +match + Allows to find a section to "replace" through one of its parameters. + The value to this parameter is a ``