mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2018.3' into 'develop'
Conflicts: - tests/unit/grains/test_core.py
This commit is contained in:
commit
bd184a257f
44 changed files with 1795 additions and 891 deletions
32
.github/CODEOWNERS
vendored
32
.github/CODEOWNERS
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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``.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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...',
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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']:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
25
tests/integration/modules/test_autoruns.py
Normal file
25
tests/integration/modules/test_autoruns.py
Normal 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))
|
110
tests/integration/modules/test_firewall.py
Normal file
110
tests/integration/modules/test_firewall.py
Normal 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)
|
60
tests/integration/modules/test_network.py
Normal file
60
tests/integration/modules/test_network.py
Normal 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)
|
30
tests/integration/modules/test_ntp.py
Normal file
30
tests/integration/modules/test_ntp.py
Normal 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])
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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']))
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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}
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue