forked from ungleich-public/cdist
Compare commits
71 commits
Author | SHA1 | Date | |
---|---|---|---|
|
d4bf41ce3b | ||
7de931829a | |||
17466452f0 | |||
7d8fc8a5c3 | |||
6243165645 | |||
483f0c1614 | |||
ff6b2d0abf | |||
|
339ca9347b | ||
5a7542db75 | |||
0ae37b3445 | |||
5e6cde1398 | |||
|
77d9a757ec | ||
e5adcf451b | |||
|
9839c2d8ec | ||
1edc4d0a60 | |||
3d58c9b24f | |||
|
6c8c692a22 | ||
|
abbc7dfc37 | ||
|
8b915b15b5 | ||
|
2df2578e36 | ||
|
6f8c774cb0 | ||
54a5cb17b7 | |||
cb0fa0f2e4 | |||
|
af54fe6feb | ||
|
22039284f5 | ||
bd44c023d3 | |||
|
e0150e7796 | ||
15e1ce6450 | |||
|
08ff41efde | ||
c2c5668b70 | |||
6e3ad11ea0 | |||
|
fc6ddac718 | ||
3a321469a8 | |||
e2500248f2 | |||
0b710c6173 | |||
c33d99ee12 | |||
560374a686 | |||
fc9bd40c9a | |||
5b7cca99f7 | |||
15c642a9b7 | |||
|
bf222d0543 | ||
433399d4dc | |||
12c536dbf9 | |||
67a6965e1d | |||
398ee1e416 | |||
b209adcfca | |||
72ff48154c | |||
3d7b31cbb4 | |||
d246e06710 | |||
12787ffe2c | |||
7b6789ddeb | |||
cd4acde67e | |||
5bf0c71e7a | |||
aabef7f44a | |||
b7f392fa37 | |||
90488fcebc | |||
0f6e48dbc6 | |||
d7fdc8006f | |||
fcd730f905 | |||
|
b8eb6e984c | ||
b762ea0233 | |||
|
05c2a62191 | ||
|
5af1317c29 | ||
|
4a05669765 | ||
|
23fbfaf035 | ||
|
2ffa895f57 | ||
|
abc6d009b2 | ||
|
edcac70b2a | ||
cf0032d667 | |||
7a5896acfa | |||
485283f2e5 |
53 changed files with 1688 additions and 185 deletions
|
@ -21,6 +21,9 @@
|
|||
|
||||
set +e
|
||||
case "$("$__explorer/os")" in
|
||||
checkpoint)
|
||||
awk '{printf("%s\n", $(NF-1))}' /etc/cp-release
|
||||
;;
|
||||
openwrt)
|
||||
# shellcheck disable=SC1091
|
||||
(. /etc/openwrt_release && echo "$DISTRIB_CODENAME")
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
set +e
|
||||
case "$("$__explorer/os")" in
|
||||
checkpoint)
|
||||
cat /etc/cp-release
|
||||
;;
|
||||
openwrt)
|
||||
# shellcheck disable=SC1091
|
||||
(. /etc/openwrt_release && echo "$DISTRIB_DESCRIPTION")
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
set +e
|
||||
case "$("$__explorer/os")" in
|
||||
checkpoint)
|
||||
echo "CheckPoint"
|
||||
;;
|
||||
openwrt)
|
||||
# shellcheck disable=SC1091
|
||||
(. /etc/openwrt_release && echo "$DISTRIB_ID")
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
set +e
|
||||
case "$("$__explorer/os")" in
|
||||
checkpoint)
|
||||
sed /etc/cp-release -e 's/.* R\([1-9][0-9]*\)\.[0-9]*$/\1/'
|
||||
;;
|
||||
openwrt)
|
||||
# shellcheck disable=SC1091
|
||||
(. /etc/openwrt_release && echo "$DISTRIB_RELEASE")
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -116,6 +116,13 @@ if [ -f /etc/slackware-version ]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
# Appliances
|
||||
|
||||
if grep -q '^Check Point Gaia' /etc/cp-release 2>/dev/null; then
|
||||
echo checkpoint
|
||||
exit 0
|
||||
fi
|
||||
|
||||
uname_s="$(uname -s)"
|
||||
|
||||
# Assume there is no tr on the client -> do lower case ourselves
|
||||
|
|
|
@ -34,5 +34,9 @@ elif test -f /var/run/os-release
|
|||
then
|
||||
# FreeBSD (created by os-release service)
|
||||
cat /var/run/os-release
|
||||
elif test -f /etc/cp-release
|
||||
then
|
||||
# Checkpoint firewall or management (actually linux based)
|
||||
cat /etc/cp-release
|
||||
fi
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@ in
|
|||
# empty, but well...
|
||||
cat /etc/arch-release
|
||||
;;
|
||||
checkpoint)
|
||||
awk '{version=$NF; printf("%s\n", substr(version, 2))}' /etc/cp-release
|
||||
;;
|
||||
debian)
|
||||
debian_version=$(cat /etc/debian_version)
|
||||
case $debian_version
|
||||
|
|
|
@ -57,6 +57,11 @@ __file "/etc/apt/preferences.d/$name" \
|
|||
--owner root --group root --mode 0644 \
|
||||
--state "$state" \
|
||||
--source - << EOF
|
||||
# Created by cdist ${__type##*/}
|
||||
# Do not change. Changes will be overwritten.
|
||||
#
|
||||
|
||||
# $name
|
||||
Package: $package
|
||||
Pin: $pin
|
||||
Pin-Priority: $priority
|
||||
|
|
1
cdist/conf/type/__apt_pin/parameter/default/priority
Normal file
1
cdist/conf/type/__apt_pin/parameter/default/priority
Normal file
|
@ -0,0 +1 @@
|
|||
500
|
|
@ -1,2 +1,3 @@
|
|||
state
|
||||
package
|
||||
priority
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
distribution
|
||||
priority
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Remove the given apt repository.
|
||||
#
|
||||
# Exit with:
|
||||
# 0: if it worked
|
||||
# 1: if not
|
||||
# 2: on other error
|
||||
|
||||
import os
|
||||
import sys
|
||||
from aptsources import distro, sourceslist
|
||||
from softwareproperties import ppa
|
||||
from softwareproperties.SoftwareProperties import SoftwareProperties
|
||||
|
||||
|
||||
def remove_if_empty(file_name):
|
||||
with open(file_name, 'r') as f:
|
||||
if f.read().strip():
|
||||
return
|
||||
os.unlink(file_name)
|
||||
|
||||
def remove_repository(repository):
|
||||
#print 'repository:', repository
|
||||
codename = distro.get_distro().codename
|
||||
#print 'codename:', codename
|
||||
(line, file) = ppa.expand_ppa_line(repository.strip(), codename)
|
||||
#print 'line:', line
|
||||
#print 'file:', file
|
||||
deb_source_entry = sourceslist.SourceEntry(line, file)
|
||||
src_source_entry = sourceslist.SourceEntry('deb-src{}'.format(line[3:]), file)
|
||||
|
||||
try:
|
||||
sp = SoftwareProperties()
|
||||
sp.remove_source(deb_source_entry)
|
||||
try:
|
||||
# If there's a deb-src entry, remove that too
|
||||
sp.remove_source(src_source_entry)
|
||||
except:
|
||||
pass
|
||||
remove_if_empty(file)
|
||||
return True
|
||||
except ValueError:
|
||||
print >> sys.stderr, "Error: '%s' doesn't exists in a sourcelist file" % line
|
||||
return False
|
||||
|
||||
if __name__ == '__main__':
|
||||
if (len(sys.argv) != 2):
|
||||
print >> sys.stderr, 'Error: need a repository as argument'
|
||||
sys.exit(2)
|
||||
repository = sys.argv[1]
|
||||
if remove_repository(repository):
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
|
@ -29,9 +29,9 @@ fi
|
|||
|
||||
case "$state_should" in
|
||||
present)
|
||||
echo "add-apt-repository '$name'"
|
||||
echo "add-apt-repository -y '$name'"
|
||||
;;
|
||||
absent)
|
||||
echo "remove-apt-repository '$name'"
|
||||
echo "add-apt-repository -r -y '$name'"
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -20,9 +20,4 @@
|
|||
|
||||
__package software-properties-common
|
||||
|
||||
require="__package/software-properties-common" \
|
||||
__file /usr/local/bin/remove-apt-repository \
|
||||
--source "$__type/files/remove-apt-repository" \
|
||||
--mode 0755
|
||||
|
||||
require="$__object_name" __apt_update_index
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
set -u
|
||||
|
||||
entry="$uri $distribution $component"
|
||||
|
||||
cat << DONE
|
||||
# Created by cdist ${__type##*/}
|
||||
# Do not change. Changes will be overwritten.
|
||||
#
|
||||
|
||||
# $name
|
||||
deb ${forcedarch} $entry
|
||||
deb ${options} $entry
|
||||
DONE
|
||||
if [ -f "$__object/parameter/include-src" ]; then
|
||||
echo "deb-src $entry"
|
||||
|
|
|
@ -22,7 +22,21 @@
|
|||
name="$__object_id"
|
||||
destination="/etc/apt/sources.list.d/${name}.list"
|
||||
|
||||
# There are special arguments to apt(8) to prevent aborts if apt woudn't been
|
||||
# updated after the 19th April 2021 till the bullseye release. The additional
|
||||
# arguments acknoledge the happend suite change (the apt(8) update does the
|
||||
# same by itself).
|
||||
#
|
||||
# Using '-o $config' instead of the --allow-releaseinfo-change-* parameter
|
||||
# allows backward compatablility to pre-buster Debian versions.
|
||||
#
|
||||
# See more: ticket #861
|
||||
# https://code.ungleich.ch/ungleich-public/cdist/-/issues/861
|
||||
apt_opts="-o Acquire::AllowReleaseInfoChange::Suite=true -o Acquire::AllowReleaseInfoChange::Version=true"
|
||||
|
||||
# run 'apt-get update' only if something changed with our sources.list file
|
||||
# it will be run a second time on error as a redundancy messure to success
|
||||
if grep -q "^__file${destination}" "$__messages_in"; then
|
||||
printf 'apt-get update || apt-get update\n'
|
||||
printf 'apt-get %s update || apt-get %s update\n' "$apt_opts" "$apt_opts"
|
||||
fi
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ OPTIONAL PARAMETERS
|
|||
arch
|
||||
set this if you need to force and specific arch (ubuntu specific)
|
||||
|
||||
signed-by
|
||||
provide a GPG key fingerprint or keyring path for signature checks
|
||||
|
||||
state
|
||||
'present' or 'absent', defaults to 'present'
|
||||
|
||||
|
@ -56,6 +59,11 @@ EXAMPLES
|
|||
--uri http://archive.canonical.com/ \
|
||||
--component partner --state present
|
||||
|
||||
__apt_source goaccess \
|
||||
--uri http://deb.goaccess.io/ \
|
||||
--component main \
|
||||
--signed-by C03B48887D5E56B046715D3297BD1A0133449C3D
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
|
|
|
@ -31,9 +31,15 @@ fi
|
|||
component="$(cat "$__object/parameter/component")"
|
||||
|
||||
if [ -f "$__object/parameter/arch" ]; then
|
||||
forcedarch="[arch=$(cat "$__object/parameter/arch")]"
|
||||
else
|
||||
forcedarch=""
|
||||
options="arch=$(cat "$__object/parameter/arch")"
|
||||
fi
|
||||
|
||||
if [ -f "$__object/parameter/signed-by" ]; then
|
||||
options="$options signed-by=$(cat "$__object/parameter/signed-by")"
|
||||
fi
|
||||
|
||||
if [ "$options" ]; then
|
||||
options="[$options]"
|
||||
fi
|
||||
|
||||
# export variables for use in template
|
||||
|
@ -41,7 +47,7 @@ export name
|
|||
export uri
|
||||
export distribution
|
||||
export component
|
||||
export forcedarch
|
||||
export options
|
||||
|
||||
# generate file from template
|
||||
mkdir "$__object/files"
|
||||
|
|
|
@ -2,3 +2,4 @@ state
|
|||
distribution
|
||||
component
|
||||
arch
|
||||
signed-by
|
||||
|
|
|
@ -18,9 +18,23 @@
|
|||
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
# There are special arguments to apt(8) to prevent aborts if apt woudn't been
|
||||
# updated after the 19th April 2021 till the bullseye release. The additional
|
||||
# arguments acknoledge the happend suite change (the apt(8) update does the
|
||||
# same by itself).
|
||||
#
|
||||
# Using '-o $config' instead of the --allow-releaseinfo-change-* parameter
|
||||
# allows backward compatablility to pre-buster Debian versions.
|
||||
#
|
||||
# See more: ticket #861
|
||||
# https://code.ungleich.ch/ungleich-public/cdist/-/issues/861
|
||||
apt_opts="-o Acquire::AllowReleaseInfoChange::Suite=true -o Acquire::AllowReleaseInfoChange::Version=true"
|
||||
|
||||
# run 'apt-get update' if anything in /etc/apt is newer then /var/lib/apt/lists
|
||||
# it will be run a second time on error as a redundancy messure to success
|
||||
cat << DONE
|
||||
if find /etc/apt -mindepth 1 -cnewer /var/lib/apt/lists | grep . > /dev/null; then
|
||||
apt-get update || apt-get update
|
||||
apt-get $apt_opts update || apt-get $apt_opts update
|
||||
fi
|
||||
DONE
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
'file' has been deprecated in favour of 'line' in order to provide idempotency.
|
|
@ -37,6 +37,12 @@ state
|
|||
source
|
||||
forwarded to :strong:`__file` type
|
||||
|
||||
file
|
||||
forwarded to :strong:`__file` type
|
||||
This can be used if multiple users need to have a dotfile updated,
|
||||
which will result in duplicate object id errors. When using the
|
||||
file parameter the object id can be some unique value.
|
||||
|
||||
MESSAGES
|
||||
--------
|
||||
|
||||
|
@ -61,6 +67,15 @@ EXAMPLES
|
|||
# Install default xmonad config for user 'eve'. Parent directory is created automatically.
|
||||
__dot_file .xmonad/xmonad.hs --user eve --state exists --source "$__files/xmonad.hs"
|
||||
|
||||
# install .vimrc for root and some users
|
||||
for user in root userx usery userz; do
|
||||
__dot_file "${user}_dot_vimrc" \
|
||||
--user $user \
|
||||
--file .vimrc \
|
||||
--state exists \
|
||||
--source "$__files/$user/.vimrc"
|
||||
done
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
|
|
|
@ -20,13 +20,19 @@ user="$(cat "${__object}/parameter/user")"
|
|||
home="$(cat "${__object}/explorer/home")"
|
||||
primary_group="$(cat "${__object}/explorer/primary_group")"
|
||||
dirmode="$(cat "${__object}/parameter/dirmode")"
|
||||
if [ -f "${__object}/parameter/file" ]; then
|
||||
file="$(cat "${__object}/parameter/file")"
|
||||
else
|
||||
file="${__object_id}"
|
||||
fi
|
||||
|
||||
|
||||
# Create parent directory. Type __directory has flag 'parents', but it
|
||||
# will leave us with root-owned directory in user home, which is not
|
||||
# acceptable. So we create parent directories one-by-one. XXX: maybe
|
||||
# it should be fixed in '__directory'?
|
||||
set --
|
||||
subpath=${__object_id}
|
||||
subpath=${file}
|
||||
while subpath="$(dirname "${subpath}")" ; do
|
||||
[ "${subpath}" = . ] && break
|
||||
set -- "${subpath}" "$@"
|
||||
|
@ -64,4 +70,4 @@ if [ "${source}" = "-" ] ; then
|
|||
fi
|
||||
unset source
|
||||
|
||||
__file "${home}/${__object_id}" --owner "$user" --group "$primary_group" "$@"
|
||||
__file "${home}/${file}" --owner "$user" --group "$primary_group" "$@"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
|
||||
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
|
||||
# 2013-2022 Steven Armstrong (steven-cdist armstrong.cc)
|
||||
#
|
||||
# This file is part of cdist.
|
||||
#
|
||||
|
@ -72,6 +72,7 @@ if [ "$state_should" = "present" ] || [ "$state_should" = "exists" ]; then
|
|||
if [ "$type" != "file" ]; then
|
||||
# destination is not a regular file, upload source to replace it
|
||||
upload_file=1
|
||||
echo upload >> "$__messages_out"
|
||||
else
|
||||
local_cksum="$(cksum < "$source")"
|
||||
remote_cksum="$(cat "$__object/explorer/cksum")"
|
||||
|
@ -88,13 +89,30 @@ if [ "$state_should" = "present" ] || [ "$state_should" = "exists" ]; then
|
|||
mkdir "$__object/files"
|
||||
touch "$__object/files/set-attributes"
|
||||
|
||||
if [ "$create_file" ]; then
|
||||
# When creating an empty file we create it locally and then
|
||||
# upload it so that permissions can be set before moving the file
|
||||
# into place.
|
||||
source="$__object/files/empty"
|
||||
touch "$source"
|
||||
fi
|
||||
|
||||
# upload file to temp location
|
||||
tempfile_template="${destination}.cdist.XXXXXXXXXX"
|
||||
cat << DONE
|
||||
destination_upload="\$($__remote_exec $__target_host "mktemp $tempfile_template")"
|
||||
DONE
|
||||
if [ "$upload_file" ]; then
|
||||
echo upload >> "$__messages_out"
|
||||
upload_destination="${destination}.cdist.${__cdist_object_marker}.$$"
|
||||
# Yes, we are aware that this is a race condition.
|
||||
# However:
|
||||
# a) cdist usually writes to directories that are not user writable
|
||||
# (probably > 99.9%)
|
||||
# b) if they are user owned, the user / attacker always wins
|
||||
# (probably < 0.1%)
|
||||
# c) the only case which we could improve are tmp directories and we
|
||||
# don't think managing tmp directories with cdist is a typical case
|
||||
# ("the rest %)"
|
||||
|
||||
# Tell gencode-remote to where we uploaded the file so it can move
|
||||
# it to its final destination.
|
||||
echo "$upload_destination" > "$__object/files/upload-destination"
|
||||
|
||||
# IPv6 fix
|
||||
if echo "${__target_host}" | grep -q -E '^[0-9a-fA-F:]+$'
|
||||
then
|
||||
|
@ -103,12 +121,7 @@ DONE
|
|||
my_target_host="${__target_host}"
|
||||
fi
|
||||
cat << DONE
|
||||
$__remote_copy "$source" "${my_target_host}:\$destination_upload"
|
||||
DONE
|
||||
fi
|
||||
# move uploaded file into place
|
||||
cat << DONE
|
||||
$__remote_exec $__target_host "rm -rf \"$destination\"; mv \"\$destination_upload\" \"$destination\""
|
||||
$__remote_copy "$source" "${my_target_host}:${upload_destination}"
|
||||
DONE
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
|
||||
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
|
||||
# 2013-2022 Steven Armstrong (steven-cdist armstrong.cc)
|
||||
#
|
||||
# This file is part of cdist.
|
||||
#
|
||||
|
@ -62,6 +62,13 @@ set_mode() {
|
|||
|
||||
case "$state_should" in
|
||||
present|exists)
|
||||
if [ -f "$__object/files/upload-destination" ]; then
|
||||
final_destination="$destination"
|
||||
# We change the 'global' $destination variable here so we can
|
||||
# change attributes of the new/uploaded file before moving it
|
||||
# to it's final destination.
|
||||
destination="$(cat "$__object/files/upload-destination")"
|
||||
fi
|
||||
# Note: Mode - needs to happen last as a chown/chgrp can alter mode by
|
||||
# clearing S_ISUID and S_ISGID bits (see chown(2))
|
||||
for attribute in group owner mode; do
|
||||
|
@ -81,6 +88,11 @@ case "$state_should" in
|
|||
fi
|
||||
fi
|
||||
done
|
||||
if [ -f "$__object/files/upload-destination" ]; then
|
||||
# move uploaded file into place
|
||||
printf 'rm -rf "%s"\n' "$final_destination"
|
||||
printf 'mv "%s" "%s"\n' "$destination" "$final_destination"
|
||||
fi
|
||||
if [ -f "$__object/files/set-attributes" ]; then
|
||||
# set-attributes is created if file is created or uploaded in gencode-local
|
||||
fire_onchange=1
|
||||
|
|
|
@ -15,7 +15,7 @@ case $os in
|
|||
# Differntation not needed anymore
|
||||
apt_source_distribution=stable
|
||||
;;
|
||||
10*)
|
||||
10*|11*)
|
||||
# Differntation not needed anymore
|
||||
apt_source_distribution=stable
|
||||
;;
|
||||
|
|
8
cdist/conf/type/__haproxy_dualstack/files/http
Normal file
8
cdist/conf/type/__haproxy_dualstack/files/http
Normal file
|
@ -0,0 +1,8 @@
|
|||
frontend http
|
||||
bind BIND@:80
|
||||
mode http
|
||||
option httplog
|
||||
default_backend http
|
||||
|
||||
backend http
|
||||
mode http
|
10
cdist/conf/type/__haproxy_dualstack/files/https
Normal file
10
cdist/conf/type/__haproxy_dualstack/files/https
Normal file
|
@ -0,0 +1,10 @@
|
|||
frontend https
|
||||
bind BIND@:443
|
||||
mode tcp
|
||||
option tcplog
|
||||
tcp-request inspect-delay 5s
|
||||
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||
default_backend https
|
||||
|
||||
backend https
|
||||
mode tcp
|
12
cdist/conf/type/__haproxy_dualstack/files/imaps
Normal file
12
cdist/conf/type/__haproxy_dualstack/files/imaps
Normal file
|
@ -0,0 +1,12 @@
|
|||
frontend imaps
|
||||
bind BIND@:143
|
||||
bind BIND@:993
|
||||
|
||||
mode tcp
|
||||
option tcplog
|
||||
tcp-request inspect-delay 5s
|
||||
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||
default_backend imaps
|
||||
|
||||
backend imaps
|
||||
mode tcp
|
12
cdist/conf/type/__haproxy_dualstack/files/smtps
Normal file
12
cdist/conf/type/__haproxy_dualstack/files/smtps
Normal file
|
@ -0,0 +1,12 @@
|
|||
frontend smtps
|
||||
bind BIND@:25
|
||||
bind BIND@:465
|
||||
|
||||
mode tcp
|
||||
option tcplog
|
||||
tcp-request inspect-delay 5s
|
||||
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||
default_backend smtps
|
||||
|
||||
backend smtps
|
||||
mode tcp
|
121
cdist/conf/type/__haproxy_dualstack/man.rst
Normal file
121
cdist/conf/type/__haproxy_dualstack/man.rst
Normal file
|
@ -0,0 +1,121 @@
|
|||
cdist-type__haproxy_dualstack(7)
|
||||
================================
|
||||
|
||||
|
||||
NAME
|
||||
----
|
||||
cdist-type__haproxy_dualstack - Proxy services from a dual-stack server
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
This (singleton) type installs and configures haproxy to act as a dual-stack
|
||||
proxy for single-stack services.
|
||||
|
||||
This can be useful to add IPv4 support to IPv6-only services while only using
|
||||
one IPv4 for many such services.
|
||||
|
||||
By default this type uses the plain TCP proxy mode, which means that there is no
|
||||
need for TLS termination on this host when SNI is supported.
|
||||
This also means that proxied services will not receive the client's IP address,
|
||||
but will see the proxy's IP address instead (that of `$__target_host`).
|
||||
|
||||
This can be solved by using the PROXY protocol, but do take into account that,
|
||||
e.g. nginx cannot serve both regular HTTP(S) and PROXY protocols on the same
|
||||
port, so you will need to use other ports for that.
|
||||
|
||||
As a recommendation in this type: use TCP ports 8080 and 591 respectively to
|
||||
serve HTTP and HTTPS using the PROXY protocol.
|
||||
|
||||
See the EXAMPLES for more details.
|
||||
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
-------------------
|
||||
v4proxy
|
||||
Proxy incoming IPv4 connections to the equivalent IPv6 endpoint.
|
||||
In its simplest use, it must be a NAME with an `AAAA` DNS entry, which is
|
||||
the IP address actually providing the proxied services.
|
||||
The full format of this argument is:
|
||||
`[proxy:]NAME[[:PROTOCOL_1=PORT_1]...[:PROTOCOL_N=PORT_N]]`
|
||||
Where starting with `proxy:` determines that the PROXY protocol must be
|
||||
used and each `:PROTOCOL=PORT` (e.g. `:http=8080` or `:https=591`) is a PORT
|
||||
override for the given PROTOCOL (see `--protocol`), if not present the
|
||||
PROTOCOL's default port will be used.
|
||||
|
||||
|
||||
v6proxy
|
||||
Proxy incoming IPv6 connections to the equivalent IPv4 endpoint.
|
||||
In its simplest use, it must be a NAME with an `A` DNS entry, which is
|
||||
the IP address actually providing the proxied services.
|
||||
See `--v4proxy` for more options and details.
|
||||
|
||||
protocol
|
||||
Can be passed multiple times or as a space-separated list of protocols.
|
||||
Currently supported protocols are: `http`, `https`, `imaps`, `smtps`.
|
||||
This defaults to: `http https imaps smtps`.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# Proxy the IPv6-only services so IPv4-only clients can access them
|
||||
# This uses HAProxy's TCP mode for http, https, imaps and smtps
|
||||
__haproxy_dualstack \
|
||||
--v4proxy ipv6.chat \
|
||||
--v4proxy matrix.ungleich.ch
|
||||
|
||||
# Proxy the IPv6-only HTTP(S) services so IPv4-only clients can access them
|
||||
# Note this means that the backend IPv6-only server will only see
|
||||
# the IPv6 address of the haproxy host managed by cdist, which can be
|
||||
# troublesome if this information is relevant for analytics/security/...
|
||||
# See the PROXY example below
|
||||
__haproxy_dualstack \
|
||||
--protocol http --protocol https \
|
||||
--v4proxy ipv6.chat \
|
||||
--v4proxy matrix.ungleich.ch
|
||||
|
||||
# Use the PROXY protocol to proxy the IPv6-only HTTP(S) services enabling
|
||||
# IPv4-only clients to access them while maintaining the client's IP address
|
||||
__haproxy_dualstack \
|
||||
--protocol http --protocol https \
|
||||
--v4proxy proxy:ipv6.chat:http=8080:https=591 \
|
||||
--v4proxy proxy:matrix.ungleich.ch:http=8080:https=591
|
||||
# Note however that the PROXY protocol is not compatible with regular
|
||||
# HTTP(S) protocols, so your nginx will have to listen on different ports
|
||||
# with the PROXY settings.
|
||||
# Note that you will need to restrict access to the 8080 port to prevent
|
||||
# Client IP spoofing.
|
||||
# This can be something like:
|
||||
# server {
|
||||
# # listen for regular HTTP connections
|
||||
# listen [::]:80 default_server;
|
||||
# listen 80 default_server;
|
||||
# # listen for PROXY HTTP connections
|
||||
# listen [::]:8080 proxy_protocol;
|
||||
# # Accept the Client's IP from the PROXY protocol
|
||||
# real_ip_header proxy_protocol;
|
||||
# }
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
- https://www.haproxy.com/blog/enhanced-ssl-load-balancing-with-server-name-indication-sni-tls-extension/
|
||||
- https://www.haproxy.com/blog/haproxy/proxy-protocol/
|
||||
- https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
ungleich <foss--@--ungleich.ch>
|
||||
Evilham <cvs--@--evilham.com>
|
||||
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2021 ungleich glarus ag. 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.
|
155
cdist/conf/type/__haproxy_dualstack/manifest
Normal file
155
cdist/conf/type/__haproxy_dualstack/manifest
Normal file
|
@ -0,0 +1,155 @@
|
|||
#!/bin/sh -eu
|
||||
|
||||
__package haproxy
|
||||
require="__package/haproxy" __start_on_boot haproxy
|
||||
|
||||
tmpdir="$__object/files"
|
||||
mkdir "$tmpdir"
|
||||
configtmp="$__object/files/haproxy.cfg"
|
||||
|
||||
os=$(cat "$__global/explorer/os")
|
||||
case $os in
|
||||
freebsd)
|
||||
CONFIG_FILE="/usr/local/etc/haproxy.conf"
|
||||
cat <<EOF > "$configtmp"
|
||||
global
|
||||
maxconn 4000
|
||||
user nobody
|
||||
group nogroup
|
||||
daemon
|
||||
|
||||
EOF
|
||||
|
||||
;;
|
||||
*)
|
||||
CONFIG_FILE="/etc/haproxy/haproxy.cfg"
|
||||
cat <<EOF > "$configtmp"
|
||||
global
|
||||
log [::1] local2
|
||||
chroot /var/lib/haproxy
|
||||
pidfile /var/run/haproxy.pid
|
||||
maxconn 4000
|
||||
user haproxy
|
||||
group haproxy
|
||||
daemon
|
||||
|
||||
# turn on stats unix socket
|
||||
stats socket /var/lib/haproxy/stats
|
||||
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
cat <<EOF >> "$configtmp"
|
||||
defaults
|
||||
retries 3
|
||||
log global
|
||||
timeout http-request 10s
|
||||
timeout queue 1m
|
||||
timeout connect 10s
|
||||
timeout client 1m
|
||||
timeout server 1m
|
||||
timeout http-keep-alive 10s
|
||||
timeout check 10s
|
||||
EOF
|
||||
|
||||
dig_cmd="$(command -v dig || true)"
|
||||
get_ip() {
|
||||
# Usage: get_ip (ipv4|ipv6) NAME
|
||||
# uses "dig" if available, else fallback to "host"
|
||||
case $1 in
|
||||
ipv4)
|
||||
if [ -n "${dig_cmd}" ]; then
|
||||
${dig_cmd} +short A "$2"
|
||||
else
|
||||
host -t A "$2" | cut -d ' ' -f 4 | grep -v 'found:'
|
||||
fi
|
||||
;;
|
||||
ipv6)
|
||||
if [ -n "${dig_cmd}" ]; then
|
||||
${dig_cmd} +short AAAA "$2"
|
||||
else
|
||||
host -t AAAA "$2" | cut -d ' ' -f 5 | grep -v 'NXDOMAIN'
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
PROTOCOLS="$(cat "$__object/parameter/protocol")"
|
||||
|
||||
for proxy in v4proxy v6proxy; do
|
||||
param=$__object/parameter/$proxy
|
||||
# no backend? skip generating code
|
||||
if [ ! -f "$param" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# turn backend name into bind parameter: v4backend -> ipv4@
|
||||
bind=$(echo $proxy | sed -e 's/^/ip/' -e 's/proxy//')
|
||||
|
||||
case $bind in
|
||||
ipv4)
|
||||
backendproto=ipv6
|
||||
;;
|
||||
ipv6)
|
||||
backendproto=ipv4
|
||||
;;
|
||||
esac
|
||||
|
||||
for proto in ${PROTOCOLS}; do
|
||||
# Add protocol "header"
|
||||
printf "\n# %s %s \n" "${bind}" "${proto}" >> "$configtmp"
|
||||
|
||||
sed -e "s/BIND/$bind/" \
|
||||
-e "s/\(frontend[[:space:]].*\)/\1$bind/" \
|
||||
-e "s/\(backend[[:space:]].*\)/\\1$bind/" \
|
||||
"$__type/files/$proto" >> "$configtmp"
|
||||
|
||||
while read -r hostdefinition; do
|
||||
if echo "$hostdefinition" | grep -qE '^proxy:'; then
|
||||
# Proxy protocol was requested
|
||||
host="$(echo "$hostdefinition" | sed -E 's/^proxy:([^:]+).*$/\1/')"
|
||||
send_proxy=" send-proxy"
|
||||
else
|
||||
# Just use tcp proxy mode
|
||||
host="$hostdefinition"
|
||||
send_proxy=""
|
||||
fi
|
||||
if echo "$hostdefinition" | grep -qE ":${proto}="; then
|
||||
# Use custom port definition if requested
|
||||
port="$(echo "$hostdefinition" | sed -E "s/^(.*:)?${proto}=([0-9]+).*$/:\2/")"
|
||||
else
|
||||
# Else use the default
|
||||
port=""
|
||||
fi
|
||||
servername=$host
|
||||
|
||||
res=$(get_ip "$bind" "$servername")
|
||||
|
||||
if [ -z "$res" ]; then
|
||||
echo "$servername does not resolve - aborting config" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Treat protocols without TLS+SNI specially
|
||||
if [ "$proto" = http ]; then
|
||||
echo " use-server $servername if { hdr(host) -i $host }" >> "$configtmp"
|
||||
else
|
||||
echo " use-server $servername if { req_ssl_sni -i $host }" >> "$configtmp"
|
||||
fi
|
||||
|
||||
# Create the "server" itself.
|
||||
# Note that port and send_proxy will be empty unless
|
||||
# they were requested by the type user
|
||||
echo " server $servername ${backendproto}@${host}${port}${send_proxy}" >> "$configtmp"
|
||||
|
||||
done < "$param"
|
||||
done
|
||||
done
|
||||
|
||||
# Create config file
|
||||
require="__package/haproxy" __file ${CONFIG_FILE} --source "$configtmp" --mode 0644
|
||||
|
||||
require="__file${CONFIG_FILE}" __check_messages "haproxy_reload" \
|
||||
--pattern "^__file${CONFIG_FILE}" \
|
||||
--execute "service haproxy reload || service haproxy restart"
|
|
@ -0,0 +1 @@
|
|||
http https imaps smtps
|
|
@ -0,0 +1,3 @@
|
|||
protocol
|
||||
v4proxy
|
||||
v6proxy
|
0
cdist/conf/type/__haproxy_dualstack/singleton
Normal file
0
cdist/conf/type/__haproxy_dualstack/singleton
Normal file
|
@ -41,7 +41,7 @@ if [ -z "${certbot_fullpath}" ]; then
|
|||
require="__apt_source/stretch-backports" __package_apt certbot \
|
||||
--target-release stretch-backports
|
||||
;;
|
||||
10*)
|
||||
10*|11*)
|
||||
__package_apt certbot
|
||||
;;
|
||||
|
||||
|
|
|
@ -81,12 +81,24 @@ aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes -o Dpkg::Options::=
|
|||
|
||||
case "$state_should" in
|
||||
present)
|
||||
# There are special arguments to apt(8) to prevent aborts if apt woudn't been
|
||||
# updated after the 19th April 2021 till the bullseye release. The additional
|
||||
# arguments acknoledge the happend suite change (the apt(8) update does the
|
||||
# same by itself).
|
||||
#
|
||||
# Using '-o $config' instead of the --allow-releaseinfo-change-* parameter
|
||||
# allows backward compatablility to pre-buster Debian versions.
|
||||
#
|
||||
# See more: ticket #861
|
||||
# https://code.ungleich.ch/ungleich-public/cdist/-/issues/861
|
||||
apt_opts="-o Acquire::AllowReleaseInfoChange::Suite=true -o Acquire::AllowReleaseInfoChange::Version=true"
|
||||
|
||||
# following is bit ugly, but important hack.
|
||||
# due to how cdist config run works, there isn't
|
||||
# currently better way to do it :(
|
||||
cat << EOF
|
||||
if [ ! -f /var/cache/apt/pkgcache.bin ] || [ "\$( stat --format %Y /var/cache/apt/pkgcache.bin )" -lt "\$( date +%s -d '-1 day' )" ]
|
||||
then echo apt-get update > /dev/null 2>&1 || true
|
||||
then echo apt-get $apt_opts update > /dev/null 2>&1 || true
|
||||
fi
|
||||
EOF
|
||||
if [ -n "$version" ]; then
|
||||
|
|
|
@ -41,7 +41,19 @@ fi
|
|||
case "$type" in
|
||||
yum) ;;
|
||||
apt)
|
||||
echo "apt-get --quiet update"
|
||||
# There are special arguments to apt(8) to prevent aborts if apt woudn't been
|
||||
# updated after the 19th April 2021 till the bullseye release. The additional
|
||||
# arguments acknoledge the happend suite change (the apt(8) update does the
|
||||
# same by itself).
|
||||
#
|
||||
# Using '-o $config' instead of the --allow-releaseinfo-change-* parameter
|
||||
# allows backward compatablility to pre-buster Debian versions.
|
||||
#
|
||||
# See more: ticket #861
|
||||
# https://code.ungleich.ch/ungleich-public/cdist/-/issues/861
|
||||
apt_opts="-o Acquire::AllowReleaseInfoChange::Suite=true -o Acquire::AllowReleaseInfoChange::Version=true"
|
||||
|
||||
echo "apt-get --quiet $apt_opts update"
|
||||
echo "apt-cache updated (age was: $currage)" >> "$__messages_out"
|
||||
;;
|
||||
pacman)
|
||||
|
|
|
@ -28,6 +28,10 @@ apt_clean="$__object/parameter/apt-clean"
|
|||
|
||||
apt_dist_upgrade="$__object/parameter/apt-dist-upgrade"
|
||||
|
||||
if [ -f "$__object/parameter/apt-with-new-pkgs" ]; then
|
||||
apt_with_new_pkgs="--with-new-pkgs"
|
||||
fi
|
||||
|
||||
if [ -f "$type" ]; then
|
||||
type="$(cat "$type")"
|
||||
else
|
||||
|
@ -54,7 +58,7 @@ case "$type" in
|
|||
apt)
|
||||
if [ -f "$apt_dist_upgrade" ]
|
||||
then echo "$aptget dist-upgrade"
|
||||
else echo "$aptget upgrade"
|
||||
else echo "$aptget $apt_with_new_pkgs upgrade"
|
||||
fi
|
||||
|
||||
if [ -f "$apt_clean" ]
|
||||
|
|
|
@ -33,6 +33,14 @@ BOOLEAN PARAMETERS
|
|||
apt-dist-upgrade
|
||||
Do dist-upgrade instead of upgrade.
|
||||
|
||||
apt-with-new-pkg
|
||||
Allow installing new packages when used in conjunction with
|
||||
upgrade. This is useful if the update of an installed package
|
||||
requires new dependencies to be installed. Instead of holding the
|
||||
package back upgrade will upgrade the package and install the new
|
||||
dependencies. Note that upgrade with this option will never remove
|
||||
packages, only allow adding new ones.
|
||||
|
||||
apt-clean
|
||||
Clean out the local repository of retrieved package files.
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
apt-clean
|
||||
apt-dist-upgrade
|
||||
apt-with-new-pkgs
|
||||
|
|
16
cdist/conf/type/__sed/explorer/file
Executable file
16
cdist/conf/type/__sed/explorer/file
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
if [ -f "$__object/parameter/file" ]
|
||||
then
|
||||
file="$( cat "$__object/parameter/file" )"
|
||||
else
|
||||
file="/$__object_id"
|
||||
fi
|
||||
|
||||
if [ ! -e "$file" ]
|
||||
then
|
||||
echo "$file does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat "$file"
|
58
cdist/conf/type/__sed/gencode-remote
Executable file
58
cdist/conf/type/__sed/gencode-remote
Executable file
|
@ -0,0 +1,58 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
if [ -f "$__object/parameter/file" ]
|
||||
then
|
||||
file="$( cat "$__object/parameter/file" )"
|
||||
else
|
||||
file="/$__object_id"
|
||||
fi
|
||||
|
||||
script="$( cat "$__object/parameter/script" )"
|
||||
|
||||
if [ "$script" = '-' ]
|
||||
then
|
||||
script="$( cat "$__object/stdin" )"
|
||||
fi
|
||||
|
||||
# since stdin is not available in explorer, we pull file from target with explorer
|
||||
|
||||
file_from_target="$__object/explorer/file"
|
||||
|
||||
sed_cmd='sed'
|
||||
|
||||
if [ -f "$__object/parameter/regexp-extended" ]
|
||||
then
|
||||
sed_cmd="$sed_cmd -E"
|
||||
fi
|
||||
|
||||
# do sed dry run, diff result and if no change, then there's nothing to do
|
||||
# also redirect diff's output to stderr for debugging purposes
|
||||
|
||||
if echo "$script" | "$sed_cmd" -f - "$file_from_target" | diff -u "$file_from_target" - >&2
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# we can't use -i, because it's not posix, so we fly with tempfile and cp
|
||||
# and we use cp because we want to preserve destination file's attributes
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
echo 'tmp="$__object/tempfile"'
|
||||
|
||||
echo "$sed_cmd -f - '$file' > \"\$tmp\" << EOF"
|
||||
|
||||
echo "$script"
|
||||
|
||||
echo 'EOF'
|
||||
|
||||
echo "cp \"\$tmp\" '$file'"
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
echo 'rm -f "$tmp"'
|
||||
|
||||
echo 'change' >> "$__messages_out"
|
||||
|
||||
if [ -f "$__object/parameter/onchange" ]
|
||||
then
|
||||
cat "$__object/parameter/onchange"
|
||||
fi
|
57
cdist/conf/type/__sed/man.rst
Normal file
57
cdist/conf/type/__sed/man.rst
Normal file
|
@ -0,0 +1,57 @@
|
|||
cdist-type__sed(7)
|
||||
==================
|
||||
|
||||
NAME
|
||||
----
|
||||
cdist-type__sed - Transform text files with ``sed``
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Transform text files with ``sed``.
|
||||
|
||||
|
||||
REQUIRED MULTIPLE PARAMETERS
|
||||
----------------------------
|
||||
script
|
||||
``sed`` script.
|
||||
If ``-`` then the script is read from ``stdin``.
|
||||
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
-------------------
|
||||
file
|
||||
Path to the file. Defaults to ``$__object_id``.
|
||||
|
||||
onchange
|
||||
Execute this command if ``sed`` changes file.
|
||||
|
||||
|
||||
BOOLEAN PARAMETERS
|
||||
------------------
|
||||
regexp-extended
|
||||
Use extended regular expressions in the script.
|
||||
Might not be supported with every ``sed`` version.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
__sed /tmp/foobar --script 's/foo/bar/'
|
||||
|
||||
echo 's/foo/bar/' | __sed foobar --file /tmp/foobar --script -
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Ander Punnar <ander-at-kvlt-dot-ee>
|
||||
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2021 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.
|
1
cdist/conf/type/__sed/parameter/boolean
Normal file
1
cdist/conf/type/__sed/parameter/boolean
Normal file
|
@ -0,0 +1 @@
|
|||
regexp-extended
|
2
cdist/conf/type/__sed/parameter/optional
Normal file
2
cdist/conf/type/__sed/parameter/optional
Normal file
|
@ -0,0 +1,2 @@
|
|||
file
|
||||
onchange
|
1
cdist/conf/type/__sed/parameter/required_multiple
Normal file
1
cdist/conf/type/__sed/parameter/required_multiple
Normal file
|
@ -0,0 +1 @@
|
|||
script
|
|
@ -40,6 +40,7 @@ if [ -f "$file" ]; then
|
|||
grep -v -F -x '$line' '$file' >\$tmpfile
|
||||
fi
|
||||
cat "\$tmpfile" >"$file"
|
||||
rm -f "\$tmpfile"
|
||||
DONE
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ def _process_hosts_simple(action, host, manifest, verbose,
|
|||
"""
|
||||
if isinstance(host, str):
|
||||
hosts = [host, ]
|
||||
elif isinstance(host, collections.Iterable):
|
||||
elif isinstance(host, collections.abc.Iterable):
|
||||
hosts = host
|
||||
else:
|
||||
raise cdist.Error('Invalid host argument: {}'.format(host))
|
||||
|
|
|
@ -33,7 +33,7 @@ class AbsolutePathRequiredError(cdist.Error):
|
|||
return 'Absolute path required, got: {}'.format(self.path)
|
||||
|
||||
|
||||
class FileList(collections.MutableSequence):
|
||||
class FileList(collections.abc.MutableSequence):
|
||||
"""A list that stores it's state in a file.
|
||||
|
||||
"""
|
||||
|
@ -102,7 +102,7 @@ class FileList(collections.MutableSequence):
|
|||
self.__write(lines)
|
||||
|
||||
|
||||
class DirectoryDict(collections.MutableMapping):
|
||||
class DirectoryDict(collections.abc.MutableMapping):
|
||||
"""A dict that stores it's items as files in a directory.
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
Changelog
|
||||
---------
|
||||
|
||||
next:
|
||||
* Explorer machine_type: Rewrite (Dennis Camera)
|
||||
* New type: __sed (Ander Punnar)
|
||||
* New type: __haproxy_dualstack (Evilham and ungleich)
|
||||
* Type __apt_update_index: Fix complaint about suite change (Matthias Stecher)
|
||||
* Type __package_update_index: Fix complaint about suite change (Matthias Stecher)
|
||||
* Type __package_upgrade_all: Add new --apt-with-new-pkgs argument (Evilham)
|
||||
* Type __apt_source: Fix complaint about suite change (Matthias Stecher)
|
||||
* Type __package_apt: Fix complaint about suite change (Matthias Stecher)
|
||||
* Type __debconf_set_selections: Fix bug where --file was unsupported (Evilham)
|
||||
* Types __letsencrypt_cert, __grafana_dashboard: Improve bullseye support (Evilham)
|
||||
* Type __ssh_authorized_key: Also remove tmpfile if removing line (Mark Verboom)
|
||||
* Type __apt_pin: Add default priority, add comment in generated files (Daniel Fancsali)
|
||||
* Type __file: make file uploading and attribute changes more atomic (Steven Armstrong)
|
||||
* Type __dot_file: Add support for using --file parameter (Stephan Leemburg)
|
||||
* Type __apt_ppa: Replace custom "remove-apt-repository" with add-apt-repository -r (Romain Dartigues)
|
||||
* Type __apt_source: Add signed-by parameter (Daniel Fancsali)
|
||||
* Explorer: add support for checkpoint (Stephan Leemburg)
|
||||
|
||||
6.9.8: 2021-08-24
|
||||
* Type __rsync: Rewrite (Ander Punnar)
|
||||
* New type: __apt_pin (Daniel Fancsali)
|
||||
|
|
Loading…
Reference in a new issue