Merge branch '2018.3' into 'develop'

Conflicts:
  - tests/unit/grains/test_core.py
This commit is contained in:
rallytime 2018-05-02 15:28:21 -04:00
commit bd184a257f
No known key found for this signature in database
GPG key ID: E8F1A4B90D0DEA19
44 changed files with 1795 additions and 891 deletions

32
.github/CODEOWNERS vendored
View file

@ -9,43 +9,45 @@
# See https://help.github.com/articles/about-codeowners/
# for more info about the CODEOWNERS file
# This file uses an fnmatch-style matching pattern.
# Team Boto
salt/**/*boto* @saltstack/team-boto
# Team Core
salt/auth/ @saltstack/team-core
salt/cache/ @saltstack/team-core
salt/cli/ @saltstack/team-core
salt/auth/* @saltstack/team-core
salt/cache/* @saltstack/team-core
salt/cli/* @saltstack/team-core
salt/client/* @saltstack/team-core
salt/config/* @saltstack/team-core
salt/daemons/ @saltstack/team-core
salt/pillar/ @saltstack/team-core
salt/daemons/* @saltstack/team-core
salt/pillar/* @saltstack/team-core
salt/loader.py @saltstack/team-core
salt/payload.py @saltstack/team-core
salt/**/master* @saltstack/team-core
salt/**/minion* @saltstack/team-core
# Team Cloud
salt/cloud/ @saltstack/team-cloud
salt/utils/openstack/ @saltstack/team-cloud
salt/cloud/* @saltstack/team-cloud
salt/utils/openstack/* @saltstack/team-cloud
salt/utils/aws.py @saltstack/team-cloud
salt/**/*cloud* @saltstack/team-cloud
# Team NetAPI
salt/cli/api.py @saltstack/team-netapi
salt/client/netapi.py @saltstack/team-netapi
salt/netapi/ @saltstack/team-netapi
salt/netapi/* @saltstack/team-netapi
# Team Network
salt/proxy/ @saltstack/team-proxy
salt/proxy/* @saltstack/team-proxy
# Team SPM
salt/cli/spm.py @saltstack/team-spm
salt/spm/ @saltstack/team-spm
salt/spm/* @saltstack/team-spm
# Team SSH
salt/cli/ssh.py @saltstack/team-ssh
salt/client/ssh/ @saltstack/team-ssh
salt/client/ssh/* @saltstack/team-ssh
salt/runners/ssh.py @saltstack/team-ssh
salt/**/thin.py @saltstack/team-ssh
@ -61,8 +63,12 @@ salt/**/*xfs* @saltstack/team-suse
salt/**/*zypper* @saltstack/team-suse
# Team Transport
salt/transport/ @saltstack/team-transport
salt/transport/* @saltstack/team-transport
salt/utils/zeromq.py @saltstack/team-transport
# Team Windows
salt/**/*win* @saltstack/team-windows
salt/*/*win* @saltstack/team-windows
salt/modules/reg.py @saltstack/team-windows
salt/states/reg.py @saltstack/team-windows
tests/*/*win* @saltstack/team-windows
tests/*/test_reg.py @saltstack/team-windows

View file

@ -323,6 +323,7 @@ rst_prolog = """\
.. _`salt-users`: https://groups.google.com/forum/#!forum/salt-users
.. _`salt-announce`: https://groups.google.com/forum/#!forum/salt-announce
.. _`salt-packagers`: https://groups.google.com/forum/#!forum/salt-packagers
.. _`salt-slack`: https://saltstackcommunity.herokuapp.com/
.. |windownload| raw:: html
<p>Python2 x86: <a

View file

@ -60,7 +60,7 @@ Fork a Repo Guide_>`_ and is well worth reading.
isolated into separate branches.
If you're working on a bug or documentation fix, create your branch from
the oldest release branch that contains the bug or requires the documentation
the oldest **supported** main release branch that contains the bug or requires the documentation
update. See :ref:`Which Salt Branch? <which-salt-branch>`.
.. code-block:: bash
@ -212,8 +212,11 @@ There are three different kinds of branches in use: develop, main release
branches, and dot release branches.
- All feature work should go into the ``develop`` branch.
- Bug fixes and documentation changes should go into the oldest supported
**main** release branch affected by the the bug or documentation change.
- Bug fixes and documentation changes should go into the oldest **supported
main** release branch affected by the the bug or documentation change (you
can use the blame button in github to figure out when the bug was introduced).
Supported releases are the last 2 releases. For example, if the latest release
is 2018.3, the last two release are 2018.3 and 2017.7.
Main release branches are named after a year and month, such as
``2016.11`` and ``2017.7``.
- Hot fixes, as determined by SaltStack's release team, should be submitted
@ -247,7 +250,7 @@ Main Release Branches
=====================
The current release branch is the most recent stable release. Pull requests
containing bug fixes or documentation changes should be made against the main
containing bug fixes or documentation changes should be made against the oldest supported main
release branch that is affected.
The branch name will be a date-based name such as ``2016.11``.

View file

@ -221,8 +221,9 @@ The best way to create new Formula repositories for now is to create a
repository in your own account on GitHub and notify a SaltStack employee when
it is ready. We will add you to the Contributors team on the
`saltstack-formulas`_ organization and help you transfer the repository over.
Ping a SaltStack employee on IRC (``#salt`` on Freenode) or send an email to
the `salt-users`_ mailing list.
Ping a SaltStack employee on IRC (``#salt`` on Freenode), join the
``#formulas`` channel on the `salt-slack`_ or send an email to the
`salt-users`_ mailing list.
There are a lot of repositories in that organization! Team members can manage
which repositories they are subscribed to on GitHub's watching page:

View file

@ -20,6 +20,9 @@ Statistics:
Changes:
This release includes a CVE Fix:
CVE-2017-7893: Compromised salt-minions can impersonate the salt-master. (Discovery credit: Frank Spierings)
- **PR** `#39855`_: (*Foxlik*) Use regular expression instead of split when replacing authorized_keys
@ *2017-03-22T18:28:32Z*

View file

@ -3,3 +3,12 @@ Salt 2018.3.1 Release Notes
===========================
Version 2018.3.1 is a bugfix release for :ref:`2018.3.0 <release-2018-3-0>`.
Changes to Slack Engine pillars
-------------------------------
When using ``groups_pillar_name`` for the slack engine, the engine should be
used as part of a salt-minion process running on the master. This will allow
the minion to have pillars assigned to it, and will still allow the engine to
create a LocalClient connection to the master ipc sockets to control
environments.

View file

@ -9,7 +9,7 @@
#
# BUGS: https://github.com/saltstack/salt-bootstrap/issues
#
# COPYRIGHT: (c) 2012-2017 by the SaltStack Team, see AUTHORS.rst for more
# COPYRIGHT: (c) 2012-2018 by the SaltStack Team, see AUTHORS.rst for more
# details.
#
# LICENSE: Apache 2.0
@ -18,7 +18,7 @@
#======================================================================================================================
set -o nounset # Treat unset variables as an error
__ScriptVersion="2017.12.13"
__ScriptVersion="2018.04.25"
__ScriptName="bootstrap-salt.sh"
__ScriptFullName="$0"
@ -249,7 +249,6 @@ _CURL_ARGS=${BS_CURL_ARGS:-}
_FETCH_ARGS=${BS_FETCH_ARGS:-}
_GPG_ARGS=${BS_GPG_ARGS:-}
_WGET_ARGS=${BS_WGET_ARGS:-}
_ENABLE_EXTERNAL_ZMQ_REPOS=${BS_ENABLE_EXTERNAL_ZMQ_REPOS:-$BS_FALSE}
_SALT_MASTER_ADDRESS=${BS_SALT_MASTER_ADDRESS:-null}
_SALT_MINION_ID="null"
# _SIMPLIFY_VERSION is mostly used in Solaris based distributions
@ -299,13 +298,13 @@ __usage() {
Examples:
- ${__ScriptName}
- ${__ScriptName} stable
- ${__ScriptName} stable 2016.3
- ${__ScriptName} stable 2016.3.1
- ${__ScriptName} stable 2017.7
- ${__ScriptName} stable 2017.7.2
- ${__ScriptName} daily
- ${__ScriptName} testing
- ${__ScriptName} git
- ${__ScriptName} git 2016.3
- ${__ScriptName} git v2016.3.1
- ${__ScriptName} git 2017.7
- ${__ScriptName} git v2017.7.2
- ${__ScriptName} git 06f249901a2e2f1ed310d58ea3921a129f214358
Options:
@ -355,8 +354,6 @@ __usage() {
per -p flag. You're responsible for providing the proper package name.
-H Use the specified HTTP proxy for all download URLs (including https://).
For example: http://myproxy.example.com:3128
-Z Enable additional package repository for newer ZeroMQ
(only available for RHEL/CentOS/Fedora/Ubuntu based distributions)
-b Assume that dependencies are already installed and software sources are
set up. If git is selected, git tree is still checked out as dependency
step.
@ -395,7 +392,7 @@ __usage() {
tested with Centos 6 and is considered experimental. This will install the
ius repo on the box if disable repo is false. This must be used in conjunction
with -x <pythonversion>. For example:
sh bootstrap.sh -P -y -x python2.7 git v2016.11.3
sh bootstrap.sh -P -y -x python2.7 git v2017.7.2
The above will install python27 and install the git version of salt using the
python2.7 executable. This only works for git and pip installations.
@ -438,7 +435,6 @@ do
p ) _EXTRA_PACKAGES="$_EXTRA_PACKAGES $OPTARG" ;;
d ) _DISABLE_SALT_CHECKS=$BS_TRUE ;;
H ) _HTTP_PROXY="$OPTARG" ;;
Z ) _ENABLE_EXTERNAL_ZMQ_REPOS=$BS_TRUE ;;
b ) _NO_DEPS=$BS_TRUE ;;
f ) _FORCE_SHALLOW_CLONE=$BS_TRUE ;;
l ) _DISABLE_SSL=$BS_TRUE ;;
@ -593,14 +589,14 @@ elif [ "$ITYPE" = "stable" ]; then
if [ "$#" -eq 0 ];then
STABLE_REV="latest"
else
if [ "$(echo "$1" | egrep '^(latest|1\.6|1\.7|2014\.1|2014\.7|2015\.5|2015\.8|2016\.3|2016\.11|2017\.7)$')" != "" ]; then
if [ "$(echo "$1" | egrep '^(latest|1\.6|1\.7|2014\.1|2014\.7|2015\.5|2015\.8|2016\.3|2016\.11|2017\.7|2018\.3)$')" != "" ]; then
STABLE_REV="$1"
shift
elif [ "$(echo "$1" | egrep '^([0-9]*\.[0-9]*\.[0-9]*)$')" != "" ]; then
STABLE_REV="archive/$1"
shift
else
echo "Unknown stable version: $1 (valid: 1.6, 1.7, 2014.1, 2014.7, 2015.5, 2015.8, 2016.3, 2016.11, 2017.7, latest, \$MAJOR.\$MINOR.\$PATCH)"
echo "Unknown stable version: $1 (valid: 1.6, 1.7, 2014.1, 2014.7, 2015.5, 2015.8, 2016.3, 2016.11, 2017.7, 2018.3, latest, \$MAJOR.\$MINOR.\$PATCH)"
exit 1
fi
fi
@ -1331,10 +1327,10 @@ __check_dpkg_architecture() {
if [ "${error_msg}" != "" ]; then
echoerror "${error_msg}"
if [ "$ITYPE" != "git" ]; then
echoerror "You can try git installation mode, i.e.: sh ${__ScriptName} git v2016.11.5."
echoerror "You can try git installation mode, i.e.: sh ${__ScriptName} git v2017.7.2."
echoerror "It may be necessary to use git installation mode with pip and disable the SaltStack apt repository."
echoerror "For example:"
echoerror " sh ${__ScriptName} -r -P git v2016.11.5"
echoerror " sh ${__ScriptName} -r -P git v2017.7.2"
fi
fi
@ -1372,16 +1368,10 @@ __ubuntu_codename_translation() {
DISTRO_CODENAME="trusty"
;;
"16")
if [ "$_april" ]; then
DISTRO_CODENAME="xenial"
else
DISTRO_CODENAME="yakkety"
fi
DISTRO_CODENAME="xenial"
;;
"17")
if [ "$_april" ]; then
DISTRO_CODENAME="zesty"
fi
DISTRO_CODENAME="artful"
;;
*)
DISTRO_CODENAME="trusty"
@ -1500,9 +1490,12 @@ __check_end_of_life_versions() {
# < 14.04
# = 14.10
# = 15.04, 15.10
# = 16.10
# = 17.04
if [ "$DISTRO_MAJOR_VERSION" -lt 14 ] || \
[ "$DISTRO_MAJOR_VERSION" -eq 15 ] || \
([ "$DISTRO_MAJOR_VERSION" -lt 16 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]); then
([ "$DISTRO_MAJOR_VERSION" -eq 17 ] && [ "$DISTRO_MINOR_VERSION" -eq 04 ]) || \
([ "$DISTRO_MAJOR_VERSION" -lt 17 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]); then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://wiki.ubuntu.com/Releases"
@ -1544,8 +1537,8 @@ __check_end_of_life_versions() {
;;
fedora)
# Fedora lower than 25 are no longer supported
if [ "$DISTRO_MAJOR_VERSION" -lt 25 ]; then
# Fedora lower than 26 are no longer supported
if [ "$DISTRO_MAJOR_VERSION" -lt 26 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://fedoraproject.org/wiki/Releases"
@ -1765,12 +1758,41 @@ __function_defined() {
}
#--- FUNCTION -------------------------------------------------------------------------------------------------------
# NAME: __wait_for_apt
# DESCRIPTION: Check if any apt, apt-get, aptitude, or dpkg processes are running before
# calling these again. This is useful when these process calls are part of
# a boot process, such as on AWS AMIs. This func will wait until the boot
# process is finished so the script doesn't exit on a locked proc.
#----------------------------------------------------------------------------------------------------------------------
__wait_for_apt(){
echodebug "Checking if apt process is currently running."
# Timeout set at 15 minutes
WAIT_TIMEOUT=900
while ps -C apt,apt-get,aptitude,dpkg >/dev/null; do
sleep 1
WAIT_TIMEOUT=$((WAIT_TIMEOUT - 1))
# If timeout reaches 0, abort.
if [ "$WAIT_TIMEOUT" -eq 0 ]; then
echoerror "Apt, apt-get, aptitude, or dpkg process is taking too long."
echoerror "Bootstrap script cannot proceed. Aborting."
return 1
fi
done
echodebug "No apt processes are currently running."
}
#--- FUNCTION -------------------------------------------------------------------------------------------------------
# NAME: __apt_get_install_noinput
# DESCRIPTION: (DRY) apt-get install with noinput options
# PARAMETERS: packages
#----------------------------------------------------------------------------------------------------------------------
__apt_get_install_noinput() {
__wait_for_apt
apt-get install -y -o DPkg::Options::=--force-confold "${@}"; return $?
} # ---------- end of function __apt_get_install_noinput ----------
@ -1780,6 +1802,7 @@ __apt_get_install_noinput() {
# DESCRIPTION: (DRY) apt-get upgrade with noinput options
#----------------------------------------------------------------------------------------------------------------------
__apt_get_upgrade_noinput() {
__wait_for_apt
apt-get upgrade -y -o DPkg::Options::=--force-confold; return $?
} # ---------- end of function __apt_get_upgrade_noinput ----------
@ -1790,6 +1813,7 @@ __apt_get_upgrade_noinput() {
# PARAMETERS: url
#----------------------------------------------------------------------------------------------------------------------
__apt_key_fetch() {
__wait_for_apt
url=$1
# shellcheck disable=SC2086
@ -2544,7 +2568,7 @@ __enable_universe_repository() {
__install_saltstack_ubuntu_repository() {
# Workaround for latest non-LTS ubuntu
if [ "$DISTRO_VERSION" = "16.10" ] || [ "$DISTRO_MAJOR_VERSION" -gt 16 ]; then
if [ "$DISTRO_MAJOR_VERSION" -gt 16 ]; then
echowarn "Non-LTS Ubuntu detected, but stable packages requested. Trying packages from latest LTS release. You may experience problems."
UBUNTU_VERSION=16.04
UBUNTU_CODENAME="xenial"
@ -2556,8 +2580,8 @@ __install_saltstack_ubuntu_repository() {
__PACKAGES=''
# Install downloader backend for GPG keys fetching
if [ "$DISTRO_VERSION" = "16.10" ] || [ "$DISTRO_MAJOR_VERSION" -gt 16 ]; then
__PACKAGES="${__PACKAGES} gnupg2 dirmngr"
if [ "$DISTRO_MAJOR_VERSION" -gt 16 ]; then
__PACKAGES="${__PACKAGES} gnupg dirmngr"
else
__PACKAGES="${__PACKAGES} gnupg-curl"
fi
@ -2576,6 +2600,7 @@ __install_saltstack_ubuntu_repository() {
__apt_key_fetch "$SALTSTACK_UBUNTU_URL/SALTSTACK-GPG-KEY.pub" || return 1
__wait_for_apt
apt-get update
}
@ -2588,6 +2613,7 @@ install_ubuntu_deps() {
__enable_universe_repository || return 1
__wait_for_apt
apt-get update
fi
@ -2644,6 +2670,7 @@ install_ubuntu_stable_deps() {
# No user interaction, libc6 restart services for example
export DEBIAN_FRONTEND=noninteractive
__wait_for_apt
apt-get update
if [ "${_UPGRADE_SYS}" -eq $BS_TRUE ]; then
@ -2664,6 +2691,7 @@ install_ubuntu_stable_deps() {
}
install_ubuntu_daily_deps() {
__wait_for_apt
install_ubuntu_stable_deps || return 1
if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then
@ -2681,6 +2709,7 @@ install_ubuntu_daily_deps() {
}
install_ubuntu_git_deps() {
__wait_for_apt
apt-get update
if ! __check_command_exists git; then
@ -2711,8 +2740,8 @@ install_ubuntu_git_deps() {
else
install_ubuntu_stable_deps || return 1
__PACKAGES="${__PACKAGES} python-crypto python-jinja2 python-msgpack python-requests"
__PACKAGES="${__PACKAGES} python-tornado python-yaml python-zmq"
__PACKAGES="${__PACKAGES} python-crypto python-jinja2 python-m2crypto python-msgpack"
__PACKAGES="${__PACKAGES} python-requests python-tornado python-yaml python-zmq"
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
# Install python-libcloud if asked to
@ -2791,7 +2820,7 @@ install_ubuntu_stable_post() {
/bin/systemctl preset salt-$fname.service > /dev/null 2>&1 &&
/bin/systemctl enable salt-$fname.service > /dev/null 2>&1
)
sleep 0.1
sleep 1
/bin/systemctl daemon-reload
elif [ -f /etc/init.d/salt-$fname ]; then
update-rc.d salt-$fname defaults
@ -2817,7 +2846,7 @@ install_ubuntu_git_post() {
[ $fname = "api" ] && continue
systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service)
sleep 0.1
sleep 1
systemctl daemon-reload
elif [ -f /sbin/initctl ]; then
_upstart_conf="/etc/init/salt-$fname.conf"
@ -2973,6 +3002,7 @@ __install_saltstack_debian_repository() {
__apt_key_fetch "$SALTSTACK_DEBIAN_URL/SALTSTACK-GPG-KEY.pub" || return 1
__wait_for_apt
apt-get update
}
@ -2984,6 +3014,7 @@ install_debian_deps() {
# No user interaction, libc6 restart services for example
export DEBIAN_FRONTEND=noninteractive
__wait_for_apt
apt-get update
if [ "${_UPGRADE_SYS}" -eq $BS_TRUE ]; then
@ -3030,9 +3061,9 @@ install_debian_git_deps() {
__git_clone_and_checkout || return 1
__PACKAGES="libzmq3 libzmq3-dev lsb-release python-apt python-backports.ssl-match-hostname python-crypto"
__PACKAGES="${__PACKAGES} python-jinja2 python-msgpack python-requests"
__PACKAGES="${__PACKAGES} python-tornado python-yaml python-zmq"
__PACKAGES="libzmq3 libzmq3-dev lsb-release python-apt python-backports.ssl-match-hostname"
__PACKAGES="${__PACKAGES} python-crypto python-jinja2 python-msgpack python-m2crypto"
__PACKAGES="${__PACKAGES} python-requests python-tornado python-yaml python-zmq"
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
# Install python-libcloud if asked to
@ -3071,8 +3102,9 @@ install_debian_8_git_deps() {
__git_clone_and_checkout || return 1
__PACKAGES="libzmq3 libzmq3-dev lsb-release python-apt python-crypto python-jinja2 python-msgpack"
__PACKAGES="${__PACKAGES} python-requests python-systemd python-yaml python-zmq"
__PACKAGES="libzmq3 libzmq3-dev lsb-release python-apt python-crypto python-jinja2"
__PACKAGES="${__PACKAGES} python-m2crypto python-msgpack python-requests python-systemd"
__PACKAGES="${__PACKAGES} python-yaml python-zmq"
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
# Install python-libcloud if asked to
@ -3081,7 +3113,7 @@ install_debian_8_git_deps() {
__PIP_PACKAGES=''
if (__check_pip_allowed >/dev/null 2>&1); then
__PIP_PACKAGES='tornado'
__PIP_PACKAGES='tornado<5.0'
# Install development environment for building tornado Python module
__PACKAGES="${__PACKAGES} build-essential python-dev"
@ -3096,6 +3128,7 @@ install_debian_8_git_deps() {
/etc/apt/sources.list.d/backports.list
fi
__wait_for_apt
apt-get update || return 1
# python-tornado package should be installed from backports repo
@ -3135,8 +3168,8 @@ install_debian_9_git_deps() {
__git_clone_and_checkout || return 1
__PACKAGES="libzmq5 lsb-release python-apt python-backports-abc python-crypto"
__PACKAGES="${__PACKAGES} python-jinja2 python-msgpack python-requests python-systemd"
__PACKAGES="${__PACKAGES} python-tornado python-yaml python-zmq"
__PACKAGES="${__PACKAGES} python-jinja2 python-m2crypto python-msgpack python-requests"
__PACKAGES="${__PACKAGES} python-systemd python-tornado python-yaml python-zmq"
if [ "$_INSTALL_CLOUD" -eq $BS_TRUE ]; then
# Install python-libcloud if asked to
@ -3330,15 +3363,8 @@ install_debian_check_services() {
install_fedora_deps() {
if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then
if [ "$_ENABLE_EXTERNAL_ZMQ_REPOS" -eq $BS_TRUE ]; then
__install_saltstack_copr_zeromq_repository || return 1
fi
__install_saltstack_copr_salt_repository || return 1
fi
__PACKAGES="PyYAML libyaml python-crypto python-jinja2 python-zmq python2-msgpack python2-requests"
__PACKAGES="libyaml m2crypto PyYAML python-crypto python-jinja2"
__PACKAGES="${__PACKAGES} python2-msgpack python2-requests python-zmq"
if [ "$DISTRO_MAJOR_VERSION" -lt 26 ]; then
__PACKAGES="${__PACKAGES} yum-utils"
@ -3395,7 +3421,7 @@ install_fedora_stable_post() {
[ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue
systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service)
sleep 0.1
sleep 1
systemctl daemon-reload
done
}
@ -3456,7 +3482,7 @@ install_fedora_git_post() {
[ $fname = "api" ] && continue
systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service)
sleep 0.1
sleep 1
systemctl daemon-reload
done
}
@ -3523,20 +3549,6 @@ __install_epel_repository() {
return 0
}
__install_saltstack_copr_zeromq_repository() {
echoinfo "Installing Zeromq >=4 and PyZMQ>=14 from SaltStack's COPR repository"
if [ ! -s /etc/yum.repos.d/saltstack-zeromq4.repo ]; then
if [ "${DISTRO_NAME_L}" = "fedora" ]; then
__REPOTYPE="${DISTRO_NAME_L}"
else
__REPOTYPE="epel"
fi
__fetch_url /etc/yum.repos.d/saltstack-zeromq4.repo \
"${HTTP_VAL}://copr.fedorainfracloud.org/coprs/saltstack/zeromq4/repo/${__REPOTYPE}-${DISTRO_MAJOR_VERSION}/saltstack-zeromq4-${__REPOTYPE}-${DISTRO_MAJOR_VERSION}.repo" || return 1
fi
return 0
}
__install_saltstack_rhel_repository() {
if [ "$ITYPE" = "stable" ]; then
repo_rev="$STABLE_REV"
@ -3550,7 +3562,7 @@ __install_saltstack_rhel_repository() {
gpg_key="SALTSTACK-GPG-KEY.pub"
repo_file="/etc/yum.repos.d/saltstack.repo"
if [ ! -s "$repo_file" ]; then
if [ ! -s "$repo_file" ] || [ "$_FORCE_OVERWRITE" -eq $BS_TRUE ]; then
cat <<_eof > "$repo_file"
[saltstack]
name=SaltStack ${repo_rev} Release Channel for RHEL/CentOS \$releasever
@ -3564,26 +3576,10 @@ _eof
fetch_url="${HTTP_VAL}://${_REPO_URL}/yum/redhat/${DISTRO_MAJOR_VERSION}/${CPU_ARCH_L}/${repo_rev}/"
__rpm_import_gpg "${fetch_url}${gpg_key}" || return 1
fi
return 0
}
__install_saltstack_copr_salt_repository() {
echoinfo "Adding SaltStack's COPR repository"
if [ "${DISTRO_NAME_L}" = "fedora" ]; then
[ "$DISTRO_MAJOR_VERSION" -ge 22 ] && return 0
__REPOTYPE="${DISTRO_NAME_L}"
else
__REPOTYPE="epel"
fi
__REPO_FILENAME="saltstack-salt-${__REPOTYPE}-${DISTRO_MAJOR_VERSION}.repo"
if [ ! -s "/etc/yum.repos.d/${__REPO_FILENAME}" ]; then
__fetch_url "/etc/yum.repos.d/${__REPO_FILENAME}" \
"${HTTP_VAL}://copr.fedorainfracloud.org/coprs/saltstack/salt/repo/${__REPOTYPE}-${DISTRO_MAJOR_VERSION}/${__REPO_FILENAME}" || return 1
yum clean metadata || return 1
elif [ "$repo_rev" != "latest" ]; then
echowarn "saltstack.repo already exists, ignoring salt version argument."
echowarn "Use -F (forced overwrite) to install $repo_rev."
fi
return 0
@ -3688,7 +3684,8 @@ install_centos_git_deps() {
__git_clone_and_checkout || return 1
__PACKAGES="python-crypto python-futures python-msgpack python-zmq python-jinja2 python-requests python-tornado"
__PACKAGES="m2crypto python-crypto python-futures python-jinja2 python-msgpack"
__PACKAGES="${__PACKAGES} python-requests python-tornado python-zmq"
if [ "$DISTRO_MAJOR_VERSION" -ge 7 ]; then
__PACKAGES="${__PACKAGES} systemd-python"
@ -3705,7 +3702,12 @@ install_centos_git_deps() {
if [ "${_PY_EXE}" != "" ]; then
# If "-x" is defined, install dependencies with pip based on the Python version given.
_PIP_PACKAGES="jinja2 msgpack-python pycrypto PyYAML tornado zmq"
_PIP_PACKAGES="m2crypto jinja2 msgpack-python pycrypto PyYAML tornado<5.0 zmq"
# install swig and openssl on cent6
if [ "$DISTRO_MAJOR_VERSION" -eq 6 ]; then
__yum_install_noinput openssl-devel swig || return 1
fi
if [ -f "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt" ]; then
for SINGLE_PACKAGE in $_PIP_PACKAGES; do
@ -4275,7 +4277,7 @@ install_alpine_linux_stable_deps() {
install_alpine_linux_git_deps() {
install_alpine_linux_stable_deps || return 1
apk -U add python2 py-virtualenv py2-crypto py2-setuptools \
apk -U add python2 py-virtualenv py2-crypto py2-m2crypto py2-setuptools \
py2-jinja2 py2-yaml py2-markupsafe py2-msgpack py2-psutil \
py2-zmq zeromq py2-requests || return 1
@ -4367,6 +4369,7 @@ install_alpine_linux_restart_daemons() {
# Skip if not meant to be installed
[ $fname = "master" ] && [ "$_INSTALL_MASTER" -eq $BS_FALSE ] && continue
[ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue
[ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue
# Disable stdin to fix shell session hang on killing tee pipe
/sbin/rc-service salt-$fname stop < /dev/null > /dev/null 2>&1
@ -4382,6 +4385,7 @@ install_alpine_linux_check_services() {
# Skip if not meant to be installed
[ $fname = "master" ] && [ "$_INSTALL_MASTER" -eq $BS_FALSE ] && continue
[ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue
[ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue
__check_services_alpine salt-$fname || return 1
done
@ -4400,6 +4404,7 @@ daemons_running_alpine_linux() {
# Skip if not meant to be installed
[ $fname = "minion" ] && [ "$_INSTALL_MINION" -eq $BS_FALSE ] && continue
[ $fname = "master" ] && [ "$_INSTALL_MASTER" -eq $BS_FALSE ] && continue
[ $fname = "syndic" ] && [ "$_INSTALL_SYNDIC" -eq $BS_FALSE ] && continue
# shellcheck disable=SC2009
if [ "$(ps wwwaux | grep -v grep | grep salt-$fname)" = "" ]; then
@ -4427,10 +4432,20 @@ install_amazon_linux_ami_deps() {
_USEAWS=$BS_FALSE
pkg_append="python"
repo_rev="$(echo "${STABLE_REV}" | sed 's|.*\/||g')"
if [ "$ITYPE" = "stable" ]; then
repo_rev="$STABLE_REV"
else
repo_rev="latest"
fi
if echo $repo_rev | egrep -q '^archive'; then
year=$(echo "$repo_rev" | cut -d '/' -f 2 | cut -c1-4)
else
year=$(echo "$repo_rev" | cut -c1-4)
fi
if echo "$repo_rev" | egrep -q '^(latest|2016\.11)$' || \
[ "$(echo "$repo_rev" | cut -c1-4)" -gt 2016 ]; then
[ "$year" -gt 2016 ]; then
_USEAWS=$BS_TRUE
pkg_append="python27"
fi
@ -4477,7 +4492,8 @@ _eof
# Package python-ordereddict-1.1-2.el6.noarch is obsoleted by python26-2.6.9-2.88.amzn1.x86_64
# which is already installed
__PACKAGES="${pkg_append}-PyYAML ${pkg_append}-crypto ${pkg_append}-msgpack ${pkg_append}-zmq ${pkg_append}-jinja2 ${pkg_append}-requests"
__PACKAGES="m2crypto ${pkg_append}-crypto ${pkg_append}-jinja2 ${pkg_append}-PyYAML"
__PACKAGES="${__PACKAGES} ${pkg_append}-msgpack ${pkg_append}-requests ${pkg_append}-zmq"
# shellcheck disable=SC2086
__yum_install_noinput ${__PACKAGES} || return 1
@ -4630,7 +4646,7 @@ install_arch_linux_git_deps() {
fi
pacman -R --noconfirm python2-distribute
pacman -Su --noconfirm --needed python2-crypto python2-setuptools python2-jinja \
python2-markupsafe python2-msgpack python2-psutil \
python2-m2crypto python2-markupsafe python2-msgpack python2-psutil \
python2-pyzmq zeromq python2-requests python2-systemd || return 1
__git_clone_and_checkout || return 1
@ -4704,7 +4720,7 @@ install_arch_linux_post() {
/usr/bin/systemctl preset salt-$fname.service > /dev/null 2>&1 &&
/usr/bin/systemctl enable salt-$fname.service > /dev/null 2>&1
)
sleep 0.1
sleep 1
/usr/bin/systemctl daemon-reload
continue
fi
@ -4732,7 +4748,7 @@ install_arch_linux_git_post() {
/usr/bin/systemctl preset salt-${fname}.service > /dev/null 2>&1 &&
/usr/bin/systemctl enable salt-${fname}.service > /dev/null 2>&1
)
sleep 0.1
sleep 1
/usr/bin/systemctl daemon-reload
continue
fi
@ -4885,9 +4901,9 @@ install_freebsd_9_stable_deps() {
__configure_freebsd_pkg_details || return 1
fi
# Now install swig
# Now install swig30
# shellcheck disable=SC2086
/usr/local/sbin/pkg install ${FROM_FREEBSD} -y swig || return 1
/usr/local/sbin/pkg install ${FROM_FREEBSD} -y swig30 || return 1
# YAML module is used for generating custom master/minion configs
# shellcheck disable=SC2086
@ -4934,7 +4950,7 @@ install_freebsd_git_deps() {
# We're on the develop branch, install whichever tornado is on the requirements file
__REQUIRED_TORNADO="$(grep tornado "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt")"
if [ "${__REQUIRED_TORNADO}" != "" ]; then
/usr/local/sbin/pkg install -y www/py-tornado || return 1
/usr/local/sbin/pkg install -y www/py-tornado4 || return 1
fi
fi
@ -5098,35 +5114,11 @@ install_freebsd_restart_daemons() {
# OpenBSD Install Functions
#
__choose_openbsd_mirror() {
OPENBSD_REPO=''
MINTIME=''
MIRROR_LIST=$(ftp -w 15 -Vao - 'https://ftp.openbsd.org/cgi-bin/ftplist.cgi?dbversion=1' | awk '/^http/ {print $1}')
for MIRROR in $MIRROR_LIST; do
MIRROR_HOST=$(echo "$MIRROR" | sed -e 's|.*//||' -e 's|+*/.*$||')
TIME=$(ping -c 1 -w 1 -q "$MIRROR_HOST" | awk -F/ '/round-trip/ { print $5 }')
[ -z "$TIME" ] && continue
echodebug "ping time for $MIRROR_HOST is $TIME"
if [ -z "$MINTIME" ]; then
FASTER_MIRROR=1
else
FASTER_MIRROR=$(echo "$TIME < $MINTIME" | bc)
fi
if [ "$FASTER_MIRROR" -eq 1 ]; then
MINTIME=$TIME
OPENBSD_REPO="$MIRROR"
fi
done
}
install_openbsd_deps() {
if [ $_DISABLE_REPOS -eq $BS_FALSE ]; then
__choose_openbsd_mirror || return 1
echoinfo "setting package repository to $OPENBSD_REPO with ping time of $MINTIME"
[ -n "$OPENBSD_REPO" ] || return 1
echo "${OPENBSD_REPO}" >>/etc/installurl || return 1
OPENBSD_REPO='https://cdn.openbsd.org/pub/OpenBSD'
echoinfo "setting package repository to $OPENBSD_REPO"
echo "${OPENBSD_REPO}" >/etc/installurl || return 1
fi
if [ "${_EXTRA_PACKAGES}" != "" ]; then
@ -5226,7 +5218,7 @@ install_openbsd_restart_daemons() {
# SmartOS Install Functions
#
install_smartos_deps() {
pkgin -y install zeromq py27-crypto py27-msgpack py27-yaml py27-jinja2 py27-zmq py27-requests || return 1
pkgin -y install zeromq py27-crypto py27-m2crypto py27-msgpack py27-yaml py27-jinja2 py27-zmq py27-requests || return 1
# Set _SALT_ETC_DIR to SmartOS default if they didn't specify
_SALT_ETC_DIR=${BS_SALT_ETC_DIR:-/opt/local/etc/salt}
@ -5456,6 +5448,13 @@ __version_lte() {
}
__zypper() {
# Check if any zypper process is running before calling zypper again.
# This is useful when a zypper call is part of a boot process and will
# wait until the zypper process is finished, such as on AWS AMIs.
while pgrep -l zypper; do
sleep 1
done
zypper --non-interactive "${@}"; return $?
}
@ -5515,7 +5514,7 @@ install_opensuse_stable_deps() {
}
install_opensuse_git_deps() {
if [ "$_INSECURE_DL" -eq $BS_FALSE ] && [ "${_SALT_REPO_URL%%://*}" = "https" ]; then
if [ "$_INSECURE_DL" -eq $BS_FALSE ] && [ "${_SALT_REPO_URL%%://*}" = "https" ] && ! __check_command_exists update-ca-certificates; then
__zypper_install ca-certificates || return 1
fi
@ -5529,7 +5528,7 @@ install_opensuse_git_deps() {
__git_clone_and_checkout || return 1
__PACKAGES="libzmq5 python-Jinja2 python-msgpack-python python-pycrypto python-pyzmq python-xml"
__PACKAGES="libzmq5 python-Jinja2 python-m2crypto python-msgpack-python python-pycrypto python-pyzmq python-xml"
if [ -f "${_SALT_GIT_CHECKOUT_DIR}/requirements/base.txt" ]; then
# We're on the develop branch, install whichever tornado is on the requirements file
@ -5594,7 +5593,7 @@ install_opensuse_stable_post() {
if [ -f /bin/systemctl ]; then
systemctl is-enabled salt-$fname.service || (systemctl preset salt-$fname.service && systemctl enable salt-$fname.service)
sleep 0.1
sleep 1
systemctl daemon-reload
continue
fi
@ -5723,6 +5722,12 @@ install_suse_12_stable_deps() {
# shellcheck disable=SC2086,SC2090
__zypper_install ${__PACKAGES} || return 1
# SLES 11 SP3 ships with both python-M2Crypto-0.22.* and python-m2crypto-0.21 and we will be asked which
# we want to install, even with --non-interactive.
# Let's try to install the higher version first and then the lower one in case of failure
__zypper_install 'python-M2Crypto>=0.22' || __zypper_install 'python-M2Crypto>=0.21' || return 1
if [ "${_EXTRA_PACKAGES}" != "" ]; then
echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}"
# shellcheck disable=SC2086
@ -5825,6 +5830,11 @@ install_suse_11_stable_deps() {
# shellcheck disable=SC2086,SC2090
__zypper_install ${__PACKAGES} || return 1
# SLES 11 SP3 ships with both python-M2Crypto-0.22.* and python-m2crypto-0.21 and we will be asked which
# we want to install, even with --non-interactive.
# Let's try to install the higher version first and then the lower one in case of failure
__zypper_install 'python-M2Crypto>=0.22' || __zypper_install 'python-M2Crypto>=0.21' || return 1
if [ "${_EXTRA_PACKAGES}" != "" ]; then
echoinfo "Installing the following extra packages as requested: ${_EXTRA_PACKAGES}"
# shellcheck disable=SC2086

View file

@ -88,6 +88,13 @@ In addition, other groups are being loaded from pillars.
:depends: slackclient
.. note:: groups_pillar_name
In order to use this, the engine must be running as a minion running on
the master, so that the ``Caller`` client can be used to retrieve that
minions pillar data, because the master process does not have pillars.
'''
# Import python libraries
@ -237,10 +244,8 @@ class SlackClient(object):
XXX: instead of using Caller, make the minion to use configurable so there could be some
restrictions placed on what pillars can be used.
'''
if pillar_name:
caller = salt.client.Caller()
pillar_groups = caller.cmd('pillar.get', pillar_name)
# pillar_groups = __salt__['pillar.get'](pillar_name, {})
if pillar_name and __opts__['__role'] == 'minion':
pillar_groups = __salt__['pillar.get'](pillar_name, {})
log.debug('Got pillar groups %s from pillar %s', pillar_groups, pillar_name)
log.debug('pillar groups is %s', pillar_groups)
log.debug('pillar groups type is %s', type(pillar_groups))

View file

@ -56,7 +56,7 @@ def inet_pton(address_family, ip_string):
addr_size = ctypes.c_int(ctypes.sizeof(addr))
if WSAStringToAddressA(
ip_string,
ip_string.encode('ascii'),
address_family,
None,
ctypes.byref(addr),

View file

@ -771,13 +771,6 @@ def _virtual(osdata):
grains['virtual'] = 'kvm'
# Break out of the loop so the next log message is not issued
break
elif command == 'virt-what':
# if 'virt-what' returns nothing, it's either an undetected platform
# so we default just as virt-what to 'physical', otherwise use the
# platform detected/returned by virt-what
if output:
grains['virtual'] = output.lower()
break
elif command == 'prtdiag':
model = output.lower().split("\n")[0]
if 'vmware' in model:

View file

@ -414,10 +414,10 @@ class FileserverUpdate(salt.utils.process.SignalHandlingMultiprocessingProcess):
interval = self.opts[interval_key]
except KeyError:
interval = DEFAULT_INTERVAL
log.error(
'%s key missing from master configuration. This is '
'a bug, please report it. Falling back to default '
'interval of %d seconds', interval_key, interval
log.warning(
'%s key missing from configuration. Falling back to '
'default interval of %d seconds',
interval_key, interval
)
self.buckets.setdefault(
interval, OrderedDict())[(backend, update_func)] = None

View file

@ -28,12 +28,15 @@ import salt.utils.stringutils
import salt.utils.vt
from salt.exceptions import SaltInvocationError, CommandExecutionError
# Import 3rd-party libs
# Import third-party libs
from salt.ext import six
from salt.ext.six.moves.urllib.parse import urlparse as _urlparse # pylint: disable=no-name-in-module,import-error
HAS_LIBS = False
SIGN_PROMPT_RE = re.compile(r'Enter passphrase: ', re.M)
REPREPRO_SIGN_PROMPT_RE = re.compile(r'Passphrase: ', re.M)
try:
import gnupg # pylint: disable=unused-import
import salt.modules.gpg
@ -61,7 +64,8 @@ def __virtual__():
if HAS_LIBS and not missing_util:
return __virtualname__
else:
return False, 'The debbuild module could not be loaded: requires python-gnupg, gpg, debuild, pbuilder and reprepro utilities to be installed'
return False, ('The debbuild module could not be loaded: requires python-gnupg, gpg, debuild, '
'pbuilder and reprepro utilities to be installed')
else:
return (False, 'The debbuild module could not be loaded: unsupported OS family')
@ -78,7 +82,7 @@ def _check_repo_sign_utils_support(name):
)
def _check_repo_gpg_phrase_utils_support():
def _check_repo_gpg_phrase_utils():
'''
Check for /usr/lib/gnupg2/gpg-preset-passphrase is installed
'''
@ -270,7 +274,7 @@ def _mk_tree():
return basedir
def _get_spec(tree_base, spec, template, saltenv='base'):
def _get_spec(tree_base, spec, saltenv='base'):
'''
Get the spec file (tarball of the debian sub-dir to use)
and place it in build area
@ -294,7 +298,7 @@ def _get_src(tree_base, source, saltenv='base'):
shutil.copy(source, dest)
def make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv='base'):
def make_src_pkg(dest_dir, spec, sources, env=None, saltenv='base'):
'''
Create a platform specific source package from the given platform spec/control file and sources
@ -304,7 +308,9 @@ def make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv='base
.. code-block:: bash
salt '*' pkgbuild.make_src_pkg /var/www/html/ https://raw.githubusercontent.com/saltstack/libnacl/master/pkg/deb/python-libnacl.control.tar.xz https://pypi.python.org/packages/source/l/libnacl/libnacl-1.3.5.tar.gz
salt '*' pkgbuild.make_src_pkg /var/www/html/
https://raw.githubusercontent.com/saltstack/libnacl/master/pkg/deb/python-libnacl.control.tar.xz
https://pypi.python.org/packages/source/l/libnacl/libnacl-1.3.5.tar.gz
This example command should build the libnacl SOURCE package and place it in
/var/www/html/ on the minion
@ -315,7 +321,7 @@ def make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv='base
if not os.path.isdir(dest_dir):
os.makedirs(dest_dir)
spec_pathfile = _get_spec(tree_base, spec, template, saltenv)
spec_pathfile = _get_spec(tree_base, spec, saltenv)
# build salt equivalents from scratch
if isinstance(sources, six.string_types):
@ -350,26 +356,36 @@ def make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv='base
debname += '+ds'
debname_orig = debname + '.orig.tar.gz'
abspath_debname = os.path.join(tree_base, debname)
retrc = 0
cmd = 'tar -xvzf {0}'.format(salttarball)
__salt__['cmd.run'](cmd, cwd=tree_base)
retrc = __salt__['cmd.retcode'](cmd, cwd=tree_base)
cmd = 'mv {0} {1}'.format(salttar_name, debname)
__salt__['cmd.run'](cmd, cwd=tree_base)
retrc |= __salt__['cmd.retcode'](cmd, cwd=tree_base)
cmd = 'tar -cvzf {0} {1}'.format(os.path.join(tree_base, debname_orig), debname)
__salt__['cmd.run'](cmd, cwd=tree_base)
retrc |= __salt__['cmd.retcode'](cmd, cwd=tree_base)
cmd = 'rm -f {0}'.format(salttarball)
__salt__['cmd.run'](cmd, cwd=tree_base)
retrc |= __salt__['cmd.retcode'](cmd, cwd=tree_base, env=env)
cmd = 'cp {0} {1}'.format(spec_pathfile, abspath_debname)
__salt__['cmd.run'](cmd, cwd=abspath_debname)
retrc |= __salt__['cmd.retcode'](cmd, cwd=abspath_debname)
cmd = 'tar -xvJf {0}'.format(spec_pathfile)
__salt__['cmd.run'](cmd, cwd=abspath_debname)
retrc |= __salt__['cmd.retcode'](cmd, cwd=abspath_debname, env=env)
cmd = 'rm -f {0}'.format(os.path.basename(spec_pathfile))
__salt__['cmd.run'](cmd, cwd=abspath_debname)
retrc |= __salt__['cmd.retcode'](cmd, cwd=abspath_debname)
cmd = 'debuild -S -uc -us -sa'
__salt__['cmd.run'](cmd, cwd=abspath_debname, python_shell=True)
retrc |= __salt__['cmd.retcode'](cmd, cwd=abspath_debname, python_shell=True, env=env)
cmd = 'rm -fR {0}'.format(abspath_debname)
__salt__['cmd.run'](cmd)
retrc |= __salt__['cmd.retcode'](cmd)
if retrc != 0:
raise SaltInvocationError(
'Make source package for destination directory {0}, spec {1}, sources {2}, failed '
'with return error {3}, check logs for further details'.format(
dest_dir,
spec,
sources,
retrc)
)
for dfile in os.listdir(tree_base):
if not dfile.endswith('.build'):
@ -401,12 +417,15 @@ def build(runas,
.. code-block:: bash
salt '*' pkgbuild.make_src_pkg deb-8-x86_64 /var/www/html https://raw.githubusercontent.com/saltstack/libnacl/master/pkg/deb/python-libnacl.control https://pypi.python.org/packages/source/l/libnacl/libnacl-1.3.5.tar.gz
salt '*' pkgbuild.make_src_pkg deb-8-x86_64 /var/www/html
https://raw.githubusercontent.com/saltstack/libnacl/master/pkg/deb/python-libnacl.control
https://pypi.python.org/packages/source/l/libnacl/libnacl-1.3.5.tar.gz
This example command should build the libnacl package for Debian using pbuilder
and place it in /var/www/html/ on the minion
'''
ret = {}
retrc = 0
try:
os.makedirs(dest_dir)
except OSError as exc:
@ -414,36 +433,45 @@ def build(runas,
raise
dsc_dir = tempfile.mkdtemp()
try:
dscs = make_src_pkg(dsc_dir, spec, sources, env, template, saltenv)
dscs = make_src_pkg(dsc_dir, spec, sources, env, saltenv)
except Exception as exc:
shutil.rmtree(dsc_dir)
log.error('Failed to make src package')
return ret
cmd = 'pbuilder --create'
__salt__['cmd.run'](cmd, runas=runas, python_shell=True)
retrc = __salt__['cmd.retcode'](cmd, runas=runas, python_shell=True, env=env)
if retrc != 0:
raise SaltInvocationError(
'pbuilder create failed with return error {0}, check logs for further details'.format(retrc))
# use default /var/cache/pbuilder/result
results_dir = '/var/cache/pbuilder/result'
## ensure clean
__salt__['cmd.run']('rm -fR {0}'.format(results_dir))
# ensure clean
retrc |= __salt__['cmd.retcode']('rm -fR {0}'.format(results_dir))
# dscs should only contain salt orig and debian tarballs and dsc file
for dsc in dscs:
afile = os.path.basename(dsc)
adist = os.path.join(dest_dir, afile)
os.path.join(dest_dir, afile)
if dsc.endswith('.dsc'):
dbase = os.path.dirname(dsc)
try:
__salt__['cmd.run']('chown {0} -R {1}'.format(runas, dbase))
retrc |= __salt__['cmd.retcode']('chown {0} -R {1}'.format(runas, dbase))
cmd = 'pbuilder update --override-config'
__salt__['cmd.run'](cmd, runas=runas, python_shell=True)
retrc |= __salt__['cmd.retcode'](cmd, runas=runas, python_shell=True, env=env)
cmd = 'pbuilder build --debbuildopts "-sa" {0}'.format(dsc)
__salt__['cmd.run'](cmd, runas=runas, python_shell=True)
retrc |= __salt__['cmd.retcode'](cmd, runas=runas, python_shell=True, env=env)
if retrc != 0:
raise SaltInvocationError(
'pbuilder build or update failed with return error {0}, '
'check logs for further details'.format(retrc)
)
# ignore local deps generated package file
for bfile in os.listdir(results_dir):
@ -487,44 +515,20 @@ def make_repo(repodir,
.. versionchanged:: 2016.3.0
Optional Key ID to use in signing packages and repository.
This consists of the last 8 hex digits of the GPG key ID.
Utilizes Public and Private keys associated with keyid which have
been loaded into the minion's Pillar data. Leverages gpg-agent and
gpg-preset-passphrase for caching keys, etc.
These pillar values are assumed to be filenames which are present
in ``gnupghome``. The pillar keys shown below have to match exactly.
For example, contents from a Pillar data file with named Public
and Private keys as follows:
.. code-block:: yaml
gpg_pkg_priv_key: |
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1
lQO+BFciIfQBCADAPCtzx7I5Rl32escCMZsPzaEKWe7bIX1em4KCKkBoX47IG54b
w82PCE8Y1jF/9Uk2m3RKVWp3YcLlc7Ap3gj6VO4ysvVz28UbnhPxsIkOlf2cq8qc
.
.
Ebe+8JCQTwqSXPRTzXmy/b5WXDeM79CkLWvuGpXFor76D+ECMRPv/rawukEcNptn
R5OmgHqvydEnO4pWbn8JzQO9YX/Us0SMHBVzLC8eIi5ZIopzalvX
=JvW8
-----END PGP PRIVATE KEY BLOCK-----
gpg_pkg_priv_keyname: gpg_pkg_key.pem
gpg_pkg_pub_key: |
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
mQENBFciIfQBCADAPCtzx7I5Rl32escCMZsPzaEKWe7bIX1em4KCKkBoX47IG54b
w82PCE8Y1jF/9Uk2m3RKVWp3YcLlc7Ap3gj6VO4ysvVz28UbnhPxsIkOlf2cq8qc
.
.
bYP7t5iwJmQzRMyFInYRt77wkJBPCpJc9FPNebL9vlZcN4zv0KQta+4alcWivvoP
4QIxE+/+trC6QRw2m2dHk6aAeq/J0Sc7ilZufwnNA71hf9SzRIwcFXMsLx4iLlki
inNqW9c=
=s1CX
-----END PGP PUBLIC KEY BLOCK-----
gpg_pkg_pub_keyname: gpg_pkg_key.pub
env
@ -571,12 +575,17 @@ def make_repo(repodir,
salt '*' pkgbuild.make_repo /var/www/html
'''
res = {'retcode': 1,
res = {
'retcode': 1,
'stdout': '',
'stderr': 'initialization value'}
'stderr': 'initialization value'
}
SIGN_PROMPT_RE = re.compile(r'Enter passphrase: ', re.M)
REPREPRO_SIGN_PROMPT_RE = re.compile(r'Passphrase: ', re.M)
retrc = 0
if gnupghome and env is None:
env = {}
env['GNUPGHOME'] = gnupghome
repoconf = os.path.join(repodir, 'conf')
if not os.path.isdir(repoconf):
@ -600,7 +609,6 @@ def make_repo(repodir,
# preset passphase and interaction with gpg-agent
gpg_info_file = '{0}/gpg-agent-info-salt'.format(gnupghome)
gpg_tty_info_file = '{0}/gpg-tty-info-salt'.format(gnupghome)
gpg_tty_info_dict = {}
# if using older than gnupg 2.1, then env file exists
older_gnupg = __salt__['file.file_exists'](gpg_info_file)
@ -639,9 +647,13 @@ def make_repo(repodir,
break
if not older_gnupg:
_check_repo_sign_utils_support('gpg2')
cmd = '{0} --with-keygrip --list-secret-keys'.format(salt.utils.path.which('gpg2'))
local_keys2_keygrip = __salt__['cmd.run'](cmd, runas=runas)
try:
_check_repo_sign_utils_support('gpg2')
cmd = 'gpg2 --with-keygrip --list-secret-keys'
except CommandExecutionError:
# later gpg versions have dispensed with gpg2 - Ubuntu 18.04
cmd = 'gpg --with-keygrip --list-secret-keys'
local_keys2_keygrip = __salt__['cmd.run'](cmd, runas=runas, env=env)
local_keys2 = iter(local_keys2_keygrip.splitlines())
try:
for line in local_keys2:
@ -672,25 +684,25 @@ def make_repo(repodir,
for gpg_info_line in gpg_raw_info:
gpg_info_line = salt.utils.stringutils.to_unicode(gpg_info_line)
gpg_info = gpg_info_line.split('=')
gpg_info_dict = {gpg_info[0]: gpg_info[1]}
__salt__['environ.setenv'](gpg_info_dict)
env[gpg_info[0]] = gpg_info[1]
break
else:
with salt.utils.files.fopen(gpg_tty_info_file, 'r') as fow:
gpg_raw_info = fow.readlines()
for gpg_tty_info_line in gpg_raw_info:
gpg_info_line = salt.utils.stringutils.to_unicode(gpg_info_line)
gpg_tty_info_line = salt.utils.stringutils.to_unicode(gpg_tty_info_line)
gpg_tty_info = gpg_tty_info_line.split('=')
gpg_tty_info_dict = {gpg_tty_info[0]: gpg_tty_info[1]}
__salt__['environ.setenv'](gpg_tty_info_dict)
env[gpg_tty_info[0]] = gpg_tty_info[1]
break
if use_passphrase:
_check_repo_gpg_phrase_utils_support()
_check_repo_gpg_phrase_utils()
phrase = __salt__['pillar.get']('gpg_passphrase')
cmd = '/usr/lib/gnupg2/gpg-preset-passphrase --verbose --preset --passphrase "{0}" {1}'.format(phrase, local_keygrip_to_use)
__salt__['cmd.run'](cmd, runas=runas)
cmd = '/usr/lib/gnupg2/gpg-preset-passphrase --verbose --preset --passphrase "{0}" {1}'.format(
phrase,
local_keygrip_to_use)
retrc |= __salt__['cmd.retcode'](cmd, runas=runas, env=env)
for debfile in os.listdir(repodir):
abs_file = os.path.join(repodir, debfile)
@ -702,10 +714,12 @@ def make_repo(repodir,
if older_gnupg:
if local_keyid is not None:
cmd = 'debsign --re-sign -k {0} {1}'.format(keyid, abs_file)
__salt__['cmd.run'](cmd, cwd=repodir, use_vt=True)
retrc |= __salt__['cmd.retcode'](cmd, cwd=repodir, use_vt=True, env=env)
cmd = 'reprepro --ignore=wrongdistribution --component=main -Vb . includedsc {0} {1}'.format(codename, abs_file)
__salt__['cmd.run'](cmd, cwd=repodir, use_vt=True)
cmd = 'reprepro --ignore=wrongdistribution --component=main -Vb . includedsc {0} {1}'.format(
codename,
abs_file)
retrc |= __salt__['cmd.retcode'](cmd, cwd=repodir, use_vt=True, env=env)
else:
# interval of 0.125 is really too fast on some systems
interval = 0.5
@ -715,15 +729,15 @@ def make_repo(repodir,
error_msg = 'Failed to debsign file {0}'.format(abs_file)
cmd = 'debsign --re-sign -k {0} {1}'.format(keyid, abs_file)
try:
stdout, stderr = None, None
proc = salt.utils.vt.Terminal(
cmd,
env=env,
shell=True,
stream_stdout=True,
stream_stderr=True
)
while proc.has_unread_data:
stdout, stderr = proc.recv()
stdout, _ = proc.recv()
if stdout and SIGN_PROMPT_RE.search(stdout):
# have the prompt for inputting the passphrase
proc.sendline(phrase)
@ -732,21 +746,24 @@ def make_repo(repodir,
if times_looped > number_retries:
raise SaltInvocationError(
'Attempting to sign file {0} failed, timed out after {1} seconds'
.format(abs_file, int(times_looped * interval))
'Attempting to sign file {0} failed, timed out after {1} seconds'.format(
abs_file,
int(times_looped * interval))
)
time.sleep(interval)
proc_exitstatus = proc.exitstatus
if proc_exitstatus != 0:
raise SaltInvocationError(
'Signing file {0} failed with proc.status {1}'
.format(abs_file, proc_exitstatus)
'Signing file {0} failed with proc.status {1}'.format(
abs_file,
proc_exitstatus)
)
except salt.utils.vt.TerminalException as err:
trace = traceback.format_exc()
log.error(error_msg, err, trace)
res = {'retcode': 1,
res = {
'retcode': 1,
'stdout': '',
'stderr': trace}
finally:
@ -755,19 +772,21 @@ def make_repo(repodir,
number_retries = timeout / interval
times_looped = 0
error_msg = 'Failed to reprepro includedsc file {0}'.format(abs_file)
cmd = 'reprepro --ignore=wrongdistribution --component=main -Vb . includedsc {0} {1}'.format(codename, abs_file)
cmd = 'reprepro --ignore=wrongdistribution --component=main -Vb . includedsc {0} {1}'.format(
codename,
abs_file)
try:
stdout, stderr = None, None
proc = salt.utils.vt.Terminal(
cmd,
env=env,
shell=True,
cwd=repodir,
env=gpg_tty_info_dict,
stream_stdout=True,
stream_stderr=True
)
while proc.has_unread_data:
stdout, stderr = proc.recv()
stdout, _ = proc.recv()
if stdout and REPREPRO_SIGN_PROMPT_RE.search(stdout):
# have the prompt for inputting the passphrase
proc.sendline(phrase)
@ -776,26 +795,38 @@ def make_repo(repodir,
if times_looped > number_retries:
raise SaltInvocationError(
'Attempting to reprepro includedsc for file {0} failed, timed out after {1} loops'.format(abs_file, times_looped)
'Attempting to reprepro includedsc for file {0} failed, timed out after {1} loops'
.format(abs_file, times_looped)
)
time.sleep(interval)
proc_exitstatus = proc.exitstatus
if proc_exitstatus != 0:
raise SaltInvocationError(
'Reprepro includedsc for codename {0} and file {1} failed with proc.status {2}'.format(codename, abs_file, proc_exitstatus)
)
'Reprepro includedsc for codename {0} and file {1} failed with proc.status {2}'.format(
codename,
abs_file,
proc_exitstatus)
)
except salt.utils.vt.TerminalException as err:
trace = traceback.format_exc()
log.error(error_msg, err, trace)
res = {'retcode': 1,
res = {
'retcode': 1,
'stdout': '',
'stderr': trace}
'stderr': trace
}
finally:
proc.close(terminate=True, kill=True)
if retrc != 0:
raise SaltInvocationError(
'Making a repo encountered errors, return error {0}, check logs for further details'.format(retrc))
if debfile.endswith('.deb'):
cmd = 'reprepro --ignore=wrongdistribution --component=main -Vb . includedeb {0} {1}'.format(codename, abs_file)
res = __salt__['cmd.run_all'](cmd, cwd=repodir, use_vt=True)
cmd = 'reprepro --ignore=wrongdistribution --component=main -Vb . includedeb {0} {1}'.format(
codename,
abs_file)
res = __salt__['cmd.run_all'](cmd, cwd=repodir, use_vt=True, env=env)
return res

View file

@ -4982,7 +4982,7 @@ def get_diff(file1,
)
args = []
for idx, filename in enumerate(files):
for filename in files:
try:
with salt.utils.files.fopen(filename, 'rb') as fp_:
args.append(fp_.readlines())
@ -5011,7 +5011,8 @@ def get_diff(file1,
*salt.utils.data.decode(args)
)
)
return ret
return ret
return ''
def manage_file(name,

View file

@ -213,6 +213,14 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
To pass in jump options that doesn't take arguments, pass in an empty
string.
.. note::
Whereas iptables will accept ``-p``, ``--proto[c[o[l]]]`` as synonyms
of ``--protocol``, if ``--proto`` appears in an iptables command after
the appearance of ``-m policy``, it is interpreted as the ``--proto``
option of the policy extension (see the iptables-extensions(8) man
page).
CLI Examples:
.. code-block:: bash
@ -243,7 +251,6 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
salt '*' iptables.build_rule filter INPUT command=I position=3 \\
full=True match=state connstate=RELATED,ESTABLISHED jump=ACCEPT \\
family=ipv6
'''
if 'target' in kwargs:
kwargs['jump'] = kwargs.pop('target')
@ -257,7 +264,7 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
del kwargs[ignore]
rule = []
proto = False
protocol = False
bang_not_pat = re.compile(r'(!|not)\s?')
def maybe_add_negation(arg):
@ -281,12 +288,15 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
rule.append('{0}-o {1}'.format(maybe_add_negation('of'), kwargs['of']))
del kwargs['of']
for proto_arg in ('protocol', 'proto'):
if proto_arg in kwargs:
if not proto:
rule.append('{0}-p {1}'.format(maybe_add_negation(proto_arg), kwargs[proto_arg]))
proto = True
del kwargs[proto_arg]
if 'proto' in kwargs and kwargs.get('match') != 'policy':
kwargs['protocol'] = kwargs['proto']
del kwargs['proto']
# Handle the case 'proto' in kwargs and kwargs.get('match') == 'policy' below
if 'protocol' in kwargs:
if not protocol:
rule.append('{0}-p {1}'.format(maybe_add_negation('protocol'), kwargs['protocol']))
protocol = True
del kwargs['protocol']
if 'match' in kwargs:
match_value = kwargs['match']
@ -297,6 +307,9 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
if 'name_' in kwargs and match.strip() in ('pknock', 'quota2', 'recent'):
rule.append('--name {0}'.format(kwargs['name_']))
del kwargs['name_']
if 'proto' in kwargs and kwargs.get('match') == 'policy':
rule.append('{0}--proto {1}'.format(maybe_add_negation('proto'), kwargs['proto']))
del kwargs['proto']
del kwargs['match']
if 'match-set' in kwargs:
@ -330,8 +343,8 @@ def build_rule(table='filter', chain=None, command=None, position='', full=None,
if multiport_arg in kwargs:
if '-m multiport' not in rule:
rule.append('-m multiport')
if not proto:
return 'Error: proto must be specified'
if not protocol:
return 'Error: protocol must be specified'
mp_value = kwargs[multiport_arg]
if isinstance(mp_value, list):
@ -1042,9 +1055,9 @@ def _parse_conf(conf_file=None, in_mem=False, family='ipv4'):
def _parser():
'''
This function contains _all_ the options I could find in man 8 iptables,
listed in the first section that I found them in. They will not all be used
by all parts of the module; use them intelligently and appropriately.
This function attempts to list all the options documented in the
iptables(8) and iptables-extensions(8) man pages. They will not all be
used by all parts of the module; use them intelligently and appropriately.
'''
add_arg = None
if sys.version.startswith('2.6'):

View file

@ -1,14 +1,15 @@
# -*- coding: utf-8 -*-
'''
r'''
Manage the Windows registry
-----
Hives
-----
Hives are the main sections of the registry and all begin with the word HKEY.
- HKEY_LOCAL_MACHINE
- HKEY_CURRENT_USER
- HKEY_USER
- HKEY_LOCAL_MACHINE
- HKEY_CURRENT_USER
- HKEY_USER
----
Keys
@ -19,10 +20,41 @@ can have a value assigned to them under the (Default)
-----------------
Values or Entries
-----------------
Values/Entries are name/data pairs. There can be many values in a key. The
(Default) value corresponds to the Key, the rest are their own value pairs.
:depends: - PyWin32
Values or Entries are the name/data pairs beneath the keys and subkeys. All keys
have a default name/data pair. The name is ``(Default)`` with a displayed value
of ``(value not set)``. The actual value is Null.
-------
Example
-------
The following example is an export from the Windows startup portion of the
registry:
.. code-block:: bash
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
"RTHDVCPL"="\"C:\\Program Files\\Realtek\\Audio\\HDA\\RtkNGUI64.exe\" -s"
"NvBackend"="\"C:\\Program Files (x86)\\NVIDIA Corporation\\Update Core\\NvBackend.exe\""
"BTMTrayAgent"="rundll32.exe \"C:\\Program Files (x86)\\Intel\\Bluetooth\\btmshellex.dll\",TrayApp"
In this example these are the values for each:
Hive:
``HKEY_LOCAL_MACHINE``
Key and subkeys:
``SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run``
Value:
- There are 3 value names:
- `RTHDVCPL`
- `NvBackend`
- `BTMTrayAgent`
- Each value name has a corresponding value
:depends: - salt.utils.win_reg
'''
# When production windows installer is using Python 3, Python 2 code can be removed
from __future__ import absolute_import, print_function, unicode_literals
@ -42,7 +74,7 @@ __virtualname__ = 'reg'
def __virtual__():
'''
Only works on Windows systems with the PyWin32
Only works on Windows systems with PyWin32
'''
if not salt.utils.platform.is_windows():
return (False, 'reg execution module failed to load: '
@ -56,16 +88,26 @@ def __virtual__():
def key_exists(hive, key, use_32bit_registry=False):
'''
r'''
Check that the key is found in the registry. This refers to keys and not
value/data pairs.
:param str hive: The hive to connect to.
:param str key: The key to check
:param bool use_32bit_registry: Look in the 32bit portion of the registry
Args:
:return: Returns True if found, False if not found
:rtype: bool
hive (str): The hive to connect to
key (str): The key to check
use_32bit_registry (bool): Look in the 32bit portion of the registry
Returns:
bool: True if exists, otherwise False
CLI Example:
.. code-block:: bash
salt '*' reg.key_exists HKLM SOFTWARE\Microsoft
'''
return __utils__['reg.key_exists'](hive=hive,
key=key,
@ -76,13 +118,18 @@ def broadcast_change():
'''
Refresh the windows environment.
Returns (bool): True if successful, otherwise False
.. note::
This will only effect new processes and windows. Services will not see
the change until the system restarts.
Returns:
bool: True if successful, otherwise False
CLI Example:
.. code-block:: bash
.. code-block:: bash
salt '*' reg.broadcast_change
salt '*' reg.broadcast_change
'''
return salt.utils.win_functions.broadcast_setting_change('Environment')
@ -91,28 +138,33 @@ def list_keys(hive, key=None, use_32bit_registry=False):
'''
Enumerates the subkeys in a registry key or hive.
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following:
:param str key: The key (looks like a path) to the value name. If a key is
not passed, the keys under the hive will be returned.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64 bit installations. On 32bit machines this is ignored.
key (str):
The key (looks like a path) to the value name. If a key is not
passed, the keys under the hive will be returned.
:return: A list of keys/subkeys under the hive or key.
:rtype: list
use_32bit_registry (bool):
Accesses the 32bit portion of the registry on 64 bit installations.
On 32bit machines this is ignored.
Returns:
list: A list of keys/subkeys under the hive or key.
CLI Example:
.. code-block:: bash
.. code-block:: bash
salt '*' reg.list_keys HKLM 'SOFTWARE'
salt '*' reg.list_keys HKLM 'SOFTWARE'
'''
return __utils__['reg.list_keys'](hive=hive,
key=key,
@ -123,30 +175,36 @@ def list_values(hive, key=None, use_32bit_registry=False, include_default=True):
'''
Enumerates the values in a registry key or hive.
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following:
:param str key: The key (looks like a path) to the value name. If a key is
not passed, the values under the hive will be returned.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64 bit installations. On 32bit machines this is ignored.
key (str):
The key (looks like a path) to the value name. If a key is not
passed, the values under the hive will be returned.
:param bool include_default: Toggle whether to include the '(Default)' value.
use_32bit_registry (bool):
Accesses the 32bit portion of the registry on 64 bit installations.
On 32bit machines this is ignored.
:return: A list of values under the hive or key.
:rtype: list
include_default (bool):
Toggle whether to include the '(Default)' value.
Returns:
list: A list of values under the hive or key.
CLI Example:
.. code-block:: bash
.. code-block:: bash
salt '*' reg.list_values HKLM 'SYSTEM\\CurrentControlSet\\Services\\Tcpip'
salt '*' reg.list_values HKLM 'SYSTEM\\CurrentControlSet\\Services\\Tcpip'
'''
return __utils__['reg.list_values'](hive=hive,
key=key,
@ -156,40 +214,58 @@ def list_values(hive, key=None, use_32bit_registry=False, include_default=True):
def read_value(hive, key, vname=None, use_32bit_registry=False):
r'''
Reads a registry value entry or the default value for a key.
Reads a registry value entry or the default value for a key. To read the
default value, don't pass ``vname``
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str): The name of the hive. Can be one of the following:
:param str key: The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be returned
key (str):
The key (looks like a path) to the value name.
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64bit installations. On 32bit machines this is ignored.
vname (str):
The value name. These are the individual name/data pairs under the
key. If not passed, the key (Default) value will be returned.
:return: A dictionary containing the passed settings as well as the
value_data if successful. If unsuccessful, sets success to False.
use_32bit_registry (bool):
Accesses the 32bit portion of the registry on 64bit installations.
On 32bit machines this is ignored.
:rtype: dict
Returns:
dict: A dictionary containing the passed settings as well as the
value_data if successful. If unsuccessful, sets success to False.
If vname is not passed:
bool: Returns False if the key is not found
- Returns the first unnamed value (Default) as a string.
- Returns none if first unnamed value is empty.
- Returns False if key not found.
If vname is not passed:
- Returns the first unnamed value (Default) as a string.
- Returns none if first unnamed value is empty.
CLI Example:
.. code-block:: bash
The following will get the value of the ``version`` value name in the
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt`` key
salt '*' reg.read_value HKEY_LOCAL_MACHINE 'SOFTWARE\Salt' 'version'
.. code-block:: bash
salt '*' reg.read_value HKEY_LOCAL_MACHINE 'SOFTWARE\Salt' 'version'
CLI Example:
The following will get the default value of the
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt`` key
.. code-block:: bash
salt '*' reg.read_value HKEY_LOCAL_MACHINE 'SOFTWARE\Salt'
'''
return __utils__['reg.read_value'](hive=hive,
key=key,
@ -205,98 +281,114 @@ def set_value(hive,
use_32bit_registry=False,
volatile=False):
'''
Sets a registry value entry or the default value for a key.
Sets a value in the registry. If ``vname`` is passed, it will be the value
for that value name, otherwise it will be the default value for the
specified key
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following
:param str key: The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be set.
key (str):
The key (looks like a path) to the value name.
:param object vdata: The value data to be set.
What the type of this parameter
should be is determined by the value of the vtype
parameter. The correspondence
is as follows:
vname (str):
The value name. These are the individual name/data pairs under the
key. If not passed, the key (Default) value will be set.
.. glossary::
vdata (str, int, list, bytes):
The value you'd like to set. If a value name (vname) is passed, this
will be the data for that value name. If not, this will be the
(Default) value for the key.
REG_BINARY
binary data (i.e. str in python version < 3 and bytes in version >=3)
REG_DWORD
int
REG_EXPAND_SZ
str
REG_MULTI_SZ
list of objects of type str
REG_SZ
str
The type of data this parameter expects is determined by the value
type specified in ``vtype``. The correspondence is as follows:
:param str vtype: The value type.
The possible values of the vtype parameter are indicated
above in the description of the vdata parameter.
- REG_BINARY: Binary data (str in Py2, bytes in Py3)
- REG_DWORD: int
- REG_EXPAND_SZ: str
- REG_MULTI_SZ: list of str
- REG_QWORD: int
- REG_SZ: str
:param bool use_32bit_registry: Sets the 32bit portion of the registry on
64bit installations. On 32bit machines this is ignored.
.. note::
When setting REG_BINARY, string data will be converted to
binary.
:param bool volatile: When this parameter has a value of True, the registry key will be
made volatile (i.e. it will not persist beyond a system reset or shutdown).
This parameter only has an effect when a key is being created and at no
other time.
.. note::
The type for the (Default) value is always REG_SZ and cannot be
changed.
:return: Returns True if successful, False if not
:rtype: bool
.. note::
This parameter is optional. If ``vdata`` is not passed, the Key
will be created with no associated item/value pairs.
vtype (str):
The value type. The possible values of the vtype parameter are
indicated above in the description of the vdata parameter.
use_32bit_registry (bool):
Sets the 32bit portion of the registry on 64bit installations. On
32bit machines this is ignored.
volatile (bool):
When this parameter has a value of True, the registry key will be
made volatile (i.e. it will not persist beyond a system reset or
shutdown). This parameter only has an effect when a key is being
created and at no other time.
Returns:
bool: True if successful, otherwise False
CLI Example:
.. code-block:: bash
This will set the version value to 2015.5.2 in the SOFTWARE\\Salt key in
the HKEY_LOCAL_MACHINE hive
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2'
.. code-block:: bash
This function is strict about the type of vdata. For instance the
the next example will fail because vtype has a value of REG_SZ and vdata
has a type of int (as opposed to str as expected).
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2'
CLI Example:
.. code-block:: bash
This function is strict about the type of vdata. For instance this
example will fail because vtype has a value of REG_SZ and vdata has a
type of int (as opposed to str as expected).
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_SZ vdata=0
.. code-block:: bash
However, this next example where vdata is properly quoted should succeed.
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'str_data' 1.2
CLI Example:
.. code-block:: bash
In this next example vdata is properly quoted and should succeed.
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_SZ vdata="'0'"
.. code-block:: bash
An example of using vtype REG_BINARY is as follows:
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'str_data' vtype=REG_SZ vdata="'1.2'"
CLI Example:
.. code-block:: bash
This is an example of using vtype REG_BINARY.
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_BINARY vdata='!!binary d2hhdCdzIHRoZSBwb2ludA=='
.. code-block:: bash
An example of using vtype REG_LIST is as follows:
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'bin_data' vtype=REG_BINARY vdata='Salty Data'
CLI Example:
.. code-block:: bash
An example of using vtype REG_MULTI_SZ is as follows:
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_LIST vdata='[a,b,c]'
.. code-block:: bash
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'list_data' vtype=REG_MULTI_SZ vdata='["Salt", "is", "great"]'
'''
return __utils__['reg.set_value'](hive=hive,
key=key,
@ -311,33 +403,38 @@ def delete_key_recursive(hive, key, use_32bit_registry=False):
'''
.. versionadded:: 2015.5.4
Delete a registry key to include all subkeys.
Delete a registry key to include all subkeys and value/data pairs.
:param hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following
:param key: The key to remove (looks like a path)
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param bool use_32bit_registry: Deletes the 32bit portion of the registry on
64bit installations. On 32bit machines this is ignored.
key (str):
The key to remove (looks like a path)
:return: A dictionary listing the keys that deleted successfully as well as
those that failed to delete.
:rtype: dict
use_32bit_registry (bool):
Deletes the 32bit portion of the registry on 64bit
installations. On 32bit machines this is ignored.
The following example will remove ``salt`` and all its subkeys from the
``SOFTWARE`` key in ``HKEY_LOCAL_MACHINE``:
Returns:
dict: A dictionary listing the keys that deleted successfully as well as
those that failed to delete.
CLI Example:
.. code-block:: bash
The following example will remove ``delete_me`` and all its subkeys from the
``SOFTWARE`` key in ``HKEY_LOCAL_MACHINE``:
salt '*' reg.delete_key_recursive HKLM SOFTWARE\\salt
.. code-block:: bash
salt '*' reg.delete_key_recursive HKLM SOFTWARE\\delete_me
'''
return __utils__['reg.delete_key_recursive'](hive=hive,
key=key,
@ -348,30 +445,36 @@ def delete_value(hive, key, vname=None, use_32bit_registry=False):
'''
Delete a registry value entry or the default value for a key.
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following
:param str key: The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be deleted.
key (str):
The key (looks like a path) to the value name.
:param bool use_32bit_registry: Deletes the 32bit portion of the registry on
64bit installations. On 32bit machines this is ignored.
vname (str):
The value name. These are the individual name/data pairs under the
key. If not passed, the key (Default) value will be deleted.
:return: Returns True if successful, False if not
:rtype: bool
use_32bit_registry (bool):
Deletes the 32bit portion of the registry on 64bit installations. On
32bit machines this is ignored.
Return:
bool: True if successful, otherwise False
CLI Example:
.. code-block:: bash
.. code-block:: bash
salt '*' reg.delete_value HKEY_CURRENT_USER 'SOFTWARE\\Salt' 'version'
salt '*' reg.delete_value HKEY_CURRENT_USER 'SOFTWARE\\Salt' 'version'
'''
return __utils__['reg.delete_value'](hive=hive,
key=key,
@ -385,32 +488,30 @@ def import_file(source, use_32bit_registry=False):
.. versionadded:: 2018.3.0
Usage:
Args:
source (str):
The full path of the ``REG`` file. This can be either a local file
path or a URL type supported by salt (e.g. ``salt://salt_master_path``)
use_32bit_registry (bool):
If the value of this parameter is ``True`` then the ``REG`` file
will be imported into the Windows 32 bit registry. Otherwise the
Windows 64 bit registry will be used.
Returns:
bool: True if successful, otherwise an error is raised
Raises:
ValueError: If the value of ``source`` is an invalid path or otherwise
causes ``cp.cache_file`` to return ``False``
CommandExecutionError: If ``reg.exe`` exits with a non-0 exit code
CLI Example:
.. code-block:: bash
.. code-block:: bash
salt machine1 reg.import_file salt://win/printer_config/110_Canon/postinstall_config.reg
:param str source: The full path of the ``REG`` file. This
can be either a local file path or a URL type supported by salt
(e.g. ``salt://salt_master_path``).
:param bool use_32bit_registry: If the value of this parameter is ``True``
then the ``REG`` file will be imported into the Windows 32 bit registry.
Otherwise the Windows 64 bit registry will be used.
:return: If the value of ``source`` is an invalid path or otherwise
causes ``cp.cache_file`` to return ``False`` then
the function will not return and
a ``ValueError`` exception will be raised.
If ``reg.exe`` exits with a non-0 exit code, then
a ``CommandExecutionError`` exception will be
raised. On success this function will return
``True``.
:rtype: bool
salt machine1 reg.import_file salt://win/printer_config/110_Canon/postinstall_config.reg
'''
cache_path = __salt__['cp.cache_file'](source)

View file

@ -50,6 +50,10 @@ def __virtual__():
Only work on select distros which still use Red Hat's /usr/bin/service for
management of either sysvinit or a hybrid sysvinit/upstart init system.
'''
# Disable when booted with systemd
if __utils__['systemd.booted'](__context__):
return (False, 'The rh_service execution module failed to load: this system was booted with systemd.')
# Enable on these platforms only.
enable = set((
'XenServer',
@ -99,15 +103,6 @@ def __virtual__():
'RedHat-based distros >= version 7 use systemd, will not '
'load rh_service.py as virtual \'service\''
)
if __grains__['os'] == 'Amazon':
if int(osrelease_major) in (2016, 2017):
return __virtualname__
else:
return (
False,
'Amazon Linux >= version 2 uses systemd. Will not '
'load rh_service.py as virtual \'service\''
)
return __virtualname__
return (False, 'Cannot load rh_service module: OS not in {0}'.format(enable))

View file

@ -87,7 +87,7 @@ def _get_username(member):
str: The username converted to domain\\username format
'''
return member.ADSPath.replace('WinNT://', '').replace(
'/', '\\').encode('ascii', 'backslashreplace')
'/', '\\')
def add(name, **kwargs):

View file

@ -17,7 +17,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -32,7 +32,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- comment: "Allow HTTP"
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -48,7 +48,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- connstate: NEW
- source: '127.0.0.1'
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -65,7 +65,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- connstate: NEW
- source: '! 127.0.0.1'
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -81,7 +81,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- connstate: NEW
- source: 'not 127.0.0.1'
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -94,7 +94,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -109,7 +109,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- dports:
- 80
- 443
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -122,7 +122,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -136,7 +136,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -148,7 +148,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -161,7 +161,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -174,7 +174,7 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- match: state
- connstate: NEW
- dport: 80
- proto: tcp
- protocol: tcp
- sport: 1025:65535
- save: True
@ -183,6 +183,55 @@ at some point be deprecated in favor of a more generic ``firewall`` state.
- chain: INPUT
- policy: ACCEPT
.. note::
Whereas iptables will accept ``-p``, ``--proto[c[o[l]]]`` as synonyms of
``--protocol``, if ``--proto`` appears in an iptables command after the
appearance of ``-m policy``, it is interpreted as the ``--proto`` option of
the policy extension (see the iptables-extensions(8) man page).
Example rules for IPSec policy:
.. code-block:: yaml
accept_esp_in:
iptables.append:
- table: filter
- chain: INPUT
- jump: ACCEPT
- source: 10.20.0.0/24
- destination: 10.10.0.0/24
- in-interface: eth0
- match: policy
- dir: in
- pol: ipsec
- reqid: 1
- proto: esp
accept_esp_forward_in:
iptables.append:
- use:
- iptables: accept_esp_in
- chain: FORWARD
accept_esp_out:
iptables.append:
- table: filter
- chain: OUTPUT
- jump: ACCEPT
- source: 10.10.0.0/24
- destination: 10.20.0.0/24
- out-interface: eth0
- match: policy
- dir: out
- pol: ipsec
- reqid: 1
- proto: esp
accept_esp_forward_out:
iptables.append:
- use:
- iptables: accept_esp_out
- chain: FORWARD
.. note::
Various functions of the ``iptables`` module use the ``--check`` option. If

View file

@ -212,6 +212,13 @@ def managed(name,
Debug mode. Will insert a new key under the output dictionary, as ``loaded_config`` containing the raw
result after the template was rendered.
.. note::
This argument cannot be used directly on the command line. Instead,
it can be passed through the ``pillar`` variable when executing one
of the :ref:`salt.modules.state.sls` or :ref:`salt.modules.state.apply`
functions (see an example below).
replace: False
Load and replace the configuration. Default: ``False`` (will apply load merge).
@ -261,7 +268,7 @@ def managed(name,
$ sudo salt 'juniper.device' state.sls router.config test=True
$ sudo salt -N all-routers state.sls router.config debug=True
$ sudo salt -N all-routers state.sls router.config pillar="{'debug': True}"
``router.config`` depends on the location of the SLS file (see above). Running this command, will be executed all
five steps from above. These examples above are not meant to be used in a production environment, their sole purpose
@ -324,11 +331,11 @@ def managed(name,
# the user can override the flags the equivalent CLI args
# which have higher precedence
test = __opts__.get('test', test)
debug = __opts__.get('debug', debug)
commit = __opts__.get('commit', commit)
replace = __opts__.get('replace', replace) # this might be a bit risky
skip_verify = __opts__.get('skip_verify', skip_verify)
test = __salt__['config.merge']('test', test)
debug = __salt__['config.merge']('debug', debug)
commit = __salt__['config.merge']('commit', commit)
replace = __salt__['config.merge']('replace', replace) # this might be a bit risky
skip_verify = __salt__['config.merge']('skip_verify', skip_verify)
config_update_ret = _update_config(template_name,
template_source=template_source,

View file

@ -761,6 +761,14 @@ def installed(name,
ret['comment'] = out['comment']
return ret
# No packages to install.
if not target_pkgs:
ret['result'] = True
aicomms = '\n'.join(already_installed_comments)
last_line = 'All specified packages are already installed' + (' and up-to-date' if upgrade else '')
ret['comment'] = aicomms + ('\n' if aicomms else '') + last_line
return ret
# Construct the string that will get passed to the install call
pkgs_str = ','.join([state_name for _, state_name in target_pkgs])
@ -811,12 +819,7 @@ def installed(name,
no_cache_dir=no_cache_dir
)
# Check the retcode for success, but don't fail if using pip1 and the package is
# already present. Pip1 returns a retcode of 1 (instead of 0 for pip2) if you run
# "pip install" without any arguments. See issue #21845.
if pip_install_call and \
(pip_install_call.get('retcode', 1) == 0 or pip_install_call.get('stdout', '').startswith(
'You must give at least one requirement to install')):
if pip_install_call and pip_install_call.get('retcode', 1) == 0:
ret['result'] = True
if requirements or editable:
@ -824,6 +827,8 @@ def installed(name,
if requirements:
PIP_REQUIREMENTS_NOCHANGE = [
'Requirement already satisfied',
'Requirement already up-to-date',
'Requirement not upgraded',
'Collecting',
'Cloning',
'Cleaning up...',

View file

@ -523,7 +523,7 @@ def _find_install_targets(name=None,
if any((pkgs, sources)):
if pkgs:
desired = _repack_pkgs(pkgs)
desired = _repack_pkgs(pkgs, normalize=normalize)
elif sources:
desired = __salt__['pkg_resource.pack_sources'](
sources,

View file

@ -12,11 +12,12 @@ Hives
-----
This is the top level of the registry. They all begin with HKEY.
- HKEY_CLASSES_ROOT (HKCR)
- HKEY_CURRENT_USER(HKCU)
- HKEY_LOCAL MACHINE (HKLM)
- HKEY_USER (HKU)
- HKEY_CURRENT_CONFIG
- HKEY_CLASSES_ROOT (HKCR)
- HKEY_CURRENT_USER(HKCU)
- HKEY_LOCAL MACHINE (HKLM)
- HKEY_USER (HKU)
- HKEY_CURRENT_CONFIG
----
Keys
@ -30,30 +31,38 @@ Values or Entries
-----------------
Values or Entries are the name/data pairs beneath the keys and subkeys. All keys
have a default name/data pair. It is usually "(Default)"="(value not set)". The
actual value for the name and the date is Null. The registry editor will display
"(Default)" and "(value not set)".
have a default name/data pair. The name is ``(Default)`` with a displayed value
of ``(value not set)``. The actual value is Null.
-------
Example
-------
The following example is taken from the windows startup portion of the registry:
```
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
"RTHDVCPL"="\"C:\\Program Files\\Realtek\\Audio\\HDA\\RtkNGUI64.exe\" -s"
"NvBackend"="\"C:\\Program Files (x86)\\NVIDIA Corporation\\Update Core\\NvBackend.exe\""
"BTMTrayAgent"="rundll32.exe \"C:\\Program Files (x86)\\Intel\\Bluetooth\\btmshellex.dll\",TrayApp"
```
.. code-block:: bash
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
"RTHDVCPL"="\"C:\\Program Files\\Realtek\\Audio\\HDA\\RtkNGUI64.exe\" -s"
"NvBackend"="\"C:\\Program Files (x86)\\NVIDIA Corporation\\Update Core\\NvBackend.exe\""
"BTMTrayAgent"="rundll32.exe \"C:\\Program Files (x86)\\Intel\\Bluetooth\\btmshellex.dll\",TrayApp"
In this example these are the values for each:
Hive: `HKEY_LOCAL_MACHINE`
Hive:
``HKEY_LOCAL_MACHINE``
Key and subkeys: `SOFTWARE\Microsoft\Windows\CurrentVersion\Run`
Key and subkeys:
``SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run``
Value:
- There are 3 value names: `RTHDVCPL`, `NvBackend`, and `BTMTrayAgent`
- There are 3 value names:
- `RTHDVCPL`
- `NvBackend`
- `BTMTrayAgent`
- Each value name has a corresponding value
:depends: - salt.utils.win_reg
'''
from __future__ import absolute_import, print_function, unicode_literals
@ -70,19 +79,19 @@ def __virtual__():
'''
if 'reg.read_value' not in __utils__:
return (False, 'reg state module failed to load: '
'missing module function: reg.read_value')
'missing util function: reg.read_value')
if 'reg.set_value' not in __utils__:
return (False, 'reg state module failed to load: '
'missing module function: reg.set_value')
'missing util function: reg.set_value')
if 'reg.delete_value' not in __utils__:
return (False, 'reg state module failed to load: '
'missing module function: reg.delete_value')
'missing util function: reg.delete_value')
if 'reg.delete_key_recursive' not in __utils__:
return (False, 'reg state module failed to load: '
'missing module function: reg.delete_key_recursive')
'missing util function: reg.delete_key_recursive')
return 'reg'
@ -102,76 +111,145 @@ def present(name,
vdata=None,
vtype='REG_SZ',
use_32bit_registry=False):
'''
r'''
Ensure a registry key or value is present.
:param str name: A string value representing the full path of the key to
include the HIVE, Key, and all Subkeys. For example:
Args:
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
name (str):
A string value representing the full path of the key to include the
HIVE, Key, and all Subkeys. For example:
Valid hive values include:
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
:param str vname: The name of the value you'd like to create beneath the
Key. If this parameter is not passed it will assume you want to set the
(Default) value
Valid hive values include:
:param str vdata: The value you'd like to set. If a value name (vname) is
passed, this will be the data for that value name. If not, this will be the
(Default) value for the key.
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
The type for the (Default) value is always REG_SZ and cannot be changed.
This parameter is optional. If not passed, the Key will be created with no
associated item/value pairs.
vname (str):
The name of the value you'd like to create beneath the Key. If this
parameter is not passed it will assume you want to set the
``(Default)`` value
:param str vtype: The value type for the data you wish to store in the
registry. Valid values are:
vdata (str, int, list, bytes):
The value you'd like to set. If a value name (``vname``) is passed,
this will be the data for that value name. If not, this will be the
``(Default)`` value for the key.
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_SZ (Default)
The type of data this parameter expects is determined by the value
type specified in ``vtype``. The correspondence is as follows:
:param bool use_32bit_registry: Use the 32bit portion of the registry.
Applies only to 64bit windows. 32bit Windows will ignore this parameter.
Default is False.
- REG_BINARY: Binary data (str in Py2, bytes in Py3)
- REG_DWORD: int
- REG_EXPAND_SZ: str
- REG_MULTI_SZ: list of str
- REG_QWORD: int
- REG_SZ: str
:return: Returns a dictionary showing the results of the registry operation.
:rtype: dict
.. note::
When setting REG_BINARY, string data will be converted to
binary automatically. To pass binary data, use the built-in
yaml tag ``!!binary`` to denote the actual binary
characters. For example, the following lines will both set
the same data in the registry:
The following example will set the ``(Default)`` value for the
``SOFTWARE\\Salt`` key in the ``HKEY_CURRENT_USER`` hive to ``2016.3.1``:
- ``vdata: Salty Test``
- ``vdata: !!binary U2FsdHkgVGVzdA==\n``
For more information about the ``!!binary`` tag see
`here <http://yaml.org/type/binary.html>`_
.. note::
The type for the ``(Default)`` value is always REG_SZ and cannot
be changed. This parameter is optional. If not passed, the Key
will be created with no associated item/value pairs.
vtype (str):
The value type for the data you wish to store in the registry. Valid
values are:
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_QWORD
- REG_SZ (Default)
use_32bit_registry (bool):
Use the 32bit portion of the registry. Applies only to 64bit
windows. 32bit Windows will ignore this parameter. Default is False.
Returns:
dict: A dictionary showing the results of the registry operation.
Example:
.. code-block:: yaml
The following example will set the ``(Default)`` value for the
``SOFTWARE\\Salt`` key in the ``HKEY_CURRENT_USER`` hive to
``2016.3.1``:
HKEY_CURRENT_USER\\SOFTWARE\\Salt:
reg.present:
- vdata: 2016.3.1
.. code-block:: yaml
The following example will set the value for the ``version`` entry under the
``SOFTWARE\\Salt`` key in the ``HKEY_CURRENT_USER`` hive to ``2016.3.1``. The
value will be reflected in ``Wow6432Node``:
HKEY_CURRENT_USER\\SOFTWARE\\Salt:
reg.present:
- vdata: 2016.3.1
Example:
.. code-block:: yaml
The following example will set the value for the ``version`` entry under
the ``SOFTWARE\\Salt`` key in the ``HKEY_CURRENT_USER`` hive to
``2016.3.1``. The value will be reflected in ``Wow6432Node``:
HKEY_CURRENT_USER\\SOFTWARE\\Salt:
reg.present:
- vname: version
- vdata: 2016.3.1
.. code-block:: yaml
In the above example the path is interpreted as follows:
- ``HKEY_CURRENT_USER`` is the hive
- ``SOFTWARE\\Salt`` is the key
- ``vname`` is the value name ('version') that will be created under the key
- ``vdata`` is the data that will be assigned to 'version'
HKEY_CURRENT_USER\\SOFTWARE\\Salt:
reg.present:
- vname: version
- vdata: 2016.3.1
In the above example the path is interpreted as follows:
- ``HKEY_CURRENT_USER`` is the hive
- ``SOFTWARE\\Salt`` is the key
- ``vname`` is the value name ('version') that will be created under the key
- ``vdata`` is the data that will be assigned to 'version'
Example:
Binary data can be set in two ways. The following two examples will set
a binary value of ``Salty Test``
.. code-block:: yaml
no_conversion:
reg.present:
- name: HKLM\SOFTWARE\SaltTesting
- vname: test_reg_binary_state
- vdata: Salty Test
- vtype: REG_BINARY
conversion:
reg.present:
- name: HKLM\SOFTWARE\SaltTesting
- vname: test_reg_binary_state_with_tag
- vdata: !!binary U2FsdHkgVGVzdA==\n
- vtype: REG_BINARY
Example:
To set a ``REG_MULTI_SZ`` value:
.. code-block:: yaml
reg_multi_sz:
reg.present:
- name: HKLM\SOFTWARE\Salt
- vname: reg_multi_sz
- vdata:
- list item 1
- list item 2
'''
ret = {'name': name,
'result': True,
@ -226,39 +304,42 @@ def absent(name, vname=None, use_32bit_registry=False):
'''
Ensure a registry value is removed. To remove a key use key_absent.
:param str name: A string value representing the full path of the key to
include the HIVE, Key, and all Subkeys. For example:
Args:
name (str):
A string value representing the full path of the key to include the
HIVE, Key, and all Subkeys. For example:
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt``
Valid hive values include:
Valid hive values include:
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
- HKEY_CURRENT_USER or HKCU
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_USERS or HKU
:param str vname: The name of the value you'd like to create beneath the
Key. If this parameter is not passed it will assume you want to set the
(Default) value
vname (str):
The name of the value you'd like to create beneath the Key. If this
parameter is not passed it will assume you want to set the
``(Default)`` value
:param bool use_32bit_registry: Use the 32bit portion of the registry.
Applies only to 64bit windows. 32bit Windows will ignore this parameter.
Default is False.
use_32bit_registry (bool):
Use the 32bit portion of the registry. Applies only to 64bit
windows. 32bit Windows will ignore this parameter. Default is False.
:return: Returns a dictionary showing the results of the registry operation.
:rtype: dict
Returns:
dict: A dictionary showing the results of the registry operation.
CLI Example:
.. code-block:: yaml
.. code-block:: yaml
'HKEY_CURRENT_USER\\SOFTWARE\\Salt':
reg.absent
- vname: version
'HKEY_CURRENT_USER\\SOFTWARE\\Salt':
reg.absent
- vname: version
In the above example the value named ``version`` will be removed from
the SOFTWARE\\Salt key in the HKEY_CURRENT_USER hive. If ``vname`` was not
passed, the (Default) value would be deleted.
In the above example the value named ``version`` will be removed from
the SOFTWARE\\Salt key in the HKEY_CURRENT_USER hive. If ``vname`` was
not passed, the ``(Default)`` value would be deleted.
'''
ret = {'name': name,
'result': True,
@ -304,39 +385,43 @@ def key_absent(name, use_32bit_registry=False):
r'''
.. versionadded:: 2015.5.4
Ensure a registry key is removed. This will remove a key and all value
entries it contains. It will fail if the key contains subkeys.
Ensure a registry key is removed. This will remove the key, subkeys, and all
value entries.
:param str name: A string representing the full path to the key to be
removed to include the hive and the keypath. The hive can be any of the
following:
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
name (str):
A string representing the full path to the key to be removed to
include the hive and the keypath. The hive can be any of the
following:
:param bool use_32bit_registry: Use the 32bit portion of the registry.
Applies only to 64bit windows. 32bit Windows will ignore this parameter.
Default is False.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
:return: Returns a dictionary showing the results of the registry operation.
:rtype: dict
use_32bit_registry (bool):
Use the 32bit portion of the registry. Applies only to 64bit
windows. 32bit Windows will ignore this parameter. Default is False.
The following example will delete the ``SOFTWARE\Salt`` key and all subkeys
under the ``HKEY_CURRENT_USER`` hive.
Returns:
dict: A dictionary showing the results of the registry operation.
Example:
.. code-block:: yaml
CLI Example:
'HKEY_CURRENT_USER\SOFTWARE\Salt':
reg.key_absent:
- force: True
The following example will delete the ``SOFTWARE\DeleteMe`` key in the
``HKEY_LOCAL_MACHINE` hive including all its subkeys and value pairs.
In the above example the path is interpreted as follows:
.. code-block:: yaml
- ``HKEY_CURRENT_USER`` is the hive
- ``SOFTWARE\Salt`` is the key
remove_key_demo:
reg.key_absent:
- name: HKEY_CURRENT_USER\SOFTWARE\DeleteMe
In the above example the path is interpreted as follows:
- ``HKEY_CURRENT_USER`` is the hive
- ``SOFTWARE\DeleteMe`` is the key
'''
ret = {'name': name,
'result': True,
@ -352,10 +437,10 @@ def key_absent(name, use_32bit_registry=False):
ret['comment'] = '{0} is already absent'.format(name)
return ret
ret['changes'] = {'reg': {
'Removed': {
'Key': r'{0}\{1}'.format(hive, key)
}}}
ret['changes'] = {
'reg': {
'Removed': {
'Key': r'{0}\{1}'.format(hive, key)}}}
# Check for test option
if __opts__['test']:

View file

@ -15,7 +15,6 @@ import os
import weakref
import time
import traceback
import errno
# Import Salt Libs
import salt.crypt
@ -33,6 +32,7 @@ import salt.transport.client
import salt.transport.server
import salt.transport.mixins.auth
from salt.ext import six
from salt.ext.six.moves import queue # pylint: disable=import-error
from salt.exceptions import SaltReqTimeoutError, SaltClientError
from salt.transport import iter_transport_opts
@ -571,6 +571,11 @@ class TCPReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt.tra
raise exc
self._socket.close()
self._socket = None
if hasattr(self.req_server, 'stop'):
try:
self.req_server.stop()
except Exception as exc:
log.exception('TCPReqServerChannel close generated an exception: %s', str(exc))
def __del__(self):
self.close()
@ -757,15 +762,23 @@ if USE_LOAD_BALANCER:
super(LoadBalancerWorker, self).__init__(
message_handler, *args, **kwargs)
self.socket_queue = socket_queue
self._stop = threading.Event()
self.thread = threading.Thread(target=self.socket_queue_thread)
self.thread.start()
t = threading.Thread(target=self.socket_queue_thread)
t.start()
def stop(self):
self._stop.set()
self.thread.join()
def socket_queue_thread(self):
try:
while True:
client_socket, address = self.socket_queue.get(True, None)
try:
client_socket, address = self.socket_queue.get(True, 1)
except queue.Empty:
if self._stop.is_set():
break
continue
# 'self.io_loop' initialized in super class
# 'tornado.tcpserver.TCPServer'.
# 'self._handle_connection' defined in same super class.

View file

@ -135,6 +135,12 @@ def vb_get_manager():
'''
global _virtualboxManager
if _virtualboxManager is None and HAS_LIBS:
try:
from importlib import reload
except ImportError:
# If we get here, we are in py2 and reload is a built-in.
pass
# Reloading the API extends sys.paths for subprocesses of multiprocessing, since they seem to share contexts
reload(vboxapi)
_virtualboxManager = vboxapi.VirtualBoxManager(None, None)
@ -149,7 +155,13 @@ def vb_get_box():
@rtype: IVirtualBox
'''
vb_get_manager()
vbox = _virtualboxManager.vbox
try:
# This works in older versions of the SDK, but does not seem to work anymore.
vbox = _virtualboxManager.vbox
except AttributeError:
vbox = _virtualboxManager.getVirtualBox()
return vbox

View file

@ -6,21 +6,23 @@ Manage the Windows registry
Hives
-----
Hives are the main sections of the registry and all begin with the word HKEY.
- HKEY_LOCAL_MACHINE
- HKEY_CURRENT_USER
- HKEY_USER
- HKEY_LOCAL_MACHINE
- HKEY_CURRENT_USER
- HKEY_USER
----
Keys
----
Keys are the folders in the registry. Keys can have many nested subkeys. Keys
can have a value assigned to them under the (Default)
can have a value assigned to them under the (Default) value name
-----------------
Values or Entries
-----------------
Values/Entries are name/data pairs. There can be many values in a key. The
(Default) value corresponds to the Key, the rest are their own value pairs.
(Default) value corresponds to the Key itself, the rest are their own name/value
pairs.
:depends: - PyWin32
'''
@ -91,7 +93,8 @@ def _to_unicode(vdata):
class Registry(object): # pylint: disable=R0903
'''
Delay usage until this module is used
This was put in a class to delay usage until this module is actually used
This class contains all the lookup dicts for working with the registry
'''
def __init__(self):
self.hkeys = {
@ -157,14 +160,26 @@ class Registry(object): # pylint: disable=R0903
def key_exists(hive, key, use_32bit_registry=False):
'''
Check that the key is found in the registry
Check that the key is found in the registry. This refers to keys and not
value/data pairs.
:param str hive: The hive to connect to.
:param str key: The key to check
:param bool use_32bit_registry: Look in the 32bit portion of the registry
Args:
:return: Returns True if found, False if not found
:rtype: bool
hive (str): The hive to connect to
key (str): The key to check
use_32bit_registry (bool): Look in the 32bit portion of the registry
Returns:
bool: True if exists, otherwise False
Usage:
.. code-block:: python
import salt.utils.win_reg
winreg.key_exists(hive='HKLM', key='SOFTWARE\\Microsoft')
'''
local_hive = _to_unicode(hive)
local_key = _to_unicode(key)
@ -188,13 +203,19 @@ def broadcast_change():
'''
Refresh the windows environment.
Returns (bool): True if successful, otherwise False
.. note::
This will only effect new processes and windows. Services will not see
the change until the system restarts.
CLI Example:
Returns:
bool: True if successful, otherwise False
.. code-block:: bash
Usage:
salt '*' reg.broadcast_change
.. code-block:: python
import salt.utils.win_reg
winreg.broadcast_change()
'''
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx
_, res = win32gui.SendMessageTimeout(
@ -207,28 +228,34 @@ def list_keys(hive, key=None, use_32bit_registry=False):
'''
Enumerates the subkeys in a registry key or hive.
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following:
:param str key: The key (looks like a path) to the value name. If a key is
not passed, the keys under the hive will be returned.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64 bit installations. On 32bit machines this is ignored.
key (str):
The key (looks like a path) to the value name. If a key is not
passed, the keys under the hive will be returned.
:return: A list of keys/subkeys under the hive or key.
:rtype: list
use_32bit_registry (bool):
Accesses the 32bit portion of the registry on 64 bit installations.
On 32bit machines this is ignored.
CLI Example:
Returns:
list: A list of keys/subkeys under the hive or key.
.. code-block:: bash
Usage:
salt '*' reg.list_keys HKLM 'SOFTWARE'
.. code-block:: python
import salt.utils.win_reg
winreg.list_keys(hive='HKLM', key='SOFTWARE\\Microsoft')
'''
local_hive = _to_unicode(hive)
@ -265,30 +292,37 @@ def list_values(hive, key=None, use_32bit_registry=False, include_default=True):
'''
Enumerates the values in a registry key or hive.
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following:
:param str key: The key (looks like a path) to the value name. If a key is
not passed, the values under the hive will be returned.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64 bit installations. On 32bit machines this is ignored.
key (str):
The key (looks like a path) to the value name. If a key is not
passed, the values under the hive will be returned.
:param bool include_default: Toggle whether to include the '(Default)' value.
use_32bit_registry (bool):
Accesses the 32bit portion of the registry on 64 bit installations.
On 32bit machines this is ignored.
:return: A list of values under the hive or key.
:rtype: list
include_default (bool):
Toggle whether to include the '(Default)' value.
CLI Example:
Returns:
list: A list of values under the hive or key.
.. code-block:: bash
Usage:
salt '*' reg.list_values HKLM 'SYSTEM\\CurrentControlSet\\Services\\Tcpip'
.. code-block:: python
import salt.utils.win_reg
winreg.list_values(hive='HKLM', key='SYSTEM\\CurrentControlSet\\Services\\Tcpip')
'''
local_hive = _to_unicode(hive)
local_key = _to_unicode(key)
@ -335,40 +369,60 @@ def list_values(hive, key=None, use_32bit_registry=False, include_default=True):
def read_value(hive, key, vname=None, use_32bit_registry=False):
r'''
Reads a registry value entry or the default value for a key.
Reads a registry value entry or the default value for a key. To read the
default value, don't pass ``vname``
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str): The name of the hive. Can be one of the following:
:param str key: The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be returned
key (str):
The key (looks like a path) to the value name.
:param bool use_32bit_registry: Accesses the 32bit portion of the registry
on 64bit installations. On 32bit machines this is ignored.
vname (str):
The value name. These are the individual name/data pairs under the
key. If not passed, the key (Default) value will be returned.
:return: A dictionary containing the passed settings as well as the
value_data if successful. If unsuccessful, sets success to False.
use_32bit_registry (bool):
Accesses the 32bit portion of the registry on 64bit installations.
On 32bit machines this is ignored.
:rtype: dict
Returns:
dict: A dictionary containing the passed settings as well as the
value_data if successful. If unsuccessful, sets success to False.
If vname is not passed:
bool: Returns False if the key is not found
- Returns the first unnamed value (Default) as a string.
- Returns none if first unnamed value is empty.
- Returns False if key not found.
If vname is not passed:
CLI Example:
- Returns the first unnamed value (Default) as a string.
- Returns none if first unnamed value is empty.
.. code-block:: bash
Usage:
salt '*' reg.read_value HKEY_LOCAL_MACHINE 'SOFTWARE\Salt' 'version'
The following will get the value of the ``version`` value name in the
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt`` key
.. code-block:: python
import salt.utils.win_reg
winreg.read_value(hive='HKLM', key='SOFTWARE\\Salt', vname='version')
Usage:
The following will get the default value of the
``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt`` key
.. code-block:: python
import salt.utils.win_reg
winreg.read_value(hive='HKLM', key='SOFTWARE\\Salt')
'''
# If no name is passed, the default value of the key will be returned
# The value name is Default
@ -438,98 +492,125 @@ def set_value(hive,
use_32bit_registry=False,
volatile=False):
'''
Sets a registry value entry or the default value for a key.
Sets a value in the registry. If ``vname`` is passed, it will be the value
for that value name, otherwise it will be the default value for the
specified key
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following
:param str key: The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be set.
key (str):
The key (looks like a path) to the value name.
:param object vdata: The value data to be set.
What the type of this parameter
should be is determined by the value of the vtype
parameter. The correspondence
is as follows:
vname (str):
The value name. These are the individual name/data pairs under the
key. If not passed, the key (Default) value will be set.
.. glossary::
vdata (str, int, list, bytes):
The value you'd like to set. If a value name (vname) is passed, this
will be the data for that value name. If not, this will be the
(Default) value for the key.
REG_BINARY
binary data (i.e. str in python version < 3 and bytes in version >=3)
REG_DWORD
int
REG_EXPAND_SZ
str
REG_MULTI_SZ
list of objects of type str
REG_SZ
str
The type of data this parameter expects is determined by the value
type specified in ``vtype``. The correspondence is as follows:
:param str vtype: The value type.
The possible values of the vtype parameter are indicated
above in the description of the vdata parameter.
- REG_BINARY: Binary data (str in Py2, bytes in Py3)
- REG_DWORD: int
- REG_EXPAND_SZ: str
- REG_MULTI_SZ: list of str
- REG_QWORD: int
- REG_SZ: str
:param bool use_32bit_registry: Sets the 32bit portion of the registry on
64bit installations. On 32bit machines this is ignored.
.. note::
When setting REG_BINARY, string data will be converted to
binary. You can pass base64 encoded using the ``binascii``
built-in module. Use ``binascii.b2a_base64('your data')``
:param bool volatile: When this parameter has a value of True, the registry key will be
made volatile (i.e. it will not persist beyond a system reset or shutdown).
This parameter only has an effect when a key is being created and at no
other time.
.. note::
The type for the (Default) value is always REG_SZ and cannot be
changed.
:return: Returns True if successful, False if not
:rtype: bool
.. note::
This parameter is optional. If not passed, the Key will be
created with no associated item/value pairs.
CLI Example:
vtype (str):
The value type. The possible values of the vtype parameter are
indicated above in the description of the vdata parameter.
.. code-block:: bash
use_32bit_registry (bool):
Sets the 32bit portion of the registry on 64bit installations. On
32bit machines this is ignored.
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2'
volatile (bool):
When this parameter has a value of True, the registry key will be
made volatile (i.e. it will not persist beyond a system reset or
shutdown). This parameter only has an effect when a key is being
created and at no other time.
This function is strict about the type of vdata. For instance the
the next example will fail because vtype has a value of REG_SZ and vdata
has a type of int (as opposed to str as expected).
Returns:
bool: True if successful, otherwise False
CLI Example:
Usage:
.. code-block:: bash
This will set the version value to 2015.5.2 in the SOFTWARE\\Salt key in
the HKEY_LOCAL_MACHINE hive
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_SZ vdata=0
.. code-block:: python
However, this next example where vdata is properly quoted should succeed.
import salt.utils.win_reg
winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='version', vdata='2015.5.2')
CLI Example:
Usage:
.. code-block:: bash
This function is strict about the type of vdata. For instance this
example will fail because vtype has a value of REG_SZ and vdata has a
type of int (as opposed to str as expected).
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_SZ vdata="'0'"
.. code-block:: python
An example of using vtype REG_BINARY is as follows:
import salt.utils.win_reg
winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='str_data', vdata=1.2)
CLI Example:
Usage:
.. code-block:: bash
In this next example vdata is properly quoted and should succeed.
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_BINARY vdata='!!binary d2hhdCdzIHRoZSBwb2ludA=='
.. code-block:: python
An example of using vtype REG_LIST is as follows:
import salt.utils.win_reg
winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='str_data', vdata='1.2')
CLI Example:
Usage:
.. code-block:: bash
This is an example of using vtype REG_BINARY. Both ``set_value``
commands will set the same value ``Salty Test``
salt '*' reg.set_value HKEY_LOCAL_MACHINE 'SOFTWARE\\Salt' 'version' '2015.5.2' \\
vtype=REG_LIST vdata='[a,b,c]'
.. code-block:: python
import salt.utils.win_reg
winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='bin_data', vdata='Salty Test', vtype='REG_BINARY')
import binascii
bin_data = binascii.b2a_base64('Salty Test')
winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='bin_data_encoded', vdata=bin_data, vtype='REG_BINARY')
Usage:
An example using vtype REG_MULTI_SZ is as follows:
.. code-block:: python
import salt.utils.win_reg
winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='list_data', vdata=['Salt', 'is', 'great'], vtype='REG_MULTI_SZ')
'''
local_hive = _to_unicode(hive)
local_key = _to_unicode(key)
@ -571,20 +652,29 @@ def cast_vdata(vdata=None, vtype='REG_SZ'):
Args:
vdata (str, list, bin): The data to cast
vdata (str, int, list, bytes): The data to cast
vtype (str):
The type of data to be written to the registry. Must be one of the
following:
- REG_BINARY
- REG_DWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_QWORD
- REG_SZ
Returns:
The vdata cast to the appropriate type. Will be unicode string, binary,
list of unicode strings, or int
Usage:
.. code-block:: python
import salt.utils.win_reg
winreg.cast_vdata(vdata='This is the string', vtype='REG_SZ')
'''
# Check data type and cast to expected type
# int will automatically become long on 64bit numbers
@ -614,33 +704,39 @@ def delete_key_recursive(hive, key, use_32bit_registry=False):
'''
.. versionadded:: 2015.5.4
Delete a registry key to include all subkeys.
Delete a registry key to include all subkeys and value/data pairs.
:param hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following
:param key: The key to remove (looks like a path)
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param bool use_32bit_registry: Deletes the 32bit portion of the registry on
64bit installations. On 32bit machines this is ignored.
key (str):
The key to remove (looks like a path)
:return: A dictionary listing the keys that deleted successfully as well as
those that failed to delete.
:rtype: dict
use_32bit_registry (bool):
Deletes the 32bit portion of the registry on 64bit
installations. On 32bit machines this is ignored.
The following example will remove ``salt`` and all its subkeys from the
``SOFTWARE`` key in ``HKEY_LOCAL_MACHINE``:
Returns:
dict: A dictionary listing the keys that deleted successfully as well as
those that failed to delete.
CLI Example:
Usage:
.. code-block:: bash
The following example will remove ``salt`` and all its subkeys from the
``SOFTWARE`` key in ``HKEY_LOCAL_MACHINE``:
salt '*' reg.delete_key_recursive HKLM SOFTWARE\\salt
.. code-block:: python
import salt.utils.win_reg
winreg.delete_key_recursive(hive='HKLM', key='SOFTWARE\\DeleteMe')
'''
local_hive = _to_unicode(hive)
@ -718,31 +814,37 @@ def delete_value(hive, key, vname=None, use_32bit_registry=False):
'''
Delete a registry value entry or the default value for a key.
:param str hive: The name of the hive. Can be one of the following
Args:
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
hive (str):
The name of the hive. Can be one of the following
:param str key: The key (looks like a path) to the value name.
- HKEY_LOCAL_MACHINE or HKLM
- HKEY_CURRENT_USER or HKCU
- HKEY_USER or HKU
- HKEY_CLASSES_ROOT or HKCR
- HKEY_CURRENT_CONFIG or HKCC
:param str vname: The value name. These are the individual name/data pairs
under the key. If not passed, the key (Default) value will be deleted.
key (str):
The key (looks like a path) to the value name.
:param bool use_32bit_registry: Deletes the 32bit portion of the registry on
64bit installations. On 32bit machines this is ignored.
vname (str):
The value name. These are the individual name/data pairs under the
key. If not passed, the key (Default) value will be deleted.
:return: Returns True if successful, None if the value didn't exist, and
False if unsuccessful
:rtype: bool
use_32bit_registry (bool):
Deletes the 32bit portion of the registry on 64bit installations. On
32bit machines this is ignored.
CLI Example:
Return:
bool: True if successful, otherwise False
.. code-block:: bash
Usage:
salt '*' reg.delete_value HKEY_CURRENT_USER 'SOFTWARE\\Salt' 'version'
.. code-block:: python
import salt.utils.win_reg
winreg.delete_value(hive='HKLM', key='SOFTWARE\\SaltTest', vname='version')
'''
local_hive = _to_unicode(hive)
local_key = _to_unicode(key)

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
# Import Salt libs
import salt.utils.platform
@skipIf(not salt.utils.platform.is_windows(), 'windows tests only')
class AutoRunsModuleTest(ModuleCase):
'''
Test the autoruns module
'''
def test_win_autoruns_list(self):
'''
test win_autoruns.list module
'''
ret = self.run_function('autoruns.list')
self.assertIn('HKLM', str(ret))
self.assertTrue(isinstance(ret, dict))

View file

@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest
# Import Salt Libs
import salt.utils.platform
@skipIf(not salt.utils.platform.is_windows(), 'Tests for only Windows')
class FirewallTest(ModuleCase):
'''
Validate windows firewall module
'''
def _pre_firewall_status(self, pre_run):
post_run = self.run_function('firewall.get_config')
network = ['Domain', 'Public', 'Private']
# compare the status of the firewall before and after test
# and re-enable or disable depending on status before test run
for net in network:
if post_run[net] != pre_run[net]:
if pre_run[net]:
self.assertTrue(self.run_function('firewall.enable', profile=net))
else:
self.assertTrue(self.run_function('firewall.disable', profile=net))
@destructiveTest
def test_firewall_get_config(self):
'''
test firewall.get_config
'''
pre_run = self.run_function('firewall.get_config')
# ensure all networks are enabled then test status
self.assertTrue(self.run_function('firewall.enable', profile='allprofiles'))
ret = self.run_function('firewall.get_config')
network = ['Domain', 'Public', 'Private']
for net in network:
self.assertTrue(ret[net])
self._pre_firewall_status(pre_run)
@destructiveTest
def test_firewall_disable(self):
'''
test firewall.disable
'''
pre_run = self.run_function('firewall.get_config')
network = 'Private'
ret = self.run_function('firewall.get_config')[network]
if not ret:
self.assertTrue(self.run_function('firewall.enable', profile=network))
self.assertTrue(self.run_function('firewall.disable', profile=network))
ret = self.run_function('firewall.get_config')[network]
self.assertFalse(ret)
self._pre_firewall_status(pre_run)
@destructiveTest
def test_firewall_enable(self):
'''
test firewall.enable
'''
pre_run = self.run_function('firewall.get_config')
network = 'Private'
ret = self.run_function('firewall.get_config')[network]
if ret:
self.assertTrue(self.run_function('firewall.disable', profile=network))
self.assertTrue(self.run_function('firewall.enable', profile=network))
ret = self.run_function('firewall.get_config')[network]
self.assertTrue(ret)
self._pre_firewall_status(pre_run)
def test_firewall_get_rule(self):
'''
test firewall.get_rule
'''
rule = 'Remote Event Log Management (NP-In)'
ret = self.run_function('firewall.get_rule', [rule])
checks = ['Private', 'LocalPort', 'RemotePort']
for check in checks:
self.assertIn(check, ret[rule])
@destructiveTest
def test_firewall_add_delete_rule(self):
'''
test firewall.add_rule and delete_rule
'''
rule = 'test rule'
port = '8080'
# test adding firewall rule
add_rule = self.run_function('firewall.add_rule', [rule, port])
ret = self.run_function('firewall.get_rule', [rule])
self.assertIn(rule, ret[rule])
self.assertIn(port, ret[rule])
# test deleting firewall rule
self.assertTrue(self.run_function('firewall.delete_rule', [rule, port]))
ret = self.run_function('firewall.get_rule', [rule])
self.assertNotIn(rule, ret)
self.assertNotIn(port, ret)
self.assertIn('No rules match the specified criteria.', ret)

View file

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
# Import Salt Libs
import salt.utils.path
import salt.utils.platform
URL = 'repo.saltstack.com'
class NetworkTest(ModuleCase):
'''
Validate network module
'''
def test_network_ping(self):
'''
network.ping
'''
ret = self.run_function('network.ping', [URL])
exp_out = ['ping', URL, 'ttl', 'time']
for out in exp_out:
self.assertIn(out, ret.lower())
@skipIf(salt.utils.platform.is_darwin(), 'not supported on macosx')
def test_network_netstat(self):
'''
network.netstat
'''
ret = self.run_function('network.netstat')
exp_out = ['proto', 'local-address']
for val in ret:
for out in exp_out:
self.assertIn(out, val)
def test_network_traceroute(self):
'''
network.traceroute
'''
if not salt.utils.path.which('traceroute') and not salt.utils.platform.is_windows():
self.skipTest('traceroute not installed')
ret = self.run_function('network.traceroute', [URL])
exp_out = ['hostname', 'ip']
for out in exp_out:
self.assertIn(out, exp_out)
@skipIf(not salt.utils.platform.is_windows(), 'windows only test')
def test_network_nslookup(self):
'''
network.nslookup
'''
ret = self.run_function('network.nslookup', [URL])
exp_out = ['Server', 'Address']
for out in exp_out:
self.assertIn(out, exp_out)

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest
# Import Salt Libs
import salt.utils.platform
@skipIf(not salt.utils.platform.is_windows(), 'Tests for only Windows')
class NTPTest(ModuleCase):
'''
Validate windows ntp module
'''
@destructiveTest
def test_ntp_set_servers(self):
'''
test ntp get and set servers
'''
ntp_srv = 'pool.ntp.org'
set_srv = self.run_function('ntp.set_servers', [ntp_srv])
self.assertTrue(set_srv)
get_srv = self.run_function('ntp.get_servers')
self.assertEqual(ntp_srv, get_srv[0])

View file

@ -929,13 +929,13 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
'pip_|-another_non_changing_state_|-mock_|-installed': {
'__run_num__': 3,
'changes': False,
'comment': 'Python package mock was already installed\nAll packages were successfully installed',
'comment': 'Python package mock was already installed\nAll specified packages are already installed',
'result': True
},
'pip_|-non_changing_state_|-mock_|-installed': {
'__run_num__': 2,
'changes': False,
'comment': 'Python package mock was already installed\nAll packages were successfully installed',
'comment': 'Python package mock was already installed\nAll specified packages are already installed',
'result': True
}
}

View file

@ -359,3 +359,65 @@ class SystemModuleTest(ModuleCase):
if self.run_function('grains.get', ['os_family']) == 'NILinuxRT':
self.assertTrue(self.run_function('system._has_settable_hwclock'))
self.assertTrue(self._hwclock_has_compare())
@skipIf(not salt.utils.platform.is_windows(), 'These tests can only be run on windows')
class WinSystemModuleTest(ModuleCase):
'''
Validate the date/time functions in the win_system module
'''
def test_get_computer_name(self):
'''
Test getting the computer name
'''
ret = self.run_function('system.get_computer_name')
self.assertTrue(isinstance(ret, str))
import socket
name = socket.gethostname()
self.assertEqual(name, ret)
@destructiveTest
def test_set_computer_desc(self):
'''
Test setting the computer description
'''
desc = 'test description'
set_desc = self.run_function('system.set_computer_desc', [desc])
self.assertTrue(set_desc)
get_desc = self.run_function('system.get_computer_desc')
self.assertEqual(set_desc['Computer Description'], get_desc)
def test_get_system_time(self):
'''
Test getting the system time
'''
ret = self.run_function('system.get_system_time')
now = datetime.datetime.now()
self.assertEqual(now.strftime("%I:%M"), ret.rsplit(':', 1)[0])
@destructiveTest
def test_set_system_time(self):
'''
Test setting the system time
'''
test_time = '10:55'
set_time = self.run_function('system.set_system_time', [test_time + ' AM'])
get_time = self.run_function('system.get_system_time').rsplit(':', 1)[0]
self.assertEqual(get_time, test_time)
def test_get_system_date(self):
'''
Test getting system date
'''
ret = self.run_function('system.get_system_date')
date = datetime.datetime.now().date().strftime("%m/%d/%Y")
self.assertEqual(date, ret)
@destructiveTest
def test_set_system_date(self):
'''
Test setting system date
'''
self.assertTrue(self.run_function('system.set_system_date', ['3/25/2018']))

View file

@ -592,7 +592,7 @@ class PipStateTest(ModuleCase, SaltReturnAssertsMixin):
self.assertEqual(
ret[key]['comment'],
('Python package carbon < 1.3 was already installed\n'
'All packages were successfully installed'))
'All specified packages are already installed'))
break
else:
raise Exception('Expected state did not run')

View file

@ -121,7 +121,7 @@ class ShellTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
data = '\n'.join(data)
self.assertIn('minion', data)
'''
arg_str = '-c {0} {1}'.format(self.get_config_dir(), arg_str)
arg_str = '-c {0} -t {1} {2}'.format(self.get_config_dir(), timeout, arg_str)
return self.run_script('salt', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=timeout)
def run_ssh(self, arg_str, with_retcode=False, timeout=25,

View file

@ -24,6 +24,7 @@ import shutil
import signal
import socket
import string
import subprocess
import sys
import tempfile
import threading
@ -60,6 +61,31 @@ import salt.utils.files
log = logging.getLogger(__name__)
HAS_SYMLINKS = None
def no_symlinks():
'''
Check if git is installed and has symlinks enabled in the configuration.
'''
global HAS_SYMLINKS
if HAS_SYMLINKS is not None:
return not HAS_SYMLINKS
output = ''
try:
output = subprocess.check_output('git config --get core.symlinks', shell=True)
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
except subprocess.CalledProcessError:
# git returned non-zero status
pass
HAS_SYMLINKS = False
if output.strip() == 'true':
HAS_SYMLINKS = True
return not HAS_SYMLINKS
def destructiveTest(caller):
'''
Mark a test case as a destructive test for example adding or removing users

View file

@ -39,6 +39,7 @@ import salt.utils.stringutils
import salt.utils.yaml
import salt.version
import salt.exceptions
import salt.utils.process
from salt.utils.verify import verify_env
from salt.utils.immutabletypes import freeze
from salt._compat import ElementTree as etree
@ -638,6 +639,29 @@ class SaltReturnAssertsMixin(object):
self.assertNotEqual(saltret, comparison)
def _fetch_events(q):
'''
Collect events and store them
'''
def _clean_queue():
print('Cleaning queue!')
while not q.empty():
queue_item = q.get()
queue_item.task_done()
atexit.register(_clean_queue)
a_config = AdaptedConfigurationTestCaseMixin()
event = salt.utils.event.get_event('minion', sock_dir=a_config.get_config('minion')['sock_dir'], opts=a_config.get_config('minion'))
while True:
try:
events = event.get_event(full=False)
except Exception:
# This is broad but we'll see all kinds of issues right now
# if we drop the proc out from under the socket while we're reading
pass
q.put(events)
class SaltMinionEventAssertsMixin(object):
'''
Asserts to verify that a given event was seen
@ -646,36 +670,15 @@ class SaltMinionEventAssertsMixin(object):
def __new__(cls, *args, **kwargs):
# We have to cross-call to re-gen a config
cls.q = multiprocessing.Queue()
cls.fetch_proc = multiprocessing.Process(target=cls._fetch, args=(cls.q,))
cls.fetch_proc = salt.utils.process.SignalHandlingMultiprocessingProcess(
target=_fetch_events, args=(cls.q,)
)
cls.fetch_proc.start()
return object.__new__(cls)
def __exit__(self, *args, **kwargs):
self.fetch_proc.join()
@staticmethod
def _fetch(q):
'''
Collect events and store them
'''
def _clean_queue():
print('Cleaning queue!')
while not q.empty():
queue_item = q.get()
queue_item.task_done()
atexit.register(_clean_queue)
a_config = AdaptedConfigurationTestCaseMixin()
event = salt.utils.event.get_event('minion', sock_dir=a_config.get_config('minion')['sock_dir'], opts=a_config.get_config('minion'))
while True:
try:
events = event.get_event(full=False)
except Exception:
# This is broad but we'll see all kinds of issues right now
# if we drop the proc out from under the socket while we're reading
pass
q.put(events)
def assertMinionEventFired(self, tag):
#TODO
raise salt.exceptions.NotImplemented('assertMinionEventFired() not implemented')

View file

@ -177,7 +177,7 @@ class SaltCoverageTestingParser(SaltTestingParser):
# Update environ so that any subprocess started on tests are also
# included in the report
coverage_options['data_suffix'] = True
os.environ['COVERAGE_PROCESS_START'] = '1'
os.environ['COVERAGE_PROCESS_START'] = ''
os.environ['COVERAGE_OPTIONS'] = salt.utils.json.dumps(coverage_options)
# Setup coverage

View file

@ -862,15 +862,6 @@ SwapTotal: 4789244 kB'''
with patch.object(salt.utils.dns, 'parse_resolv', MagicMock(return_value=resolv_mock)):
assert core.dns() == ret
def _run_dns_test(self, resolv_mock, ret):
with patch.object(salt.utils, 'is_windows',
MagicMock(return_value=False)):
with patch.dict(core.__opts__, {'ipv6': False}):
with patch.object(salt.utils.dns, 'parse_resolv',
MagicMock(return_value=resolv_mock)):
get_dns = core.dns()
self.assertEqual(get_dns, ret)
@skipIf(not salt.utils.platform.is_linux(), 'System is not Linux')
@patch.object(salt.utils, 'is_windows', MagicMock(return_value=False))
@patch('salt.utils.network.ip_addrs', MagicMock(return_value=['1.2.3.4', '5.6.7.8']))
@ -892,3 +883,21 @@ SwapTotal: 4789244 kB'''
self.assertIn('fqdns', fqdns)
self.assertEqual(len(fqdns['fqdns']), len(ret['fqdns']))
self.assertEqual(set(fqdns['fqdns']), set(ret['fqdns']))
def test_core_virtual(self):
'''
test virtual grain with cmd virt-what
'''
virt = 'kvm'
with patch.object(salt.utils, 'is_windows',
MagicMock(return_value=False)):
with patch.object(salt.utils, 'which',
MagicMock(return_value=True)):
with patch.dict(core.__salt__, {'cmd.run_all':
MagicMock(return_value={'pid': 78,
'retcode': 0,
'stderr': '',
'stdout': virt})}):
osdata = {'kernel': 'test', }
ret = core._virtual(osdata)
self.assertEqual(ret['virtual'], virt)

View file

@ -773,6 +773,107 @@ class FileModuleTestCase(TestCase, LoaderModuleMockMixin):
saltenv='base')
self.assertEqual(ret, 'This is a templated file.')
def test_get_diff(self):
text1 = textwrap.dedent('''\
foo
bar
baz
спам
''')
text2 = textwrap.dedent('''\
foo
bar
baz
яйца
''')
# The below two variables are 8 bytes of data pulled from /dev/urandom
binary1 = b'\xd4\xb2\xa6W\xc6\x8e\xf5\x0f'
binary2 = b',\x13\x04\xa5\xb0\x12\xdf%'
# pylint: disable=no-self-argument
class MockFopen(object):
'''
Provides a fake filehandle object that has just enough to run
readlines() as file.get_diff does. Any significant changes to
file.get_diff may require this class to be modified.
'''
def __init__(mockself, path, *args, **kwargs): # pylint: disable=unused-argument
mockself.path = path
def readlines(mockself): # pylint: disable=unused-argument
return {
'text1': text1.encode('utf8'),
'text2': text2.encode('utf8'),
'binary1': binary1,
'binary2': binary2,
}[mockself.path].splitlines(True)
def __enter__(mockself):
return mockself
def __exit__(mockself, *args): # pylint: disable=unused-argument
pass
# pylint: enable=no-self-argument
fopen = MagicMock(side_effect=lambda x, *args, **kwargs: MockFopen(x))
cache_file = MagicMock(side_effect=lambda x, *args, **kwargs: x)
# Mocks for __utils__['files.is_text']
mock_text_text = MagicMock(side_effect=[True, True])
mock_bin_bin = MagicMock(side_effect=[False, False])
mock_text_bin = MagicMock(side_effect=[True, False])
mock_bin_text = MagicMock(side_effect=[False, True])
with patch.dict(filemod.__salt__, {'cp.cache_file': cache_file}), \
patch.object(salt.utils.files, 'fopen', fopen):
# Test diffing two text files
with patch.dict(filemod.__utils__, {'files.is_text': mock_text_text}):
# Identical files
ret = filemod.get_diff('text1', 'text1')
self.assertEqual(ret, '')
# Non-identical files
ret = filemod.get_diff('text1', 'text2')
self.assertEqual(
ret,
textwrap.dedent('''\
--- text1
+++ text2
@@ -1,4 +1,4 @@
foo
bar
baz
-спам
+яйца
''')
)
# Test diffing two binary files
with patch.dict(filemod.__utils__, {'files.is_text': mock_bin_bin}):
# Identical files
ret = filemod.get_diff('binary1', 'binary1')
self.assertEqual(ret, '')
# Non-identical files
ret = filemod.get_diff('binary1', 'binary2')
self.assertEqual(ret, 'Replace binary file')
# Test diffing a text file with a binary file
with patch.dict(filemod.__utils__, {'files.is_text': mock_text_bin}):
ret = filemod.get_diff('text1', 'binary1')
self.assertEqual(ret, 'Replace text file with binary file')
# Test diffing a binary file with a text file
with patch.dict(filemod.__utils__, {'files.is_text': mock_bin_text}):
ret = filemod.get_diff('binary1', 'text1')
self.assertEqual(ret, 'Replace binary file with text file')
@skipIf(pytest is None, 'PyTest required for this set of tests')
class FilemodLineTests(TestCase, LoaderModuleMockMixin):

View file

@ -19,11 +19,10 @@
# Import Python Libs
from __future__ import absolute_import, print_function, unicode_literals
import os
import errno
import subprocess
# Import Salt Testing Libs
from tests.support.unit import TestCase, skipIf
from tests.support.helpers import no_symlinks
from tests.support.mock import (
MagicMock,
patch,
@ -35,31 +34,6 @@ from tests.support.mock import (
from salt.modules.inspectlib.collector import Inspector
HAS_SYMLINKS = None
def no_symlinks():
'''
Check if git is installed and has symlinks enabled in the configuration.
'''
global HAS_SYMLINKS
if HAS_SYMLINKS is not None:
return not HAS_SYMLINKS
output = ''
try:
output = subprocess.check_output('git config --get core.symlinks', shell=True)
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
except subprocess.CalledProcessError:
# git returned non-zero status
pass
HAS_SYMLINKS = False
if output.strip() == 'true':
HAS_SYMLINKS = True
return not HAS_SYMLINKS
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(no_symlinks(), "Git missing 'core.symlinks=true' config")
class InspectorCollectorTestCase(TestCase):

View file

@ -60,38 +60,38 @@ class IptablesTestCase(TestCase, LoaderModuleMockMixin):
self.assertEqual(iptables.build_rule(**{'if': 'not eth0'}),
'! -i eth0')
self.assertEqual(iptables.build_rule(**{'proto': 'tcp', 'syn': '!'}),
self.assertEqual(iptables.build_rule(**{'protocol': 'tcp', 'syn': '!'}),
'-p tcp ! --syn')
self.assertEqual(iptables.build_rule(dports=[80, 443], proto='tcp'),
self.assertEqual(iptables.build_rule(dports=[80, 443], protocol='tcp'),
'-p tcp -m multiport --dports 80,443')
self.assertEqual(iptables.build_rule(dports='80,443', proto='tcp'),
self.assertEqual(iptables.build_rule(dports='80,443', protocol='tcp'),
'-p tcp -m multiport --dports 80,443')
# Should it really behave this way?
self.assertEqual(iptables.build_rule(dports=['!80', 443],
proto='tcp'),
protocol='tcp'),
'-p tcp -m multiport ! --dports 80,443')
self.assertEqual(iptables.build_rule(dports='!80,443', proto='tcp'),
self.assertEqual(iptables.build_rule(dports='!80,443', protocol='tcp'),
'-p tcp -m multiport ! --dports 80,443')
self.assertEqual(iptables.build_rule(sports=[80, 443], proto='tcp'),
self.assertEqual(iptables.build_rule(sports=[80, 443], protocol='tcp'),
'-p tcp -m multiport --sports 80,443')
self.assertEqual(iptables.build_rule(sports='80,443', proto='tcp'),
self.assertEqual(iptables.build_rule(sports='80,443', protocol='tcp'),
'-p tcp -m multiport --sports 80,443')
self.assertEqual(iptables.build_rule('filter', 'INPUT', command='I',
position='3', full=True,
dports='proto', jump='ACCEPT'),
'Error: proto must be specified')
dports='protocol', jump='ACCEPT'),
'Error: protocol must be specified')
self.assertEqual(iptables.build_rule('filter', 'INPUT', command='I',
position='3', full=True,
sports='proto', jump='ACCEPT'),
'Error: proto must be specified')
sports='protocol', jump='ACCEPT'),
'Error: protocol must be specified')
self.assertEqual(iptables.build_rule('', 'INPUT', command='I',
position='3', full='True',

View file

@ -94,18 +94,16 @@ class SSHAuthKeyTestCase(TestCase, LoaderModuleMockMixin):
comment_line = '# this is a comment\n'
# Write out the authorized key to a temporary file
if salt.utils.platform.is_windows():
temp_file = tempfile.NamedTemporaryFile(delete=False)
else:
temp_file = tempfile.NamedTemporaryFile(delete=False, mode='w+')
# Add comment
temp_file.write(comment_line)
# Add empty line for #41335
temp_file.write(empty_line)
temp_file.write('{0} {1} {2} {3}'.format(options, enc, key, email))
temp_file = tempfile.NamedTemporaryFile(delete=False, mode='w+')
temp_file.close()
with salt.utils.files.fopen(temp_file.name, 'w') as _fh:
# Add comment
_fh.write(comment_line)
# Add empty line for #41335
_fh.write(empty_line)
_fh.write('{0} {1} {2} {3}'.format(options, enc, key, email))
with patch.dict(ssh.__salt__, {'user.info': MagicMock(return_value={})}):
with patch('salt.modules.ssh._get_config_file', MagicMock(return_value=temp_file.name)):
ssh._replace_auth_key('foo', key, config=temp_file.name)

View file

@ -520,6 +520,21 @@ class MysqlPillarTestCase(TestCase):
)
def test_301_process_results_with_lists(self):
'''
Validates the following results:
{'a': [
{'c': [
{'e': 1},
{'g': 2}
]
},
{'h': [
{'j': 3, 'k': 4}
]
}
]}
'''
return_data = mysql.MySQLExtPillar()
return_data.as_list = False
return_data.with_lists = [1, 3]
@ -529,22 +544,49 @@ class MysqlPillarTestCase(TestCase):
['a', 'b', 'c', 'f', 'g', 2],
['a', 'z', 'h', 'y', 'j', 3],
['a', 'z', 'h', 'y', 'k', 4]])
self.assertEqual(
{'a': [
{'c': [
{'e': 1},
{'g': 2}
]
},
{'h': [
{'j': 3, 'k': 4}
]
}
]},
return_data.result
)
assert 'a' in return_data.result
for x in return_data.result['a']:
if 'c' in x:
assert list(x.keys()) == ['c'], x.keys()
for y in x['c']:
if 'e' in y:
assert list(y.keys()) == ['e']
assert y['e'] == 1
elif 'g' in y:
assert list(y.keys()) == ['g']
assert y['g'] == 2
else:
raise ValueError("Unexpected value {0}".format(y))
elif 'h' in x:
assert len(x['h']) == 1
for y in x['h']:
if 'j' in y:
assert len(y.keys()) == 2
assert y['j'] == 3
elif 'h' in y:
assert len(y.keys()) == 2
assert y['k'] == 4
else:
raise ValueError("Unexpected value {0}".format(y))
else:
raise ValueError("Unexpected value {0}".format(x))
def test_302_process_results_with_lists_consecutive(self):
'''
Validates the following results:
{'a': [
[[
{'e': 1},
{'g': 2}
]
],
[[
{'j': 3, 'k': 4}
]
]
]}
'''
return_data = mysql.MySQLExtPillar()
return_data.as_list = False
return_data.with_lists = [1, 2, 3]
@ -554,17 +596,31 @@ class MysqlPillarTestCase(TestCase):
['a', 'b', 'c', 'f', 'g', 2],
['a', 'z', 'h', 'y', 'j', 3],
['a', 'z', 'h', 'y', 'k', 4]])
self.assertEqual(
{'a': [
[[
{'e': 1},
{'g': 2}
]
],
[[
{'j': 3, 'k': 4}
]
]
]},
return_data.result
)
assert 'a' in return_data.result
for x in return_data.result['a']:
assert len(x) == 1
if len(x[0][0]) == 1:
for y in x[0]:
if 'e' in y:
assert list(y.keys()) == ['e']
assert y['e'] == 1
elif 'g' in y:
assert list(y.keys()) == ['g']
assert y['g'] == 2
else:
raise ValueError("Unexpected value {0}".format(y))
elif len(x[0][0]) == 2:
for y in x[0]:
if 'j' in y:
assert len(y.keys()) == 2
assert y['j'] == 3
elif 'k' in y:
assert len(y.keys()) == 2
assert y['k'] == 4
else:
raise ValueError(
"Unexpected value {0}".format(len(x[0][0]))
)
else:
raise ValueError("Unexpected value {0}".format(x))

View file

@ -207,7 +207,7 @@ class PipStateTest(TestCase, SaltReturnAssertsMixin, LoaderModuleMockMixin):
)
self.assertSaltTrueReturn({'test': ret})
self.assertInSaltComment(
'successfully installed',
'packages are already installed',
{'test': ret}
)
@ -241,7 +241,7 @@ class PipStateTest(TestCase, SaltReturnAssertsMixin, LoaderModuleMockMixin):
)
self.assertSaltTrueReturn({'test': ret})
self.assertInSaltComment(
'were successfully installed',
'packages are already installed',
{'test': ret}
)
@ -264,7 +264,7 @@ class PipStateTest(TestCase, SaltReturnAssertsMixin, LoaderModuleMockMixin):
)
self.assertSaltTrueReturn({'test': ret})
self.assertInSaltComment(
'were successfully installed',
'packages are already installed',
{'test': ret}
)

View file

@ -4,22 +4,27 @@ integration.grains.test_core
integration.loader.test_ext_grains
integration.loader.test_ext_modules
integration.modules.test_aliases
integration.modules.test_autoruns
integration.modules.test_beacons
integration.modules.test_config
integration.modules.test_cp
integration.modules.test_data
integration.modules.test_disk
integration.modules.test_firewall
integration.modules.test_git
integration.modules.test_grains
integration.modules.test_groupadd
integration.modules.test_hosts
integration.modules.test_mine
integration.modules.test_network
integration.modules.test_ntp
integration.modules.test_pillar
integration.modules.test_pkg
integration.modules.test_publish
integration.modules.test_state
integration.modules.test_status
integration.modules.test_sysmod
integration.modules.test_system
integration.modules.test_test
integration.modules.test_useradd
integration.reactor.test_reactor