Merge branch '2017.7' into parted-naming

This commit is contained in:
zer0def 2018-07-30 22:43:39 +02:00 committed by GitHub
commit 563ad25eb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
141 changed files with 5552 additions and 1088 deletions

50
.ci/docs Normal file
View file

@ -0,0 +1,50 @@
pipeline {
agent { label 'docs' }
options {
timestamps()
ansiColor('xterm')
}
environment {
PYENV_ROOT = "/usr/local/pyenv"
PATH = "$PYENV_ROOT/bin:$PATH"
PY_COLORS = 1
}
stages {
stage('github-pending') {
steps {
githubNotify credentialsId: 'test-jenkins-credentials',
description: 'Testing docs...',
status: 'PENDING',
context: "jenkins/pr/docs"
}
}
stage('setup') {
steps {
sh 'eval "$(pyenv init -)"; pyenv install 2.7.14 || echo "We already have this python."; pyenv local 2.7.14; pyenv shell 2.7.14'
sh 'eval "$(pyenv init -)"; pip install sphinx -e .'
}
}
stage('build') {
steps {
sh 'eval "$(pyenv init -)"; make -C doc clean html'
}
}
}
post {
always {
cleanWs()
}
success {
githubNotify credentialsId: 'test-jenkins-credentials',
description: 'The docs job has passed',
status: 'SUCCESS',
context: "jenkins/pr/docs"
}
failure {
githubNotify credentialsId: 'test-jenkins-credentials',
description: 'The docs job has failed',
status: 'FAILURE',
context: "jenkins/pr/docs"
}
}
}

71
.ci/kitchen-centos7-py2 Normal file
View file

@ -0,0 +1,71 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
PATH = "/usr/local/rbenv/shims/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin"
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py2"
TEST_PLATFORM = "centos-7"
PY_COLORS = 1
}
stages {
stage('github-pending') {
steps {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "running ${TEST_SUITE}-${TEST_PLATFORM}...",
status: 'PENDING',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
stage('setup') {
steps {
sh 'bundle install --with ec2 windows --without opennebula docker'
}
}
stage('run kitchen') {
steps {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM || bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM'
sh 'bundle exec kitchen verify $TEST_SUITE-$TEST_PLATFORM'
}
}}
}
post {
always {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen destroy $TEST_SUITE-$TEST_PLATFORM'
}
}}
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
}
}
}
}
post {
always {
junit 'artifacts/xml-unittests-output/*.xml'
cleanWs()
}
success {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has passed",
status: 'SUCCESS',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
failure {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has failed",
status: 'FAILURE',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
}

71
.ci/kitchen-centos7-py3 Normal file
View file

@ -0,0 +1,71 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
PATH = "/usr/local/rbenv/shims/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin"
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py3"
TEST_PLATFORM = "centos-7"
PY_COLORS = 1
}
stages {
stage('github-pending') {
steps {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "running ${TEST_SUITE}-${TEST_PLATFORM}...",
status: 'PENDING',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
stage('setup') {
steps {
sh 'bundle install --with ec2 windows --without opennebula docker'
}
}
stage('run kitchen') {
steps {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM || bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM'
sh 'bundle exec kitchen verify $TEST_SUITE-$TEST_PLATFORM'
}
}}
}
post {
always {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen destroy $TEST_SUITE-$TEST_PLATFORM'
}
}}
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
}
}
}
}
post {
always {
junit 'artifacts/xml-unittests-output/*.xml'
cleanWs()
}
success {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has passed",
status: 'SUCCESS',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
failure {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has failed",
status: 'FAILURE',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
}

View file

@ -0,0 +1,71 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
PATH = "/usr/local/rbenv/shims/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin"
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py2"
TEST_PLATFORM = "ubuntu-1604"
PY_COLORS = 1
}
stages {
stage('github-pending') {
steps {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "running ${TEST_SUITE}-${TEST_PLATFORM}...",
status: 'PENDING',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
stage('setup') {
steps {
sh 'bundle install --with ec2 windows --without opennebula docker'
}
}
stage('run kitchen') {
steps {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM || bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM'
sh 'bundle exec kitchen verify $TEST_SUITE-$TEST_PLATFORM'
}
}}
}
post {
always {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen destroy $TEST_SUITE-$TEST_PLATFORM'
}
}}
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
}
}
}
}
post {
always {
junit 'artifacts/xml-unittests-output/*.xml'
cleanWs()
}
success {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has passed",
status: 'SUCCESS',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
failure {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has failed",
status: 'FAILURE',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
}

View file

@ -0,0 +1,71 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
PATH = "/usr/local/rbenv/shims/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin"
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py3"
TEST_PLATFORM = "ubuntu-1604"
PY_COLORS = 1
}
stages {
stage('github-pending') {
steps {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "running ${TEST_SUITE}-${TEST_PLATFORM}...",
status: 'PENDING',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
stage('setup') {
steps {
sh 'bundle install --with ec2 windows --without opennebula docker'
}
}
stage('run kitchen') {
steps {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM || bundle exec kitchen converge $TEST_SUITE-$TEST_PLATFORM'
sh 'bundle exec kitchen verify $TEST_SUITE-$TEST_PLATFORM'
}
}}
}
post {
always {
script { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sshagent(credentials: ['jenkins-testing-ssh-key']) {
sh 'ssh-add ~/.ssh/jenkins-testing.pem'
sh 'bundle exec kitchen destroy $TEST_SUITE-$TEST_PLATFORM'
}
}}
archiveArtifacts artifacts: 'artifacts/xml-unittests-output/*.xml'
}
}
}
}
post {
always {
junit 'artifacts/xml-unittests-output/*.xml'
cleanWs()
}
success {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has passed",
status: 'SUCCESS',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
failure {
githubNotify credentialsId: 'test-jenkins-credentials',
description: "The ${TEST_SUITE}-${TEST_PLATFORM} job has failed",
status: 'FAILURE',
context: "jenkins/pr/${TEST_SUITE}-${TEST_PLATFORM}"
}
}
}

72
.ci/lint Normal file
View file

@ -0,0 +1,72 @@
pipeline {
agent { label 'pr-lint-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
PYENV_ROOT = "/usr/local/pyenv"
PATH = "$PYENV_ROOT/bin:$PATH"
PY_COLORS = 1
}
stages {
stage('github-pending') {
steps {
githubNotify credentialsId: 'test-jenkins-credentials',
description: 'Testing lint...',
status: 'PENDING',
context: "jenkins/pr/lint"
}
}
stage('setup') {
steps {
sh 'eval "$(pyenv init -)"; pyenv install 2.7.14 || echo "We already have this python."; pyenv local 2.7.14; pyenv shell 2.7.14'
sh 'eval "$(pyenv init -)"; pip install tox'
}
}
stage('linting') {
failFast false
parallel {
stage('salt linting') {
steps {
sh 'eval "$(pyenv init -)"; tox -e pylint-salt $(find salt/ -name "*.py" -exec git diff --name-only "origin/$CHANGE_TARGET" "origin/$BRANCH_NAME" setup.py {} +) | tee pylint-report.xml'
archiveArtifacts artifacts: 'pylint-report.xml'
}
}
stage('test linting') {
steps {
sh 'eval "$(pyenv init -)"; tox -e pylint-tests $(find tests/ -name "*.py" -exec git diff --name-only "origin/$CHANGE_TARGET" "origin/$BRANCH_NAME" {} +) | tee pylint-report-tests.xml'
archiveArtifacts artifacts: 'pylint-report-tests.xml'
}
}
}
}
}
post {
always {
step([$class: 'WarningsPublisher',
parserConfigurations: [[
parserName: 'PyLint',
pattern: 'pylint-report*.xml'
]],
failedTotalAll: '0',
useDeltaValues: false,
canRunOnFailed: true,
usePreviousBuildAsReference: true
])
cleanWs()
}
success {
githubNotify credentialsId: 'test-jenkins-credentials',
description: 'The lint job has passed',
status: 'SUCCESS',
context: "jenkins/pr/lint"
}
failure {
githubNotify credentialsId: 'test-jenkins-credentials',
description: 'The lint job has failed',
status: 'FAILURE',
context: "jenkins/pr/lint"
}
}
}

1
.github/CODEOWNERS vendored
View file

@ -48,6 +48,7 @@ salt/spm/* @saltstack/team-spm
# Team SSH
salt/cli/ssh.py @saltstack/team-ssh
salt/client/ssh/* @saltstack/team-ssh
salt/roster/* @saltstack/team-ssh
salt/runners/ssh.py @saltstack/team-ssh
salt/**/thin.py @saltstack/team-ssh

View file

@ -1,6 +1,6 @@
---
<% vagrant = system('gem list -i kitchen-vagrant 2>/dev/null >/dev/null') %>
<% version = '2017.7.4' %>
<% version = '2017.7.6' %>
<% platformsfile = ENV['SALT_KITCHEN_PLATFORMS'] || '.kitchen/platforms.yml' %>
<% driverfile = ENV['SALT_KITCHEN_DRIVER'] || '.kitchen/driver.yml' %>
<% verifierfile = ENV['SALT_KITCHEN_VERIFIER'] || '.kitchen/verifier.yml' %>
@ -31,7 +31,7 @@ provisioner:
salt_version: latest
salt_bootstrap_url: https://bootstrap.saltstack.com
salt_bootstrap_options: -X -p rsync stable <%= version %>
log_level: debug
log_level: info
sudo: true
require_chef: false
retry_on_exit_code:
@ -43,21 +43,20 @@ provisioner:
repo: git
testingdir: /testing
salt_copy_filter:
- __pycache__
- '*.pyc'
- .bundle
- .tox
- .kitchen
- .kitchen.yml
- artifacts
- Gemfile
- Gemfile.lock
- README.rst
- .travis.yml
state_top:
base:
"os:Windows":
- match: grain
- prep_windows
"*":
- git.salt
- <%= ENV['KITCHEN_STATE'] || 'git.salt' %>
pillars:
top.sls:
base:

View file

@ -138,7 +138,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="http://saltstack.com/" target="_blank"><img src="{{ pathto('_static/images/saltstack.svg', 1) }}" class="nolightbox" height="40px" width="170px"></a>
<a href="http://saltstack.com/" target="_blank"><img src="{{ pathto('_static/images/SaltStack_white.svg', 1) }}" class="nolightbox" height="40px" width="170px"></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="navbarCollapse">
@ -252,13 +252,11 @@
<p>© {{ copyright }} SaltStack. All Rights Reserved, SaltStack Inc. | <a href="http://saltstack.com/privacy-policy" target="_blank">Privacy Policy</a></p>
</div>
</div>
<div class="col-sm-6">
<!--
<a href="https://saltstack.com/saltstack-enterprise/" target="_blank"><img class="nolightbox footer-banner center" src="{{ pathto('_static/images/enterprise_ad.jpg', 1) }}"/></a>
-->
<a href="http://saltconf.com" target="_blank"><img class="nolightbox footer-banner center" src="{{ pathto('_static/images/DOCBANNER.jpg', 1) }}"/></a>
</div>
{% endif %}
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 589 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 301.57 44.47"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Asset 2</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M50.63,6.05h8.79L72.58,43.24H64.15L61.7,35.6H48l-2.52,7.64H37.35Zm-.51,23.14h9.52l-4.7-14.64Z"/><path class="cls-1" d="M76.12,6.05h7.77V36.56h18.58v6.68H76.12Z"/><path class="cls-1" d="M127.07,6.05v6.58H115.94V43.24h-7.82V12.63H96.94V6.05Z"/><path class="cls-1" d="M190.53,6.05v6.58H179.41V43.24h-7.83V12.63H160.4V6.05Z"/><path class="cls-1" d="M200.41,6.05h8.8l13.16,37.19h-8.43l-2.45-7.64h-13.7l-2.52,7.64h-8.13Zm-.51,23.14h9.53l-4.7-14.64Z"/><path class="cls-1" d="M227.91,10.17a15.34,15.34,0,0,1,11.34-4.83q9.28-.2,13.71,5.87a13.46,13.46,0,0,1,2.69,6.89l-7.77.16a10.78,10.78,0,0,0-2-4A7.68,7.68,0,0,0,239.68,12a7.59,7.59,0,0,0-6.48,3.56Q230.88,19,231,25.25t2.73,9.32a7.91,7.91,0,0,0,6.49,3,7.27,7.27,0,0,0,6-2.8,11.86,11.86,0,0,0,1.84-4.35l7.72-.17a16.79,16.79,0,0,1-4.9,10,14.83,14.83,0,0,1-10.44,4q-7.94.16-12.59-4.88t-4.84-14.09Q222.85,15.56,227.91,10.17Z"/><path class="cls-1" d="M260.39,6.05H268V21.37L282.4,6.05h10.05L277.18,21.34l16.05,21.9h-10L271.78,27,268,30.8V43.24h-7.64Z"/><path class="cls-1" d="M15.65,12.47a9.05,9.05,0,0,1,4.6-1.05,10.15,10.15,0,0,1,4.63.94,5.29,5.29,0,0,1,3,4.77h7.47a11.06,11.06,0,0,0-4.4-9A16.57,16.57,0,0,0,20.79,5a23,23,0,0,0-5.14.54Z"/><path class="cls-1" d="M33.21,24.77a16.6,16.6,0,0,0-6.43-2.7l-6.53-1.54A22.45,22.45,0,0,1,15.31,19a3.18,3.18,0,0,1-1.81-3c0-.12,0-.22,0-.34H6.35c0,.3,0,.59,0,.9q0,5.47,3.76,8.05,2.22,1.54,8.15,2.85l4,.89a17.48,17.48,0,0,1,5.17,1.74A3.17,3.17,0,0,1,29,33c0,2.1-1.1,3.54-3.32,4.31a14.08,14.08,0,0,1-4.56.61c-3.13,0-5.33-.77-6.62-2.3a7.48,7.48,0,0,1-1.42-3.81H5.7a11,11,0,0,0,4.21,9.12q4.22,3.33,11.56,3.32,7.19,0,11.13-3.37a10.64,10.64,0,0,0,3.94-8.46A9.1,9.1,0,0,0,33.21,24.77Z"/><path class="cls-1" d="M137.55,12.73a9,9,0,0,1,4.6-1.05,10.18,10.18,0,0,1,4.63.94,5.33,5.33,0,0,1,3,4.77h7.47a11,11,0,0,0-4.41-9,16.54,16.54,0,0,0-10.15-3.12,23,23,0,0,0-5.14.54Z"/><path class="cls-1" d="M155.11,25a16.83,16.83,0,0,0-6.43-2.7l-6.53-1.54a21.71,21.71,0,0,1-4.94-1.54,3.17,3.17,0,0,1-1.81-3c0-.13,0-.23,0-.35h-7.19c0,.3-.05.6-.05.9,0,3.65,1.26,6.34,3.77,8.05,1.48,1,4.19,2,8.15,2.85l4,.89a17.29,17.29,0,0,1,5.16,1.74,3.16,3.16,0,0,1,1.63,2.85q0,3.15-3.32,4.32a14.39,14.39,0,0,1-4.56.6c-3.13,0-5.34-.76-6.62-2.3A7.48,7.48,0,0,1,135,32H127.6a11,11,0,0,0,4.21,9.13c2.8,2.21,6.66,3.32,11.55,3.32s8.51-1.13,11.14-3.37a10.7,10.7,0,0,0,3.94-8.47A9.1,9.1,0,0,0,155.11,25Z"/><rect class="cls-1" width="9.85" height="9.85"/><path class="cls-1" d="M299.8,40.44a.94.94,0,0,0,.16-.57,1.06,1.06,0,0,0-.08-.45.82.82,0,0,0-.24-.32,1,1,0,0,0-.38-.19,1.72,1.72,0,0,0-.52-.07h-1.2v3.4h.59V40.93h.66l.68,1.31h.63v0l-.76-1.42A1,1,0,0,0,299.8,40.44Zm-.59-.14a.52.52,0,0,1-.19.12,1.18,1.18,0,0,1-.28,0h-.61V39.32h.61a.79.79,0,0,1,.28,0,.55.55,0,0,1,.2.11.76.76,0,0,1,.12.19.85.85,0,0,1,0,.23.56.56,0,0,1,0,.23A.36.36,0,0,1,299.21,40.3Z"/><path class="cls-1" d="M298.7,37.68a2.88,2.88,0,1,0,2.87,2.87A2.88,2.88,0,0,0,298.7,37.68Zm0,5.27a2.4,2.4,0,1,1,2.39-2.4A2.41,2.41,0,0,1,298.7,43Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -250,8 +250,8 @@ on_saltstack = 'SALT_ON_SALTSTACK' in os.environ
project = 'Salt'
version = salt.version.__version__
latest_release = '2018.3.0' # latest release
previous_release = '2017.7.5' # latest release from previous branch
latest_release = '2018.3.2' # latest release
previous_release = '2017.7.7' # latest release from previous branch
previous_release_dir = '2017.7' # path on web server for previous branch
next_release = '' # next release
next_release_dir = '' # path on web server for next release branch

View file

@ -148,22 +148,23 @@ Why aren't my custom modules/states/etc. available on my Minions?
-----------------------------------------------------------------
Custom modules are synced to Minions when
:mod:`saltutil.sync_modules <salt.modules.saltutil.sync_modules>`,
or :mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>` is run.
Custom modules are also synced by :mod:`state.apply` when run without
any arguments.
:py:func:`saltutil.sync_modules <salt.modules.saltutil.sync_modules>`,
or :py:func:`saltutil.sync_all <salt.modules.saltutil.sync_all>` is run.
Similarly, custom states are synced to Minions when :py:func:`saltutil.sync_states
<salt.modules.saltutil.sync_states>`, or :py:func:`saltutil.sync_all
<salt.modules.saltutil.sync_all>` is run.
Similarly, custom states are synced to Minions
when :mod:`state.apply <salt.modules.state.apply_>`,
:mod:`saltutil.sync_states <salt.modules.saltutil.sync_states>`, or
:mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>` is run.
They are both also synced when a :ref:`highstate <running-highstate>` is
triggered.
Custom states are also synced by :mod:`state.apply<salt.modules.state.apply_>`
when run without any arguments.
As of the Fluorine release, as well as 2017.7.7 and 2018.3.2 in their
respective release cycles, the ``sync`` argument to :py:func:`state.apply
<salt.modules.state.apply_>`/:py:func:`state.sls <salt.modules.state.sls>` can
be used to sync custom types when running individual SLS files.
Other custom types (renderers, outputters, etc.) have similar behavior, see the
documentation for the :mod:`saltutil <salt.modules.saltutil>` module for more
documentation for the :py:func:`saltutil <salt.modules.saltutil>` module for more
information.
:ref:`This reactor example <minion-start-reactor>` can be used to automatically

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-API" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-API" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-api \- salt-api Command
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-CALL" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-CALL" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-call \- salt-call Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-CLOUD" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-CLOUD" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-cloud \- Salt Cloud Command
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-CP" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-CP" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-cp \- salt-cp Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-KEY" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-KEY" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-key \- salt-key Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-MASTER" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-MASTER" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-master \- salt-master Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-MINION" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-MINION" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-minion \- salt-minion Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-PROXY" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-PROXY" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-proxy \- salt-proxy Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-RUN" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-RUN" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-run \- salt-run Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-SSH" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-SSH" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-ssh \- salt-ssh Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-SYNDIC" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-SYNDIC" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-syndic \- salt-syndic Documentation
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT-UNITY" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT-UNITY" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt-unity \- salt-unity Command
.

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SALT" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SALT" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
salt \- salt
.

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "SPM" "1" "May 07, 2018" "2017.7.6" "Salt"
.TH "SPM" "1" "Jun 14, 2018" "2017.7.7" "Salt"
.SH NAME
spm \- Salt Package Manager Command
.

View file

@ -1162,6 +1162,40 @@ The password used for HTTP proxy access.
proxy_password: obolus
Docker Configuration
====================
.. conf_minion:: docker.update_mine
``docker.update_mine``
----------------------
.. versionadded:: 2017.7.8,2018.3.3
.. versionchanged:: Fluorine
The default value is now ``False``
Default: ``True``
If enabled, when containers are added, removed, stopped, started, etc., the
:ref:`mine <salt-mine>` will be updated with the results of :py:func:`docker.ps
verbose=True all=True host=True <salt.modules.dockermod.ps>`. This mine data is
used by :py:func:`mine.get_docker <salt.modules.mine.get_docker>`. Set this
option to ``False`` to keep Salt from updating the mine with this information.
.. note::
This option can also be set in Grains or Pillar data, with Grains
overriding Pillar and the minion config file overriding Grains.
.. note::
Disabling this will of course keep :py:func:`mine.get_docker
<salt.modules.mine.get_docker>` from returning any information for a given
minion.
.. code-block:: yaml
docker.update_mine: False
Minion Module Management
========================

View file

@ -21,11 +21,21 @@ SaltStack has its own coding style guide that informs contributors on various co
approaches. Please review the :ref:`Salt Coding Style <coding-style>` documentation
for information about Salt's particular coding patterns.
Within the :ref:`Salt Coding Style <coding-style>` documentation, there is a section
about running Salt's ``.pylintrc`` file. SaltStack recommends running the ``.pylintrc``
file on any files you are changing with your code contribution before submitting a
pull request to Salt's repository. Please see the :ref:`Linting<pylint-instructions>`
documentation for more information.
Within the :ref:`Salt Coding Style <coding-style>` documentation, there is a
section about running Salt's ``.testing.pylintrc`` file. SaltStack recommends
running the ``.testing.pylintrc`` file on any files you are changing with your
code contribution before submitting a pull request to Salt's repository. Please
see the :ref:`Linting<pylint-instructions>` documentation for more information.
.. note::
There are two pylint files in the ``salt`` directory. One is the
``.pylintrc`` file and the other is the ``.testing.pylintrc`` file. The
tests that run in Jenkins against GitHub Pull Requests use
``.testing.pylintrc``. The ``testing.pylintrc`` file is a little less
strict than the ``.pylintrc`` and is used to make it easier for contributors
to submit changes. The ``.pylintrc`` file can be used for linting, but the
``testing.pylintrc`` is the source of truth when submitting pull requests.
.. _github-pull-request:

View file

@ -22,21 +22,31 @@ improve Salt)!!
Linting
=======
Most Salt style conventions are codified in Salt's ``.pylintrc`` file. Salt's
pylint file has two dependencies: pylint_ and saltpylint_. You can install
these dependencies with ``pip``:
Most Salt style conventions are codified in Salt's ``.testing.pylintrc`` file.
Salt's pylint file has two dependencies: pylint_ and saltpylint_. You can
install these dependencies with ``pip``:
.. code-block:: bash
pip install pylint
pip install saltpylint
The ``.pylintrc`` file is found in the root of the Salt project and can be passed
as an argument to the pylint_ program as follows:
The ``.testing.pylintrc`` file is found in the root of the Salt project and can
be passed as an argument to the pylint_ program as follows:
.. code-block:: bash
pylint --rcfile=/path/to/salt/.pylintrc salt/dir/to/lint
pylint --rcfile=/path/to/salt/.testing.pylintrc salt/dir/to/lint
.. note::
There are two pylint files in the ``salt`` directory. One is the
``.pylintrc`` file and the other is the ``.testing.pylintrc`` file. The
tests that run in Jenkins against GitHub Pull Requests use
``.testing.pylintrc``. The ``testing.pylintrc`` file is a little less
strict than the ``.pylintrc`` and is used to make it easier for contributors
to submit changes. The ``.pylintrc`` file can be used for linting, but the
``testing.pylintrc`` is the source of truth when submitting pull requests.
.. _pylint: http://www.pylint.org
.. _saltpylint: https://github.com/saltstack/salt-pylint

View file

@ -1,11 +1,8 @@
========================================
In Progress: Salt 2017.7.6 Release Notes
========================================
Version 2017.7.6 is an **unreleased** bugfix release for :ref:`2017.7.0
<release-2017-7-0>`. This release is still in progress and has not been
released yet.
===========================
Salt 2017.7.6 Release Notes
===========================
Version 2017.7.6 is a bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
Statistics
==========
@ -16,6 +13,15 @@ Statistics
- Contributors: **47** (`Ch3LL`_, `DmitryKuzmenko`_, `GwiYeong`_, `Quarky9`_, `RichardW42`_, `UtahDave`_, `amaclean199`_, `arif-ali`_, `baniobloom`_, `bdrung`_, `benediktwerner`_, `bmiguel-teixeira`_, `cachedout`_, `dafenko`_, `damon-atkins`_, `dwoz`_, `ezh`_, `folti`_, `fpicot`_, `frogunder`_, `garethgreenaway`_, `gtmanfred`_, `isbm`_, `jeroennijhof`_, `jfindlay`_, `jfoboss`_, `kstreee`_, `lomeroe`_, `mattp-`_, `meaksh`_, `mirceaulinic`_, `myinitialsarepm`_, `mzbroch`_, `nages13`_, `paclat`_, `pcjeff`_, `pruiz`_, `psyer`_, `rallytime`_, `s0undt3ch`_, `skizunov`_, `smitty42`_, `terminalmage`_, `twangboy`_, `vutny`_, `yagnik`_, `yannj-fr`_)
Tornado 5.0 Support for Python 2 Only
-------------------------------------
Tornado 5.0 moves to using asyncio for all python3 versions. Because of this
and changes in asyncio between python 3.4 and 3.5 to only be able to use one
ioloop, which requires some rearchitecting, support for tornado 5.0 and python3
versions of salt has been delayed to a later release.
For now, to use tornado 5.0, the python 2 version of salt must be used.
Option to Return to Previous Pillar Include Behavior
====================================================

View file

@ -1,19 +1,89 @@
========================================
In Progress: Salt 2017.7.7 Release Notes
========================================
===========================
Salt 2017.7.7 Release Notes
===========================
Version 2017.7.7 is an **unreleased** bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
This release is still in progress and has not been released yet.
Version 2017.7.7 is a bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
New win_snmp behavior
=====================
The ``2017.7.7`` release contains only a small number of fixes, which are detailed
below.
- :py:func:`win_snmp.get_community_names
<salt.modules.win_snmp.get_community_names>` now returns the SNMP settings
actually in effect on the box. If settings are managed via GroupPolicy, those
settings will be returned. Otherwise, normal settings are returned.
This release fixes two critical issues.
- :py:func:`win_snmp.set_community_names
<salt.modules.win_snmp.set_community_names>` now raises an error when SNMP
settings are being managed by GroupPolicy.
The first is Issue `#48038`_, which is a critical bug that occurs in a multi-syndic
setup where the same job is run multiple times on a minion.
The second issue is `#48130`_. This bug appears in certain setups where the Master
reports a Minion time-out, even though the job is still running on the Minion.
Both of these issues have been fixed with this release.
Statistics
==========
- Total Merges: **5**
- Total Issue References: **2**
- Total PR References: **6**
- Contributors: **3** (`garethgreenaway`_, `gtmanfred`_, `rallytime`_)
Changelog for v2017.7.6..v2017.7.7
==================================
*Generated at: 2018-06-17 19:26:52 UTC*
* **ISSUE** `#48130`_: (`rmarchei`_) Minion timeouts with 2018.3.1 (refs: `#48157`_)
* **PR** `#48157`_: (`gtmanfred`_) always listen when gathering job info
@ *2018-06-17 19:04:09 UTC*
* 8af4452134 Merge pull request `#48157`_ from gtmanfred/2017.7.7
* d8209e8a40 always listen when gathering job info
* **PR** `#48140`_: (`rallytime`_) Update man pages for 2017.7.7
@ *2018-06-14 21:22:43 UTC*
* b98c52ee51 Merge pull request `#48140`_ from rallytime/man-pages-2017.7.7
* 8893bf0d4c Update man pages for 2017.7.7
* **PR** `#48136`_: (`gtmanfred`_) [2017.7.7] bootstrap kitchen branch tests with 2017.7.6
@ *2018-06-14 21:20:16 UTC*
* baa0363336 Merge pull request `#48136`_ from gtmanfred/2017.7.7
* fce1c31146 bootstrap kitchen branch tests with 2017.7.6
* **PR** `#48134`_: (`rallytime`_) Add release notes file for 2017.7.7
@ *2018-06-14 16:31:34 UTC*
* b0ba08f4d9 Merge pull request `#48134`_ from rallytime/release-notes-2017.7.7
* 217005b8f1 Add missing `v` for tag reference
* d53569d1e3 Add release notes file for 2017.7.7
* **ISSUE** `#48038`_: (`austinpapp`_) jobs are not dedup'ing minion side (refs: `#48075`_)
* **PR** `#48098`_: (`rallytime`_) Back-port `#48075`_ to 2017.7.7
@ *2018-06-14 12:53:42 UTC*
* **PR** `#48075`_: (`garethgreenaway`_) [2017.7] Ensure that the shared list of jids is passed (refs: `#48098`_)
* 084de927fe Merge pull request `#48098`_ from rallytime/bp-48075-2017.7.7
* e4e62e8b3a Ensure that the shared list of jids is passed when creating the Minion. Fixes an issue when minions are pointed at multiple syndics.
.. _`#48038`: https://github.com/saltstack/salt/issues/48038
.. _`#48075`: https://github.com/saltstack/salt/pull/48075
.. _`#48098`: https://github.com/saltstack/salt/pull/48098
.. _`#48130`: https://github.com/saltstack/salt/issues/48130
.. _`#48134`: https://github.com/saltstack/salt/pull/48134
.. _`#48136`: https://github.com/saltstack/salt/pull/48136
.. _`#48140`: https://github.com/saltstack/salt/pull/48140
.. _`#48157`: https://github.com/saltstack/salt/pull/48157
.. _`austinpapp`: https://github.com/austinpapp
.. _`garethgreenaway`: https://github.com/garethgreenaway
.. _`gtmanfred`: https://github.com/gtmanfred
.. _`rallytime`: https://github.com/rallytime
.. _`rmarchei`: https://github.com/rmarchei

View file

@ -0,0 +1,31 @@
========================================
In Progress: Salt 2017.7.8 Release Notes
========================================
Version 2017.7.8 is an **unreleased** bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
This release is still in progress and has not been released yet.
New win_snmp behavior
=====================
- :py:func:`win_snmp.get_community_names
<salt.modules.win_snmp.get_community_names>` now returns the SNMP settings
actually in effect on the box. If settings are managed via GroupPolicy, those
settings will be returned. Otherwise, normal settings are returned.
- :py:func:`win_snmp.set_community_names
<salt.modules.win_snmp.set_community_names>` now raises an error when SNMP
settings are being managed by GroupPolicy.
Option Added to Disable Docker Mine Updates
===========================================
When a docker container is added, removed, started, stopped, etc., the results
of a :py:func:`docker.ps verbose=True all=True host=True
<salt.modules.dockermod.ps>` are sent to the :ref:`mine <salt-mine>`, to be
used by :py:func:`mine.get_docker <salt.modules.mine.get_docker>`.
A new config option (:conf_minion:`docker.update_mine`) has been added. When
set to ``False``, Salt will not send this information to the mine. This is
useful in cases where sensitive information is stored in the container's
environment.

View file

@ -509,9 +509,8 @@ overrides all levels below it):
.. code-block:: yaml
gitfs_saltenv:
- saltenv:
- dev:
- mountpoint: salt://bar
- dev:
- mountpoint: salt://bar
3. Per-remote configuration parameter

View file

@ -330,7 +330,13 @@ Nested pillar values can also be set via the command line:
.. code-block:: bash
salt '*' state.sls my_sls_file pillar='{"foo": {"bar": "baz"}}'
salt '*' state.sls my_sls_file pillar='{"foo": {"bar": "baz"}}'
Lists can be passed via command line pillar data as follows:
.. code-block:: bash
salt '*' state.sls my_sls_file pillar='{"some_list": ["foo", "bar", "baz"]}'
.. note::

View file

@ -135,13 +135,18 @@ where it is necessary to invoke the same function from a custom :ref:`outputter
<all-salt.output>`/returner, as well as an execution module.
Utility modules placed in ``salt://_utils/`` will be synced to the minions when
any of the following Salt functions are called:
a :ref:`highstate <running-highstate>` is run, as well as when any of the
following Salt functions are called:
* :mod:`state.apply <salt.modules.state.apply_>`
* :mod:`saltutil.sync_utils <salt.modules.saltutil.sync_utils>`
* :mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>`
* :py:func:`saltutil.sync_utils <salt.modules.saltutil.sync_utils>`
* :py:func:`saltutil.sync_all <salt.modules.saltutil.sync_all>`
As of the Fluorine release, as well as 2017.7.7 and 2018.3.2 in their
respective release cycles, the ``sync`` argument to :py:func:`state.apply
<salt.modules.state.apply_>`/:py:func:`state.sls <salt.modules.state.sls>` can
be used to sync custom types when running individual SLS files.
To sync to the Master, use either of the following:
* :mod:`saltutil.sync_utils <salt.runners.saltutil.sync_utils>`
* :mod:`saltutil.sync_all <salt.runners.saltutil.sync_all>`
* :py:func:`saltutil.sync_utils <salt.runners.saltutil.sync_utils>`
* :py:func:`saltutil.sync_all <salt.runners.saltutil.sync_all>`

View file

@ -197,17 +197,17 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Updating PIP and SetupTools . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_PIP_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
} else {
$p = New-Item $Env:SALT_PIP_LOCAL_CACHE -ItemType Directory -Force # Ensure directory exists
if ( (Get-ChildItem $Env:SALT_PIP_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req_pip.txt into empty local cache SALT_REQ_PIP $Env:SALT_PIP_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_PIP_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
}
#==============================================================================
@ -218,16 +218,16 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Installing pypi resources using pip . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_REQ_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req.txt" "pip install"
} else {
if ( (Get-ChildItem $Env:SALT_REQ_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req.txt into empty local cache SALT_REQ $Env:SALT_REQ_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_REQ_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
}
#==============================================================================

View file

@ -197,17 +197,17 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Updating PIP and SetupTools . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_PIP_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
} else {
$p = New-Item $Env:SALT_PIP_LOCAL_CACHE -ItemType Directory -Force # Ensure directory exists
if ( (Get-ChildItem $Env:SALT_PIP_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req_pip.txt into empty local cache SALT_REQ_PIP $Env:SALT_PIP_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_PIP_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
}
#==============================================================================
@ -218,16 +218,16 @@ Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Installing pypi resources using pip . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_REQ_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --no-cache-dir install -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req.txt" "pip install"
} else {
if ( (Get-ChildItem $Env:SALT_REQ_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req.txt into empty local cache SALT_REQ $Env:SALT_REQ_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_REQ_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
}
#==============================================================================

View file

@ -130,20 +130,18 @@ If Defined ProgramFiles(x86) (
)
@echo.
@echo Copying VCRedist to Prerequisites
@echo ----------------------------------------------------------------------
:: Make sure the "prereq" directory exists
If NOT Exist "%PreDir%" mkdir "%PreDir%"
:: Set the location of the vcredist to download
If %Python%==3 (
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2015.exe"
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2015.exe"
:: Don't include the vcredist for Py3 installations
If %Python%==3 goto :vcredist_end
) Else (
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2008_mfc.exe"
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2008_mfc.exe"
)
@echo Copying VCRedist to Prerequisites
@echo ----------------------------------------------------------------------
:: Set the location of the vcredist to download
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2008_mfc.exe"
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2008_mfc.exe"
:: Check for 64 bit by finding the Program Files (x86) directory
If Defined ProgramFiles(x86) (
@ -153,6 +151,8 @@ If Defined ProgramFiles(x86) (
)
@echo.
:vcredist_end
:: Remove the fixed path in .exe files
@echo Removing fixed path from .exe files
@echo ----------------------------------------------------------------------

View file

@ -211,26 +211,13 @@ Section -Prerequisites
Var /Global CheckVcRedist
StrCpy $CheckVcRedist "False"
# Visual C++ 2015 redist packages
!define PY3_VC_REDIST_NAME "VC_Redist_2015"
!define PY3_VC_REDIST_X64_GUID "{50A2BC33-C9CD-3BF1-A8FF-53C10A0B183C}"
!define PY3_VC_REDIST_X86_GUID "{BBF2AC74-720C-3CB3-8291-5E34039232FA}"
# Visual C++ 2008 SP1 MFC Security Update redist packages
!define PY2_VC_REDIST_NAME "VC_Redist_2008_SP1_MFC"
!define PY2_VC_REDIST_X64_GUID "{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}"
!define PY2_VC_REDIST_X86_GUID "{9BE518E6-ECC6-35A9-88E4-87755C07200F}"
${If} ${PYTHON_VERSION} == 3
StrCpy $VcRedistName ${PY3_VC_REDIST_NAME}
${If} ${CPUARCH} == "AMD64"
StrCpy $VcRedistGuid ${PY3_VC_REDIST_X64_GUID}
${Else}
StrCpy $VcRedistGuid ${PY3_VC_REDIST_X86_GUID}
${EndIf}
StrCpy $CheckVcRedist "True"
${Else}
# VCRedist only needs to be installed for Python 2
${If} ${PYTHON_VERSION} == 2
StrCpy $VcRedistName ${PY2_VC_REDIST_NAME}
${If} ${CPUARCH} == "AMD64"

View file

@ -77,6 +77,7 @@ Function Get-Settings {
"SSLeay" = "ssleay32.dll"
"OpenSSLLic" = "OpenSSL_License.txt"
"msvcr" = "msvcr120.dll"
"Libsodium" = "libsodium.dll"
}
$ini.Add("64bitDLLs", $64bitDLLs)
@ -86,6 +87,7 @@ Function Get-Settings {
"SSLeay" = "ssleay32.dll"
"OpenSSLLic" = "OpenSSL_License.txt"
"msvcr" = "msvcr120.dll"
"Libsodium" = "libsodium.dll"
}
$ini.Add("32bitDLLs", $32bitDLLs)

View file

@ -9,34 +9,36 @@ salt for Windows with their corresponding licenses:
| certifi | ISC |
| cffi | MIT |
| CherryPy | BSD |
| cryptography | BSD |
| enum34 | BSD |
| futures | BSD |
| gitdb | BSD |
| GitPython | BSD |
| idna | BSD-like |
| ioflo | Apache 2.0 |
| ioloop | MIT |
| ipaddress | PSF |
| Jinja2 | BSD |
| libnacl | --- |
| libnacl | Apache |
| lxml | BSD |
| Mako | MIT |
| MarkupSafe | BSD |
| msgpack-python | --- |
| msgpack-python | Apache 2.0 |
| pip | MIT |
| psutil | BSD |
| pyasn1 | BSD |
| pycparser | BSD |
| pycurl | LGPL + MIT |
| PyMySQL | MIT |
| pypiwin32 | PSF |
| PyOpenSSL | Apache 2.0 |
| python-certifi-win32 | BSD |
| python-dateutil | Simplified BSD |
| python-gnupg | BSD |
| pywin32 | PSF |
| PyYAML | MIT |
| pyzmq | LGPL + BSD |
| requests | Apache 2.0 |
| setuptools | MIT |
| singledispatch | MIT |
| six | MIT |
| smmap | BSD |
| timelib | ZLIB/PHP |
| tornado | Apache 2.0 |

View file

@ -12,6 +12,7 @@ idna==2.5
ioloop==0.1a0
ipaddress==1.0.18
Jinja2==2.9.6
libnacl==1.6.1 # required by the nacl module
lxml==3.7.3
Mako==1.0.6
MarkupSafe==1.0
@ -23,6 +24,7 @@ pycrypto==2.6.1
pycurl==7.43.0
PyMySQL==0.7.11
pyOpenSSL==17.0.0
#python-certifi-win32==1.2
python-dateutil==2.6.0
python-gnupg==0.4.0
pywin32==223

View file

@ -1,4 +0,0 @@
[pytest]
addopts = --ssh-tests -ra -sv
testpaths = tests
norecursedirs = tests/kitchen

View file

@ -7,5 +7,6 @@ MarkupSafe
requests>=1.0.0
tornado>=4.2.1,<6.0; python_version < '3'
tornado>=4.2.1,<5.0; python_version >= '3.4'
# Required by Tornado to handle threads stuff.
futures>=2.0; python_version < '3.0'

View file

@ -10,3 +10,4 @@ git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt
# satisfy other requirements, and httpretty 0.8.10 has bugs in setup.py that
# prevent it from being successfully installed (at least on Python 3.4).
httpretty; python_version >= '3.4'
pylint==1.6.5

View file

@ -1,3 +1,4 @@
pytest>=3.5.0
pytest-helpers-namespace
pytest-tempdir
pytest-cov

View file

@ -1,4 +1,5 @@
-r base.txt
pycrypto>=2.6.1
pyzmq>=2.2.0
pyzmq>=2.2.0,<17.1.0; python_version == '3.4' # pyzmq 17.1.0 stopped building wheels for python3.4
pyzmq>=2.2.0; python_version != '3.4'

View file

@ -221,7 +221,7 @@ class LocalClient(object):
# Looks like the timeout is invalid, use config
return self.opts['timeout']
def gather_job_info(self, jid, tgt, tgt_type, **kwargs):
def gather_job_info(self, jid, tgt, tgt_type, listen=True, **kwargs):
'''
Return the information about a given job
'''
@ -233,6 +233,7 @@ class LocalClient(object):
arg=[jid],
tgt_type=tgt_type,
timeout=timeout,
listen=listen,
**kwargs
)

View file

@ -1106,7 +1106,10 @@ ARGS = {10}\n'''.format(self.minion_config,
shim_tmp_file.write(salt.utils.to_bytes(cmd_str))
# Copy shim to target system, under $HOME/.<randomized name>
target_shim_file = '.{0}.{1}'.format(binascii.hexlify(os.urandom(6)), extension)
target_shim_file = '.{0}.{1}'.format(
binascii.hexlify(os.urandom(6)).decode('ascii'),
extension
)
if self.winrm:
target_shim_file = saltwinshell.get_target_shim_file(self, target_shim_file)
self.shell.send(shim_tmp_file.name, target_shim_file, makedirs=True)

View file

@ -164,7 +164,7 @@ def salt_refs(data, ret=None):
return ret
def prep_trans_tar(opts, file_client, chunks, file_refs, pillar=None, id_=None):
def prep_trans_tar(file_client, chunks, file_refs, pillar=None, id_=None):
'''
Generate the execution package from the saltenv file refs and a low state
data structure

View file

@ -32,6 +32,59 @@ __func_alias__ = {
log = logging.getLogger(__name__)
def _ssh_state(chunks, st_kwargs,
kwargs, test=False):
'''
Function to run a state with the given chunk via salt-ssh
'''
file_refs = salt.client.ssh.state.lowstate_file_refs(
chunks,
_merge_extra_filerefs(
kwargs.get('extra_filerefs', ''),
__opts__.get('extra_filerefs', '')
)
)
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
__context__['fileclient'],
chunks,
file_refs,
__pillar__,
st_kwargs['id_'])
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__['hash_type'])
cmd = 'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
__opts__['thin_dir'],
test,
trans_tar_sum,
__opts__['hash_type'])
single = salt.client.ssh.Single(
__opts__,
cmd,
fsclient=__context__['fileclient'],
minion_opts=__salt__.minion_opts,
**st_kwargs)
single.shell.send(
trans_tar,
'{0}/salt_state.tgz'.format(__opts__['thin_dir']))
stdout, stderr, _ = single.cmd_block()
# Clean up our tar
try:
os.remove(trans_tar)
except (OSError, IOError):
pass
# Read in the JSON data and return the data structure
try:
return json.loads(stdout, object_hook=salt.utils.decode_dict)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(str(e))
# If for some reason the json load fails, return the stdout
return stdout
def _set_retcode(ret, highstate=None):
'''
Set the return code based on the data back from the state system
@ -156,7 +209,6 @@ def sls(mods, saltenv='base', test=None, exclude=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
@ -323,7 +375,6 @@ def low(data, **kwargs):
)
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
@ -408,7 +459,6 @@ def high(data, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
@ -642,7 +692,6 @@ def highstate(test=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
@ -719,7 +768,6 @@ def top(topfn, test=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
@ -835,6 +883,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
salt '*' state.sls_id my_state my_module,a_common_module
'''
st_kwargs = __salt__.kwargs
conflict = _check_queue(queue, kwargs)
if conflict is not None:
return conflict
@ -847,13 +896,11 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
if opts['environment'] is None:
opts['environment'] = 'base'
try:
st_ = salt.state.HighState(opts,
proxy=__proxy__,
initial_pillar=_get_initial_pillar(opts))
except NameError:
st_ = salt.state.HighState(opts,
initial_pillar=_get_initial_pillar(opts))
st_ = salt.client.ssh.state.SSHHighState(
__opts__,
__pillar__,
__salt__,
__context__['fileclient'])
if not _check_pillar(kwargs, st_.opts['pillar']):
__context__['retcode'] = 5
@ -864,10 +911,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
if isinstance(mods, six.string_types):
split_mods = mods.split(',')
st_.push_active()
try:
high_, errors = st_.render_highstate({opts['environment']: split_mods})
finally:
st_.pop_active()
high_, errors = st_.render_highstate({opts['environment']: split_mods})
errors += st_.state.verify_high(high_)
# Apply requisites to high data
high_, req_in_errors = st_.state.requisite_in(high_)
@ -879,20 +923,22 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
__context__['retcode'] = 1
return errors
chunks = st_.state.compile_high_data(high_)
ret = {}
for chunk in chunks:
if chunk.get('__id__', '') == id_:
ret.update(st_.state.call_chunk(chunk, {}, chunks))
chunk = [x for x in chunks if x.get('__id__', '') == id_]
_set_retcode(ret, highstate=highstate)
# Work around Windows multiprocessing bug, set __opts__['test'] back to
# value from before this function was run.
__opts__['test'] = orig_test
if not ret:
if not chunk:
raise SaltInvocationError(
'No matches for ID \'{0}\' found in SLS \'{1}\' within saltenv '
'\'{2}\''.format(id_, mods, opts['environment'])
)
ret = _ssh_state(chunk,
st_kwargs,
kwargs,
test=test)
_set_retcode(ret, highstate=highstate)
# Work around Windows multiprocessing bug, set __opts__['test'] back to
# value from before this function was run.
__opts__['test'] = orig_test
return ret
@ -1078,7 +1124,6 @@ def single(fun, name, test=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,

View file

@ -520,9 +520,17 @@ class AsyncAuth(object):
error = SaltClientError('Detect mode is on')
break
if self.opts.get('caller'):
print('Minion failed to authenticate with the master, '
'has the minion key been accepted?')
sys.exit(2)
# We have a list of masters, so we should break
# and try the next one in the list.
if self.opts.get('local_masters', None):
error = SaltClientError('Minion failed to authenticate'
' with the master, has the '
'minion key been accepted?')
break
else:
print('Minion failed to authenticate with the master, '
'has the minion key been accepted?')
sys.exit(2)
if acceptance_wait_time:
log.info('Waiting {0} seconds before retry.'.format(acceptance_wait_time))
yield tornado.gen.sleep(acceptance_wait_time)

View file

@ -64,10 +64,10 @@ if USE_IMPORTLIB:
SUFFIXES = []
for suffix in importlib.machinery.EXTENSION_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_EXTENSION))
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_COMPILED))
for suffix in importlib.machinery.SOURCE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_SOURCE))
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_COMPILED))
MODULE_KIND_MAP = {
MODULE_KIND_SOURCE: importlib.machinery.SourceFileLoader,
MODULE_KIND_COMPILED: importlib.machinery.SourcelessFileLoader,

View file

@ -935,7 +935,7 @@ class Minion(MinionBase):
# Flag meaning minion has finished initialization including first connect to the master.
# True means the Minion is fully functional and ready to handle events.
self.ready = False
self.jid_queue = jid_queue or []
self.jid_queue = [] if jid_queue is None else jid_queue
self.periodic_callbacks = {}
if io_loop is None:
@ -1032,10 +1032,11 @@ class Minion(MinionBase):
# I made the following 3 line oddity to preserve traceback.
# Please read PR #23978 before changing, hopefully avoiding regressions.
# Good luck, we're all counting on you. Thanks.
future_exception = self._connect_master_future.exception()
if future_exception:
# This needs to be re-raised to preserve restart_on_error behavior.
raise six.reraise(*future_exception)
if self._connect_master_future.done():
future_exception = self._connect_master_future.exception()
if future_exception:
# This needs to be re-raised to preserve restart_on_error behavior.
raise six.reraise(*future_exception)
if timeout and self._sync_connect_master_success is False:
raise SaltDaemonNotRunning('Failed to connect to the salt-master')
@ -1527,7 +1528,9 @@ class Minion(MinionBase):
)
ret['out'] = 'nested'
except TypeError as exc:
msg = 'Passed invalid arguments to {0}: {1}\n{2}'.format(function_name, exc, func.__doc__, )
msg = 'Passed invalid arguments to {0}: {1}\n{2}'.format(
function_name, exc, func.__doc__ or ''
)
log.warning(msg, exc_info_on_loglevel=logging.DEBUG)
ret['return'] = msg
ret['out'] = 'nested'

View file

@ -101,6 +101,7 @@ def cert(name,
server=None,
owner='root',
group='root',
mode='0640',
certname=None):
'''
Obtain/renew a certificate from an ACME CA, probably Let's Encrypt.
@ -113,8 +114,9 @@ def cert(name,
:param renew: True/'force' to force a renewal, or a window of renewal before expiry in days
:param keysize: RSA key bits
:param server: API endpoint to talk to
:param owner: owner of private key
:param group: group of private key
:param owner: owner of the private key file
:param group: group of the private key file
:param mode: mode of the private key file
:param certname: Name of the certificate to save
:return: dict with 'result' True/False/None, 'comment' and certificate's expiry date ('not_after')
@ -170,27 +172,17 @@ def cert(name,
return {'result': False, 'comment': 'Certificate {0} renewal failed with:\n{1}'.format(name, res['stderr'])}
if 'no action taken' in res['stdout']:
return {'result': None,
'comment': 'No action taken on certificate {0}'.format(cert_file),
'not_after': expires(name)}
if renew:
comment = 'Certificate {0} unchanged'.format(cert_file)
elif renew:
comment = 'Certificate {0} renewed'.format(name)
else:
comment = 'Certificate {0} obtained'.format(name)
ret = {'comment': comment, 'not_after': expires(name)}
res = __salt__['file.check_perms'](_cert_file(name, 'privkey'), {}, owner, group, '0600', follow_symlinks=True)
if res is None:
ret['result'] = False
ret['comment'] += ', but setting permissions failed.'
elif not res[0].get('result', False):
ret['result'] = False
ret['comment'] += ', but setting permissions failed with \n{0}'.format(res[0]['comment'])
else:
ret['result'] = True
ret['comment'] += '.'
ret = {'comment': comment, 'not_after': expires(name), 'changes': {}, 'result': True}
ret, _ = __salt__['file.check_perms'](_cert_file(name, 'privkey'),
ret,
owner, group, mode,
follow_symlinks=True)
return ret

View file

@ -304,7 +304,7 @@ def install(name=None,
# We don't support installing specific version for now
# so transform the dict in list ignoring version provided
pkgs = [
p.keys()[0] for p in pkgs
next(iter(p)) for p in pkgs
if isinstance(p, dict)
]
pkg_to_install.extend(pkgs)

View file

@ -282,12 +282,14 @@ def raw_cron(user):
# Preserve line endings
lines = sdecode(__salt__['cmd.run_stdout'](cmd,
runas=user,
ignore_retcode=True,
rstrip=False,
python_shell=False)).splitlines(True)
else:
cmd = 'crontab -u {0} -l'.format(user)
# Preserve line endings
lines = sdecode(__salt__['cmd.run_stdout'](cmd,
ignore_retcode=True,
rstrip=False,
python_shell=False)).splitlines(True)

View file

@ -436,11 +436,20 @@ def _refresh_mine_cache(wrapped):
refresh salt mine on exit.
'''
returned = wrapped(*args, **salt.utils.clean_kwargs(**kwargs))
__salt__['mine.send']('docker.ps', verbose=True, all=True, host=True)
if _check_update_mine():
__salt__['mine.send']('docker.ps', verbose=True, all=True, host=True)
return returned
return wrapper
def _check_update_mine():
try:
ret = __context__['docker.update_mine']
except KeyError:
ret = __context__['docker.update_mine'] = __salt__['config.get']('docker.update_mine', default=True)
return ret
# Helper functions
def _change_state(name, action, expected, *args, **kwargs):
'''
@ -5226,7 +5235,6 @@ def _prepare_trans_tar(name, mods=None, saltenv='base', pillar=None):
refs = salt.client.ssh.state.lowstate_file_refs(chunks)
_mk_fileclient()
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['cp.fileclient'],
chunks, refs, pillar, name)
return trans_tar

View file

@ -84,6 +84,9 @@ def fire_master(data, tag, preload=None):
channel = salt.transport.Channel.factory(__opts__, master_uri=master)
try:
channel.send(load)
# channel.send was successful.
# Ensure ret is True.
ret = True
except Exception:
ret = False
return ret

View file

@ -4262,26 +4262,6 @@ def check_perms(name, ret, user, group, mode, follow_symlinks=False):
perms['lgroup'] = cur['group']
perms['lmode'] = salt.utils.normalize_mode(cur['mode'])
# Mode changes if needed
if mode is not None:
# File is a symlink, ignore the mode setting
# if follow_symlinks is False
if os.path.islink(name) and not follow_symlinks:
pass
else:
mode = salt.utils.normalize_mode(mode)
if mode != perms['lmode']:
if __opts__['test'] is True:
ret['changes']['mode'] = mode
else:
set_mode(name, mode)
if mode != salt.utils.normalize_mode(get_mode(name)):
ret['result'] = False
ret['comment'].append(
'Failed to change mode to {0}'.format(mode)
)
else:
ret['changes']['mode'] = mode
# user/group changes if needed, then check if it worked
if user:
if isinstance(user, int):
@ -4358,6 +4338,27 @@ def check_perms(name, ret, user, group, mode, follow_symlinks=False):
elif 'cgroup' in perms and user != '':
ret['changes']['group'] = group
# Mode changes if needed
if mode is not None:
# File is a symlink, ignore the mode setting
# if follow_symlinks is False
if os.path.islink(name) and not follow_symlinks:
pass
else:
mode = salt.utils.normalize_mode(mode)
if mode != perms['lmode']:
if __opts__['test'] is True:
ret['changes']['mode'] = mode
else:
set_mode(name, mode)
if mode != salt.utils.normalize_mode(get_mode(name)):
ret['result'] = False
ret['comment'].append(
'Failed to change mode to {0}'.format(mode)
)
else:
ret['changes']['mode'] = mode
if isinstance(orig_comment, six.string_types):
if orig_comment:
ret['comment'].insert(0, orig_comment)
@ -4484,6 +4485,11 @@ def check_managed_changes(
defaults,
skip_verify,
**kwargs)
# Ensure that user-provided hash string is lowercase
if source_sum and ('hsum' in source_sum):
source_sum['hsum'] = source_sum['hsum'].lower()
if comments:
__clean_tmp(sfn)
return False, comments
@ -4725,7 +4731,7 @@ def manage_file(name,
source
file reference on the master
source_hash
source_sum
sum hash for source
user

View file

@ -26,15 +26,16 @@ def __virtual__():
return (False, 'glusterfs server is not installed')
def _get_minor_version():
# Set default version to 6 for tests
version = 6
def _get_version():
# Set the default minor version to 6 for tests
version = [3, 6]
cmd = 'gluster --version'
result = __salt__['cmd.run'](cmd).splitlines()
for line in result:
if line.startswith('glusterfs'):
version = int(line.split()[1].split('.')[1])
return version
version = line.split()[-1].split('.')
version = [int(i) for i in version]
return tuple(version)
def _gluster_ok(xml_data):
@ -67,7 +68,7 @@ def _gluster_xml(cmd):
# We will pass the command string as stdin to allow for much longer
# command strings. This is especially useful for creating large volumes
# where the list of bricks exceeds 128 characters.
if _get_minor_version() < 6:
if _get_version() < (3, 6,):
result = __salt__['cmd.run'](
'script -q -c "gluster --xml --mode=script"', stdin="{0}\n\004".format(cmd)
)

View file

@ -870,7 +870,7 @@ def _network_conf(conf_tuples=None, **kwargs):
# on old versions of lxc, still support the gateway auto mode
# if we didn't explicitly say no to
# (lxc.network.ipv4.gateway: auto)
if _LooseVersion(version()) <= '1.0.7' and \
if _LooseVersion(version()) <= _LooseVersion('1.0.7') and \
True not in ['lxc.network.ipv4.gateway' in a for a in ret] and \
True in ['lxc.network.ipv4' in a for a in ret]:
ret.append({'lxc.network.ipv4.gateway': 'auto'})
@ -2079,7 +2079,7 @@ def clone(name,
if backing in ('dir', 'overlayfs', 'btrfs'):
size = None
# LXC commands and options changed in 2.0 - CF issue #34086 for details
if version() >= _LooseVersion('2.0'):
if _LooseVersion(version()) >= _LooseVersion('2.0'):
# https://linuxcontainers.org/lxc/manpages//man1/lxc-copy.1.html
cmd = 'lxc-copy'
cmd += ' {0} -n {1} -N {2}'.format(snapshot, orig, name)
@ -2270,22 +2270,22 @@ def _change_state(cmd,
# as te command itself mess with double forks; we must not
# communicate with it, but just wait for the exit status
pkwargs = {'python_shell': False,
'redirect_stderr': True,
'with_communicate': with_communicate,
'use_vt': use_vt,
'stdin': stdin,
'stdout': stdout,
'stderr': stderr}
'stdout': stdout}
for i in [a for a in pkwargs]:
val = pkwargs[i]
if val is _marker:
pkwargs.pop(i, None)
error = __salt__['cmd.run_stderr'](cmd, **pkwargs)
_cmdout = __salt__['cmd.run_all'](cmd, **pkwargs)
if error:
if _cmdout['retcode'] != 0:
raise CommandExecutionError(
'Error changing state for container \'{0}\' using command '
'\'{1}\': {2}'.format(name, cmd, error)
'\'{1}\': {2}'.format(name, cmd, _cmdout['stdout'])
)
if expected is not None:
# some commands do not wait, so we will
@ -3507,7 +3507,9 @@ def bootstrap(name,
configdir = '/var/tmp/.c_{0}'.format(rstr)
cmd = 'install -m 0700 -d {0}'.format(configdir)
if run(name, cmd, python_shell=False):
if run_all(
name, cmd, path=path, python_shell=False
)['retcode'] != 0:
log.error('tmpdir {0} creation failed ({1}'
.format(configdir, cmd))
return False
@ -3518,6 +3520,7 @@ def bootstrap(name,
copy_to(name, bs_, script, path=path)
result = run_all(name,
'sh -c "chmod +x {0}"'.format(script),
path=path,
python_shell=True)
copy_to(name, cfg_files['config'],
@ -3544,6 +3547,7 @@ def bootstrap(name,
run_all(name,
'sh -c \'if [ -f "{0}" ];then rm -f "{0}";fi\''
''.format(script),
path=path,
ignore_retcode=True,
python_shell=True)
else:

View file

@ -374,10 +374,18 @@ def flush():
def get_docker(interfaces=None, cidrs=None, with_container_id=False):
'''
Get all mine data for 'docker.get_containers' and run an aggregation
routine. The "interfaces" parameter allows for specifying which network
interfaces to select ip addresses from. The "cidrs" parameter allows for
specifying a list of cidrs which the ip address must match.
.. versionchanged:: 2017.7.8,2018.3.3
When :conf_minion:`docker.update_mine` is set to ``False`` for a given
minion, no mine data will be populated for that minion, and thus none
will be returned for it.
.. versionchanged:: Fluorine
:conf_minion:`docker.update_mine` now defaults to ``False``
Get all mine data for :py:func:`docker.ps <salt.modules.dockermod.ps_>` and
run an aggregation routine. The ``interfaces`` parameter allows for
specifying the network interfaces from which to select IP addresses. The
``cidrs`` parameter allows for specifying a list of subnets which the IP
address must match.
with_container_id
Boolean, to expose container_id in the list of results

View file

@ -160,7 +160,11 @@ def install(pkg=None,
env.update({'SUDO_UID': uid, 'SUDO_USER': ''})
cmd = ' '.join(cmd)
result = __salt__['cmd.run_all'](cmd, python_shell=True, cwd=dir, runas=runas, env=env)
result = __salt__['cmd.run_all'](cmd,
python_shell=True,
cwd=dir,
runas=runas,
env=env)
if result['retcode'] != 0:
raise CommandExecutionError(result['stderr'])
@ -168,33 +172,9 @@ def install(pkg=None,
# npm >1.2.21 is putting the output to stderr even though retcode is 0
npm_output = result['stdout'] or result['stderr']
try:
return json.loads(npm_output)
return salt.utils.find_json(npm_output)
except ValueError:
pass
json_npm_output = _extract_json(npm_output)
return json_npm_output or npm_output
def _extract_json(npm_output):
lines = npm_output.splitlines()
log.error(lines)
# Strip all lines until JSON output starts
while lines and not lines[0].startswith('{') and not lines[0].startswith('['):
lines = lines[1:]
while lines and not lines[-1].startswith('}') and not lines[-1].startswith(']'):
lines = lines[:-1]
# macOS with fsevents includes the following line in the return
# when a new module is installed which is invalid JSON:
# [fsevents] Success: "..."
while lines and (lines[0].startswith('[fsevents]') or lines[0].startswith('Pass ')):
lines = lines[1:]
try:
return json.loads(''.join(lines))
except ValueError:
pass
return None
return npm_output
def uninstall(pkg, dir=None, runas=None, env=None):

View file

@ -168,20 +168,7 @@ def _get_pip_bin(bin_env):
# If the python binary was passed, return it
if 'python' in os.path.basename(bin_env):
return [os.path.normpath(bin_env), '-m', 'pip']
# Try to find the python binary based on the location of pip in a
# virtual environment, should be relative
if 'pip' in os.path.basename(bin_env):
# Look in the same directory as the pip binary, and also its
# parent directories.
pip_dirname = os.path.dirname(bin_env)
pip_parent_dir = os.path.dirname(pip_dirname)
for bin_path in _search_paths(pip_dirname, pip_parent_dir):
if os.path.isfile(bin_path):
logger.debug('pip: Found python binary: %s', bin_path)
return [os.path.normpath(bin_path), '-m', 'pip']
# Couldn't find python, use the passed pip binary
# This has the limitation of being unable to update pip itself
# We have been passed a pip binary, use the pip binary.
return [os.path.normpath(bin_env)]
raise CommandExecutionError(
@ -457,6 +444,13 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
``/usr/bin/pip-2.7`` or ``/usr/bin/pip-2.6``. If a directory path is
specified, it is assumed to be a virtualenv.
.. note::
For Windows, if the pip module is being used to upgrade the pip
package, bin_env should be the path to the virtualenv or to the
python binary that should be used. The pip command is unable to
upgrade itself in Windows.
use_wheel
Prefer wheel archives (requires pip>=1.4)

View file

@ -25,13 +25,13 @@ def __virtual__():
'''
if salt.utils.is_darwin() or salt.utils.is_windows():
return True
return (False, 'Module proxy: module only works on Windows or MacOS systems')
return False, 'Module proxy: module only works on Windows or MacOS systems'
def _get_proxy_osx(function, network_service):
def _get_proxy_osx(cmd_function, network_service):
ret = {}
out = __salt__['cmd.run']('networksetup -{0} {1}'.format(function, network_service))
out = __salt__['cmd.run']('networksetup -{0} {1}'.format(cmd_function, network_service))
match = re.match('Enabled: (.*)\nServer: (.*)\nPort: (.*)\n', out)
if match is not None:
g = match.groups()
@ -41,8 +41,8 @@ def _get_proxy_osx(function, network_service):
return ret
def _set_proxy_osx(function, server, port, user, password, network_service):
cmd = 'networksetup -{0} {1} {2} {3}'.format(function, network_service, server, port)
def _set_proxy_osx(cmd_function, server, port, user, password, network_service):
cmd = 'networksetup -{0} {1} {2} {3}'.format(cmd_function, network_service, server, port)
if user is not None and password is not None:
cmd = cmd + ' On {0} {1}'.format(user, password)
@ -58,12 +58,12 @@ def _get_proxy_windows(types=None):
if types is None:
types = ['http', 'https', 'ftp']
reg_val = __salt__['reg.read_value']('HKEY_CURRENT_USER',
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
'ProxyServer')
servers = reg_val['vdata']
servers = __salt__['reg.read_value'](
hive='HKEY_CURRENT_USER',
key=r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
vname='ProxyServer')['vdata']
if "=" in servers:
if servers and "=" in servers:
split = servers.split(";")
for s in split:
if len(s) == 0:
@ -87,16 +87,19 @@ def _get_proxy_windows(types=None):
del ret[key]
# Return enabled info
reg_val = __salt__['reg.read_value']('HKEY_CURRENT_USER',
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
'ProxyEnable')
enabled = reg_val.get('vdata', 0)
ret['enabled'] = True if enabled == 1 else False
ret['enabled'] = __salt__['reg.read_value'](
hive='HKEY_CURRENT_USER',
key=r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
vname='ProxyEnable')['vdata'] == 1
return ret
def _set_proxy_windows(server, port, types=None, bypass_hosts=None, import_winhttp=True):
def _set_proxy_windows(server,
port,
types=None,
bypass_hosts=None,
import_winhttp=True):
if types is None:
types = ['http', 'https', 'ftp']
@ -104,17 +107,27 @@ def _set_proxy_windows(server, port, types=None, bypass_hosts=None, import_winht
for t in types:
server_str += '{0}={1}:{2};'.format(t, server, port)
__salt__['reg.set_value']('HKEY_CURRENT_USER', r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
'ProxyServer', server_str)
__salt__['reg.set_value'](
hive='HKEY_CURRENT_USER',
key=r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
vname='ProxyServer',
vdata=server_str)
__salt__['reg.set_value']('HKEY_CURRENT_USER', r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
'ProxyEnable', 1, vtype='REG_DWORD')
__salt__['reg.set_value'](
hive='HKEY_CURRENT_USER',
key=r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
vname='ProxyEnable',
vdata=1,
vtype='REG_DWORD')
if bypass_hosts is not None:
bypass_hosts_str = '<local>;{0}'.format(';'.join(bypass_hosts))
__salt__['reg.set_value']('HKEY_CURRENT_USER', r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
'ProxyOverride', bypass_hosts_str)
__salt__['reg.set_value'](
hive='HKEY_CURRENT_USER',
key=r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
vname='ProxyOverride',
vdata=bypass_hosts_str)
if import_winhttp:
cmd = 'netsh winhttp import proxy source=ie'
@ -138,15 +151,22 @@ def get_http_proxy(network_service="Ethernet"):
salt '*' proxy.get_http_proxy Ethernet
'''
if __grains__['os'] == 'Windows':
return _get_proxy_windows(['http'])
return _get_proxy_windows(types=['http'])
return _get_proxy_osx("getwebproxy", network_service)
return _get_proxy_osx(cmd_function="getwebproxy",
network_service=network_service)
def set_http_proxy(server, port, user=None, password=None, network_service="Ethernet", bypass_hosts=None):
def set_http_proxy(server,
port,
user=None,
password=None,
network_service="Ethernet",
bypass_hosts=None):
'''
Sets the http proxy settings. Note: On Windows this will override any other proxy settings you have,
the preferred method of updating proxies on windows is using set_proxy.
Sets the http proxy settings. Note: On Windows this will override any other
proxy settings you have, the preferred method of updating proxies on windows
is using set_proxy.
server
The proxy server to use
@ -165,8 +185,8 @@ def set_http_proxy(server, port, user=None, password=None, network_service="Ethe
macOS
bypass_hosts
The hosts that are allowed to by pass the proxy. Only used on Windows for other OS's use
set_proxy_bypass to edit the bypass hosts.
The hosts that are allowed to by pass the proxy. Only used on Windows
for other OS's use set_proxy_bypass to edit the bypass hosts.
CLI Example:
@ -175,9 +195,17 @@ def set_http_proxy(server, port, user=None, password=None, network_service="Ethe
salt '*' proxy.set_http_proxy example.com 1080 user=proxy_user password=proxy_pass network_service=Ethernet
'''
if __grains__['os'] == 'Windows':
return _set_proxy_windows(server, port, ['http'], bypass_hosts)
return _set_proxy_windows(server=server,
port=port,
types=['http'],
bypass_hosts=bypass_hosts)
return _set_proxy_osx("setwebproxy", server, port, user, password, network_service)
return _set_proxy_osx(cmd_function="setwebproxy",
server=server,
port=port,
user=user,
password=password,
network_service=network_service)
def get_https_proxy(network_service="Ethernet"):
@ -195,15 +223,22 @@ def get_https_proxy(network_service="Ethernet"):
salt '*' proxy.get_https_proxy Ethernet
'''
if __grains__['os'] == 'Windows':
return _get_proxy_windows(['https'])
return _get_proxy_windows(types=['https'])
return _get_proxy_osx("getsecurewebproxy", network_service)
return _get_proxy_osx(cmd_function="getsecurewebproxy",
network_service=network_service)
def set_https_proxy(server, port, user=None, password=None, network_service="Ethernet", bypass_hosts=None):
def set_https_proxy(server,
port,
user=None,
password=None,
network_service="Ethernet",
bypass_hosts=None):
'''
Sets the https proxy settings. Note: On Windows this will override any other proxy settings you have,
the preferred method of updating proxies on windows is using set_proxy.
Sets the https proxy settings. Note: On Windows this will override any other
proxy settings you have, the preferred method of updating proxies on windows
is using set_proxy.
server
The proxy server to use
@ -222,8 +257,8 @@ def set_https_proxy(server, port, user=None, password=None, network_service="Eth
macOS
bypass_hosts
The hosts that are allowed to by pass the proxy. Only used on Windows for other OS's use
set_proxy_bypass to edit the bypass hosts.
The hosts that are allowed to by pass the proxy. Only used on Windows
for other OS's use set_proxy_bypass to edit the bypass hosts.
CLI Example:
@ -232,9 +267,17 @@ def set_https_proxy(server, port, user=None, password=None, network_service="Eth
salt '*' proxy.set_https_proxy example.com 1080 user=proxy_user password=proxy_pass network_service=Ethernet
'''
if __grains__['os'] == 'Windows':
return _set_proxy_windows(server, port, ['https'], bypass_hosts)
return _set_proxy_windows(server=server,
port=port,
types=['https'],
bypass_hosts=bypass_hosts)
return _set_proxy_osx("setsecurewebproxy", server, port, user, password, network_service)
return _set_proxy_osx(cmd_function="setsecurewebproxy",
server=server,
port=port,
user=user,
password=password,
network_service=network_service)
def get_ftp_proxy(network_service="Ethernet"):
@ -252,12 +295,18 @@ def get_ftp_proxy(network_service="Ethernet"):
salt '*' proxy.get_ftp_proxy Ethernet
'''
if __grains__['os'] == 'Windows':
return _get_proxy_windows(['ftp'])
return _get_proxy_windows(types=['ftp'])
return _get_proxy_osx("getftpproxy", network_service)
return _get_proxy_osx(cmd_function="getftpproxy",
network_service=network_service)
def set_ftp_proxy(server, port, user=None, password=None, network_service="Ethernet", bypass_hosts=None):
def set_ftp_proxy(server,
port,
user=None,
password=None,
network_service="Ethernet",
bypass_hosts=None):
'''
Sets the ftp proxy settings
@ -278,8 +327,8 @@ def set_ftp_proxy(server, port, user=None, password=None, network_service="Ether
macOS
bypass_hosts
The hosts that are allowed to by pass the proxy. Only used on Windows for other OS's use
set_proxy_bypass to edit the bypass hosts.
The hosts that are allowed to by pass the proxy. Only used on Windows
for other OS's use set_proxy_bypass to edit the bypass hosts.
CLI Example:
@ -288,9 +337,17 @@ def set_ftp_proxy(server, port, user=None, password=None, network_service="Ether
salt '*' proxy.set_ftp_proxy example.com 1080 user=proxy_user password=proxy_pass network_service=Ethernet
'''
if __grains__['os'] == 'Windows':
return _set_proxy_windows(server, port, ['ftp'], bypass_hosts)
return _set_proxy_windows(server=server,
port=port,
types=['ftp'],
bypass_hosts=bypass_hosts)
return _set_proxy_osx("setftpproxy", server, port, user, password, network_service)
return _set_proxy_osx(cmd_function="setftpproxy",
server=server,
port=port,
user=user,
password=password,
network_service=network_service)
def get_proxy_bypass(network_service="Ethernet"):
@ -309,12 +366,16 @@ def get_proxy_bypass(network_service="Ethernet"):
'''
if __grains__['os'] == 'Windows':
reg_val = __salt__['reg.read_value']('HKEY_CURRENT_USER',
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
'ProxyOverride')
bypass_servers = reg_val['vdata'].replace("<local>", "").split(";")
reg_val = __salt__['reg.read_value'](
hive='HKEY_CURRENT_USER',
key=r'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings',
vname='ProxyOverride')['vdata']
return bypass_servers
# `reg.read_value` returns None if the key doesn't exist
if reg_val is None:
return []
return reg_val.replace('<local>', '').split(';')
out = __salt__['cmd.run']('networksetup -getproxybypassdomains {0}'.format(network_service))
@ -357,7 +418,12 @@ def set_proxy_win(server, port, types=None, bypass_hosts=None):
The password to use if required by the server
types
The types of proxy connections should be setup with this server. Valid types are http and https.
The types of proxy connections should be setup with this server. Valid
types are:
- ``http``
- ``https``
- ``ftp``
bypass_hosts
The hosts that are allowed to by pass the proxy.
@ -369,7 +435,10 @@ def set_proxy_win(server, port, types=None, bypass_hosts=None):
salt '*' proxy.set_http_proxy example.com 1080 types="['http', 'https']"
'''
if __grains__['os'] == 'Windows':
return _set_proxy_windows(server, port, types, bypass_hosts)
return _set_proxy_windows(server=server,
port=port,
types=types,
bypass_hosts=bypass_hosts)
def get_proxy_win():

View file

@ -223,6 +223,7 @@ def list_users(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'list_users', '-q'],
reset_system_locale=False,
runas=runas,
python_shell=False)
@ -246,6 +247,7 @@ def list_vhosts(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'list_vhosts', '-q'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -320,6 +322,7 @@ def add_user(name, password=None, runas=None):
res = __salt__['cmd.run_all'](
cmd,
reset_system_locale=False,
output_loglevel='quiet',
runas=runas,
python_shell=python_shell)
@ -352,6 +355,7 @@ def delete_user(name, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'delete_user', name],
reset_system_locale=False,
python_shell=False,
runas=runas)
msg = 'Deleted'
@ -387,6 +391,7 @@ def change_password(name, password, runas=None):
cmd = [RABBITMQCTL, 'change_password', name, password]
res = __salt__['cmd.run_all'](
cmd,
reset_system_locale=False,
runas=runas,
output_loglevel='quiet',
python_shell=python_shell)
@ -409,6 +414,7 @@ def clear_password(name, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'clear_password', name],
reset_system_locale=False,
runas=runas,
python_shell=False)
msg = 'Password Cleared'
@ -434,7 +440,7 @@ def check_password(name, password, runas=None):
runas = salt.utils.get_user()
try:
res = __salt__['cmd.run']([RABBITMQCTL, 'status'], runas=runas, python_shell=False)
res = __salt__['cmd.run']([RABBITMQCTL, 'status'], reset_system_locale=False, runas=runas, python_shell=False)
server_version = re.search(r'\{rabbit,"RabbitMQ","(.+)"\}', res)
if server_version is None:
@ -466,6 +472,7 @@ def check_password(name, password, runas=None):
res = __salt__['cmd.run_all'](
cmd,
reset_system_locale=False,
runas=runas,
output_loglevel='quiet',
python_shell=python_shell)
@ -481,6 +488,7 @@ def check_password(name, password, runas=None):
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'eval', cmd],
reset_system_locale=False,
runas=runas,
output_loglevel='quiet',
python_shell=False)
@ -509,6 +517,7 @@ def add_vhost(vhost, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'add_vhost', vhost],
reset_system_locale=False,
runas=runas,
python_shell=False)
@ -530,6 +539,7 @@ def delete_vhost(vhost, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'delete_vhost', vhost],
reset_system_locale=False,
runas=runas,
python_shell=False)
msg = 'Deleted'
@ -551,6 +561,7 @@ def set_permissions(vhost, user, conf='.*', write='.*', read='.*', runas=None):
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'set_permissions', '-p',
vhost, user, conf, write, read],
reset_system_locale=False,
runas=runas,
python_shell=False)
msg = 'Permissions Set'
@ -571,6 +582,7 @@ def list_permissions(vhost, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'list_permissions', '-q', '-p', vhost],
reset_system_locale=False,
runas=runas,
python_shell=False)
@ -591,6 +603,7 @@ def list_user_permissions(name, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'list_user_permissions', name, '-q'],
reset_system_locale=False,
runas=runas,
python_shell=False)
@ -614,6 +627,7 @@ def set_user_tags(name, tags, runas=None):
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'set_user_tags', name] + list(tags),
reset_system_locale=False,
runas=runas,
python_shell=False)
msg = "Tag(s) set"
@ -634,6 +648,7 @@ def status(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'status'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -654,6 +669,7 @@ def cluster_status(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'cluster_status'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -678,7 +694,7 @@ def join_cluster(host, user='rabbit', ram_node=None, runas=None):
if runas is None and not salt.utils.is_windows():
runas = salt.utils.get_user()
stop_app(runas)
res = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
res = __salt__['cmd.run_all'](cmd, reset_system_locale=False, runas=runas, python_shell=False)
start_app(runas)
return _format_response(res, 'Join')
@ -698,6 +714,7 @@ def stop_app(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'stop_app'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -718,6 +735,7 @@ def start_app(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'start_app'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -738,6 +756,7 @@ def reset(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'reset'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -758,6 +777,7 @@ def force_reset(runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'force_reset'],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -778,7 +798,7 @@ def list_queues(runas=None, *args):
runas = salt.utils.get_user()
cmd = [RABBITMQCTL, 'list_queues', '-q']
cmd.extend(args)
res = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
res = __salt__['cmd.run_all'](cmd, reset_system_locale=False, runas=runas, python_shell=False)
_check_response(res)
return _output_to_dict(res['stdout'])
@ -800,7 +820,7 @@ def list_queues_vhost(vhost, runas=None, *args):
runas = salt.utils.get_user()
cmd = [RABBITMQCTL, 'list_queues', '-q', '-p', vhost]
cmd.extend(args)
res = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
res = __salt__['cmd.run_all'](cmd, reset_system_locale=False, runas=runas, python_shell=False)
_check_response(res)
return _output_to_dict(res['stdout'])
@ -823,6 +843,7 @@ def list_policies(vhost="/", runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'list_policies', '-q', '-p', vhost],
reset_system_locale=False,
runas=runas,
python_shell=False)
_check_response(res)
@ -873,8 +894,8 @@ def set_policy(vhost, name, pattern, definition, priority=None, runas=None):
if priority:
cmd.extend(['--priority', priority])
cmd.extend([name, pattern, definition])
res = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
log.debug('Set policy: {0}'.format(res['stdout']))
res = __salt__['cmd.run_all'](cmd, reset_system_locale=False, runas=runas, python_shell=False)
log.debug('Set policy: %s', res['stdout'])
return _format_response(res, 'Set')
@ -894,6 +915,7 @@ def delete_policy(vhost, name, runas=None):
runas = salt.utils.get_user()
res = __salt__['cmd.run_all'](
[RABBITMQCTL, 'clear_policy', '-p', vhost, name],
reset_system_locale=False,
runas=runas,
python_shell=False)
log.debug('Delete policy: {0}'.format(res['stdout']))
@ -931,7 +953,7 @@ def list_available_plugins(runas=None):
if runas is None and not salt.utils.is_windows():
runas = salt.utils.get_user()
cmd = [_get_rabbitmq_plugin(), 'list', '-m']
ret = __salt__['cmd.run_all'](cmd, python_shell=False, runas=runas)
ret = __salt__['cmd.run_all'](cmd, reset_system_locale=False, python_shell=False, runas=runas)
_check_response(ret)
return _output_to_list(ret['stdout'])
@ -949,7 +971,7 @@ def list_enabled_plugins(runas=None):
if runas is None and not salt.utils.is_windows():
runas = salt.utils.get_user()
cmd = [_get_rabbitmq_plugin(), 'list', '-m', '-e']
ret = __salt__['cmd.run_all'](cmd, python_shell=False, runas=runas)
ret = __salt__['cmd.run_all'](cmd, reset_system_locale=False, python_shell=False, runas=runas)
_check_response(ret)
return _output_to_list(ret['stdout'])
@ -982,7 +1004,7 @@ def enable_plugin(name, runas=None):
if runas is None and not salt.utils.is_windows():
runas = salt.utils.get_user()
cmd = [_get_rabbitmq_plugin(), 'enable', name]
ret = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
ret = __salt__['cmd.run_all'](cmd, reset_system_locale=False, runas=runas, python_shell=False)
return _format_response(ret, 'Enabled')
@ -999,5 +1021,5 @@ def disable_plugin(name, runas=None):
if runas is None and not salt.utils.is_windows():
runas = salt.utils.get_user()
cmd = [_get_rabbitmq_plugin(), 'disable', name]
ret = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
ret = __salt__['cmd.run_all'](cmd, reset_system_locale=False, runas=runas, python_shell=False)
return _format_response(ret, 'Disabled')

View file

@ -19,6 +19,7 @@ Module to provide redis functionality to Salt
from __future__ import absolute_import
from salt.ext.six.moves import zip
from salt.ext import six
from salt.utils import clean_kwargs
from datetime import datetime
# Import third party libs
@ -395,7 +396,7 @@ def hmset(key, **fieldsvals):
database = fieldsvals.pop('db', None)
password = fieldsvals.pop('password', None)
server = _connect(host, port, database, password)
return server.hmset(key, **fieldsvals)
return server.hmset(key, clean_kwargs(**fieldsvals))
def hset(key, field, value, host=None, port=None, db=None, password=None):

View file

@ -35,6 +35,7 @@ def __virtual__():
'Devuan',
'Arch',
'Arch ARM',
'Manjaro',
'ALT',
'SUSE Enterprise Server',
'SUSE',

View file

@ -458,8 +458,7 @@ def template_str(tem, queue=False, **kwargs):
return ret
def apply_(mods=None,
**kwargs):
def apply_(mods=None, **kwargs):
'''
.. versionadded:: 2015.5.0
@ -599,6 +598,22 @@ def apply_(mods=None,
.. code-block:: bash
salt '*' state.apply test localconfig=/path/to/minion.yml
sync_mods
If specified, the desired custom module types will be synced prior to
running the SLS files:
.. code-block:: bash
salt '*' state.apply test sync_mods=states,modules
salt '*' state.apply test sync_mods=all
.. note::
This option is ignored when no SLS files are specified, as a
:ref:`highstate <running-highstate>` automatically syncs all custom
module types.
.. versionadded:: 2017.7.8,2018.3.3,Fluorine
'''
if mods:
return sls(mods, **kwargs)
@ -928,7 +943,7 @@ def highstate(test=None, queue=False, **kwargs):
return ret
def sls(mods, test=None, exclude=None, queue=False, **kwargs):
def sls(mods, test=None, exclude=None, queue=False, sync_mods=None, **kwargs):
'''
Execute the states in one or more SLS files
@ -1019,6 +1034,17 @@ def sls(mods, test=None, exclude=None, queue=False, **kwargs):
.. versionadded:: 2015.8.4
sync_mods
If specified, the desired custom module types will be synced prior to
running the SLS files:
.. code-block:: bash
salt '*' state.sls test sync_mods=states,modules
salt '*' state.sls test sync_mods=all
.. versionadded:: 2017.7.8,2018.3.3,Fluorine
CLI Example:
.. code-block:: bash
@ -1087,6 +1113,28 @@ def sls(mods, test=None, exclude=None, queue=False, **kwargs):
'{0}.cache.p'.format(kwargs.get('cache_name', 'highstate'))
)
if sync_mods is True:
sync_mods = ['all']
if sync_mods is not None:
sync_mods = salt.utils.split_input(sync_mods)
else:
sync_mods = []
if 'all' in sync_mods and sync_mods != ['all']:
# Prevent unnecessary extra syncing
sync_mods = ['all']
for module_type in sync_mods:
try:
__salt__['saltutil.sync_{0}'.format(module_type)](
saltenv=opts['environment']
)
except KeyError:
log.warning(
'Invalid custom module type \'%s\', ignoring',
module_type
)
try:
st_ = salt.state.HighState(opts,
pillar_override,

View file

@ -296,7 +296,7 @@ def _register_functions():
modules_ = [module_ for module_ in modules.modules]
for mod_name in modules_:
mod_name = _to_snake_case(module_)
mod_name = _to_snake_case(mod_name)
mod_func = _copy_function(mod_name, str(mod_name))
mod_func.__doc__ = _build_doc(mod_name)
__all__.append(mod_name)

View file

@ -484,60 +484,67 @@ def set_hwclock(clock):
salt '*' timezone.set_hwclock UTC
'''
if 'AIX' in __grains__['os_family']:
if clock.lower() != 'utc':
raise SaltInvocationError(
'UTC is the only permitted value'
)
return True
timezone = get_zone()
if 'Solaris' in __grains__['os_family']:
if clock.lower() not in ('localtime', 'utc'):
raise SaltInvocationError(
'localtime and UTC are the only permitted values'
)
if 'sparc' in __grains__['cpuarch']:
raise SaltInvocationError(
'UTC is the only choice for SPARC architecture'
)
cmd = ['rtc', '-z', 'GMT' if clock.lower() == 'utc' else timezone]
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
zonepath = '/usr/share/zoneinfo/{0}'.format(timezone)
if not os.path.exists(zonepath):
raise CommandExecutionError(
'Zone \'{0}\' does not exist'.format(zonepath)
)
os.unlink('/etc/localtime')
os.symlink(zonepath, '/etc/localtime')
if 'Arch' in __grains__['os_family']:
cmd = ['timezonectl', 'set-local-rtc',
if salt.utils.which('timedatectl'):
cmd = ['timedatectl', 'set-local-rtc',
'true' if clock == 'localtime' else 'false']
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
elif 'RedHat' in __grains__['os_family']:
__salt__['file.sed'](
'/etc/sysconfig/clock', '^ZONE=.*', 'ZONE="{0}"'.format(timezone))
elif 'Suse' in __grains__['os_family']:
__salt__['file.sed'](
'/etc/sysconfig/clock', '^TIMEZONE=.*', 'TIMEZONE="{0}"'.format(timezone))
elif 'Debian' in __grains__['os_family']:
if clock == 'UTC':
__salt__['file.sed']('/etc/default/rcS', '^UTC=.*', 'UTC=yes')
elif clock == 'localtime':
__salt__['file.sed']('/etc/default/rcS', '^UTC=.*', 'UTC=no')
elif 'Gentoo' in __grains__['os_family']:
if clock not in ('UTC', 'localtime'):
raise SaltInvocationError(
'Only \'UTC\' and \'localtime\' are allowed'
else:
os_family = __grains__['os_family']
if os_family in ('AIX', 'NILinuxRT'):
if clock.lower() != 'utc':
raise SaltInvocationError(
'UTC is the only permitted value'
)
return True
timezone = get_zone()
if 'Solaris' in __grains__['os_family']:
if clock.lower() not in ('localtime', 'utc'):
raise SaltInvocationError(
'localtime and UTC are the only permitted values'
)
if 'sparc' in __grains__['cpuarch']:
raise SaltInvocationError(
'UTC is the only choice for SPARC architecture'
)
cmd = ['rtc', '-z', 'GMT' if clock.lower() == 'utc' else timezone]
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
zonepath = '/usr/share/zoneinfo/{0}'.format(timezone)
if not os.path.exists(zonepath):
raise CommandExecutionError(
'Zone \'{0}\' does not exist'.format(zonepath)
)
if clock == 'localtime':
clock = 'local'
__salt__['file.sed'](
'/etc/conf.d/hwclock', '^clock=.*', 'clock="{0}"'.format(clock))
os.unlink('/etc/localtime')
os.symlink(zonepath, '/etc/localtime')
if 'Arch' in __grains__['os_family']:
cmd = ['timezonectl', 'set-local-rtc',
'true' if clock == 'localtime' else 'false']
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
elif 'RedHat' in __grains__['os_family']:
__salt__['file.sed'](
'/etc/sysconfig/clock', '^ZONE=.*', 'ZONE="{0}"'.format(timezone))
elif 'Suse' in __grains__['os_family']:
__salt__['file.sed'](
'/etc/sysconfig/clock', '^TIMEZONE=.*', 'TIMEZONE="{0}"'.format(timezone))
elif 'Debian' in __grains__['os_family']:
if clock == 'UTC':
__salt__['file.sed']('/etc/default/rcS', '^UTC=.*', 'UTC=yes')
elif clock == 'localtime':
__salt__['file.sed']('/etc/default/rcS', '^UTC=.*', 'UTC=no')
elif 'Gentoo' in __grains__['os_family']:
if clock not in ('UTC', 'localtime'):
raise SaltInvocationError(
'Only \'UTC\' and \'localtime\' are allowed'
)
if clock == 'localtime':
clock = 'local'
__salt__['file.sed'](
'/etc/conf.d/hwclock', '^clock=.*', 'clock="{0}"'.format(clock))
return True

View file

@ -7,50 +7,55 @@ powercfg.
.. code-block:: bash
# Set monitor to never turn off on Battery power
salt '*' powercfg.set_monitor_timeout 0 power=dc
# Set disk timeout to 120 minutes on AC power
salt '*' powercfg.set_disk_timeout 120 power=ac
'''
# Import Python Libs
from __future__ import absolute_import
import re
import logging
# Import Salt Libs
import salt.utils
log = logging.getLogger(__name__)
__virtualname__ = "powercfg"
__virtualname__ = 'powercfg'
def __virtual__():
'''
Only work on Windows
'''
if __grains__['os'] == 'Windows':
return __virtualname__
return (False, 'Module only works on Windows.')
if not salt.utils.is_windows():
return False, 'PowerCFG: Module only works on Windows'
return __virtualname__
def _get_current_scheme():
cmd = "powercfg /getactivescheme"
cmd = 'powercfg /getactivescheme'
out = __salt__['cmd.run'](cmd, python_shell=False)
matches = re.search(r"GUID: (.*) \(", out)
matches = re.search(r'GUID: (.*) \(', out)
return matches.groups()[0].strip()
def _get_powercfg_minute_values(scheme, guid, subguid, safe_name):
'''
Returns the AC/DC values in an array for a guid and subguid for a the given scheme
Returns the AC/DC values in an dict for a guid and subguid for a the given
scheme
'''
if scheme is None:
scheme = _get_current_scheme()
if __grains__['osrelease'] == '7':
cmd = "powercfg /q {0} {1}".format(scheme, guid)
cmd = 'powercfg /q {0} {1}'.format(scheme, guid)
else:
cmd = "powercfg /q {0} {1} {2}".format(scheme, guid, subguid)
cmd = 'powercfg /q {0} {1} {2}'.format(scheme, guid, subguid)
out = __salt__['cmd.run'](cmd, python_shell=False)
split = out.split("\r\n\r\n")
split = out.split('\r\n\r\n')
if len(split) > 1:
for s in split:
if safe_name in s or subguid in s:
@ -59,172 +64,309 @@ def _get_powercfg_minute_values(scheme, guid, subguid, safe_name):
else:
out = split[0]
raw_settings = re.findall(r"Power Setting Index: ([0-9a-fx]+)", out)
return {"ac": int(raw_settings[0], 0) / 60, "dc": int(raw_settings[1], 0) / 60}
raw_settings = re.findall(r'Power Setting Index: ([0-9a-fx]+)', out)
return {'ac': int(raw_settings[0], 0) / 60,
'dc': int(raw_settings[1], 0) / 60}
def _set_powercfg_value(scheme, sub_group, setting_guid, power, value):
'''
Sets the value of a setting with a given power (ac/dc) to
the given scheme
Sets the AC/DC values of a setting with the given power for the given scheme
'''
salt.utils.warn_until(
'Fluorine',
'This function now expects the timeout value in minutes instead of '
'seconds as stated in the documentation. This warning will be removed '
'in Salt Fluorine.')
if scheme is None:
scheme = _get_current_scheme()
cmd = "powercfg /set{0}valueindex {1} {2} {3} {4}".format(power, scheme, sub_group, setting_guid, value)
return __salt__['cmd.run'](cmd, python_shell=False)
cmd = 'powercfg /set{0}valueindex {1} {2} {3} {4}' \
''.format(power, scheme, sub_group, setting_guid, value * 60)
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
def set_monitor_timeout(timeout, power="ac", scheme=None):
def set_monitor_timeout(timeout, power='ac', scheme=None):
'''
Set the monitor timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the monitor will timeout
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
salt '*' powercfg.set_monitor_timeout 30 power=ac
timeout
The amount of time in minutes before the monitor will timeout
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
# Sets the monitor timeout to 30 minutes
salt '*' powercfg.set_monitor_timeout 30
'''
return _set_powercfg_value(scheme, "SUB_VIDEO", "VIDEOIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_VIDEO',
setting_guid='VIDEOIDLE',
power=power,
value=timeout)
def get_monitor_timeout(scheme=None):
'''
Get the current monitor timeout of the given scheme
Args:
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_monitor_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_VIDEO", "VIDEOIDLE", "Turn off display after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_VIDEO',
subguid='VIDEOIDLE',
safe_name='Turn off display after')
def set_disk_timeout(timeout, power="ac", scheme=None):
def set_disk_timeout(timeout, power='ac', scheme=None):
'''
Set the disk timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the disk will timeout
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
# Sets the disk timeout to 30 minutes on battery
salt '*' powercfg.set_disk_timeout 30 power=dc
timeout
The amount of time in minutes before the disk will timeout
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
'''
return _set_powercfg_value(scheme, "SUB_DISK", "DISKIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_DISK',
setting_guid='DISKIDLE',
power=power,
value=timeout)
def get_disk_timeout(scheme=None):
'''
Get the current disk timeout of the given scheme
Args:
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_disk_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_DISK", "DISKIDLE", "Turn off hard disk after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_DISK',
subguid='DISKIDLE',
safe_name='Turn off hard disk after')
def set_standby_timeout(timeout, power="ac", scheme=None):
def set_standby_timeout(timeout, power='ac', scheme=None):
'''
Set the standby timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the computer sleeps
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
# Sets the system standby timeout to 30 minutes on Battery
salt '*' powercfg.set_standby_timeout 30 power=dc
timeout
The amount of time in minutes before the computer sleeps
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
'''
return _set_powercfg_value(scheme, "SUB_SLEEP", "STANDBYIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_SLEEP',
setting_guid='STANDBYIDLE',
power=power,
value=timeout)
def get_standby_timeout(scheme=None):
'''
Get the current standby timeout of the given scheme
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_standby_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_SLEEP", "STANDBYIDLE", "Sleep after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_SLEEP',
subguid='STANDBYIDLE',
safe_name='Sleep after')
def set_hibernate_timeout(timeout, power="ac", scheme=None):
def set_hibernate_timeout(timeout, power='ac', scheme=None):
'''
Set the hibernate timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the computer hibernates
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
salt '*' powercfg.set_hibernate_timeout 30 power=pc
timeout
The amount of time in minutes before the computer hibernates
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
# Sets the hibernate timeout to 30 minutes on Battery
salt '*' powercfg.set_hibernate_timeout 30 power=dc
'''
return _set_powercfg_value(scheme, "SUB_SLEEP", "HIBERNATEIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_SLEEP',
setting_guid='HIBERNATEIDLE',
power=power,
value=timeout)
def get_hibernate_timeout(scheme=None):
'''
Get the current hibernate timeout of the given scheme
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_hibernate_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_SLEEP", "HIBERNATEIDLE", "Hibernate after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_SLEEP',
subguid='HIBERNATEIDLE',
safe_name='Hibernate after')

View file

@ -683,7 +683,7 @@ def modify(name,
win32service.SERVICE_QUERY_CONFIG)
except pywintypes.error as exc:
raise CommandExecutionError(
'Failed To Open {0}: {1}'.format(name, exc[2]))
'Failed To Open {0}: {1}'.format(name, exc))
config_info = win32service.QueryServiceConfig(handle_svc)

View file

@ -9,6 +9,12 @@ import salt.utils
import logging
import re
try:
import tzlocal
HAS_TZLOCAL = True
except ImportError:
HAS_TZLOCAL = False
log = logging.getLogger(__name__)
# Maybe put in a different file ... ? %-0
@ -473,6 +479,10 @@ def get_zone():
salt '*' timezone.get_zone
'''
if HAS_TZLOCAL:
return tzlocal.get_localzone().zone
log.warning('tzutil not installed. get_zone might be inaccurate')
winzone = __salt__['cmd.run'](['tzutil', '/g'], python_shell=False)
for key in LINTOWIN:
if LINTOWIN[key] == winzone:

View file

@ -942,7 +942,6 @@ def create_crl( # pylint: disable=too-many-arguments,too-many-locals
rev_item['not_after'] = rev_cert['Not After']
serial_number = rev_item['serial_number'].replace(':', '')
serial_number = str(int(serial_number, 16))
if 'not_after' in rev_item and not include_expired:
not_after = datetime.datetime.strptime(

View file

@ -581,6 +581,8 @@ def latest_version(*names, **kwargs):
status = pkg_info.get('status', '').lower()
if status.find('not installed') > -1 or status.find('out-of-date') > -1:
ret[name] = pkg_info.get('version')
else:
ret[name] = ''
# Return a string if only one package name passed
if len(names) == 1 and len(ret):

View file

@ -210,7 +210,7 @@ import tornado
TORNADO_50 = tornado.version_info >= (5,)
if not TORNADO_50:
import zmq.eventloop.ioloop
import zmq.eventloop.ioloop # pylint: disable=import-error
# instantiate the zmq IOLoop (specialized poller)
zmq.eventloop.ioloop.install()
@ -923,9 +923,11 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
# Generate jid before triggering a job to subscribe all returns from minions
chunk['jid'] = salt.utils.jid.gen_jid()
# Subscribe returns from minions before firing a job
minions = set(self.ckminions.check_minions(chunk['tgt'], chunk.get('tgt_type', 'glob')))
future_minion_map = self.subscribe_minion_returns(chunk['jid'], minions)
# start listening for the event before we fire the job to avoid races
events = [
self.application.event_listener.get_event(self, tag='salt/job/'+chunk['jid']),
self.application.event_listener.get_event(self, tag='syndic/job/'+chunk['jid']),
]
f_call = self._format_call_run_job_async(chunk)
# fire a job off
@ -937,88 +939,92 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
# if the job didn't publish, lets not wait around for nothing
# TODO: set header??
if 'jid' not in pub_data:
for future in future_minion_map:
for future in events:
try:
future.set_result(None)
except Exception:
pass
raise tornado.gen.Return('No minions matched the target. No command was sent, no jid was assigned.')
# Map of minion_id -> returned for all minions we think we need to wait on
minions = {m: False for m in pub_data['minions']}
# minimum time required for return to complete. By default no waiting, if
# we are a syndic then we must wait syndic_wait at a minimum
min_wait_time = Future()
min_wait_time.set_result(True)
# wait syndic a while to avoid missing published events
if self.application.opts['order_masters']:
yield tornado.gen.sleep(self.application.opts['syndic_wait'])
min_wait_time = tornado.gen.sleep(self.application.opts['syndic_wait'])
# To ensure job_not_running and all_return are terminated by each other, communicate using a future
is_finished = Future()
is_finished = tornado.gen.sleep(self.application.opts['gather_job_timeout'])
job_not_running_future = self.job_not_running(pub_data['jid'],
# ping until the job is not running, while doing so, if we see new minions returning
# that they are running the job, add them to the list
tornado.ioloop.IOLoop.current().spawn_callback(self.job_not_running, pub_data['jid'],
chunk['tgt'],
f_call['kwargs']['tgt_type'],
minions,
is_finished)
minion_returns_future = self.sanitize_minion_returns(future_minion_map, pub_data['minions'], is_finished)
yield job_not_running_future
raise tornado.gen.Return((yield minion_returns_future))
def subscribe_minion_returns(self, jid, minions):
# Subscribe each minion event
future_minion_map = {}
for minion in minions:
tag = tagify([jid, 'ret', minion], 'job')
minion_future = self.application.event_listener.get_event(self,
tag=tag,
matcher=EventListener.exact_matcher)
future_minion_map[minion_future] = minion
return future_minion_map
@tornado.gen.coroutine
def sanitize_minion_returns(self, future_minion_map, minions, is_finished):
'''
Return a future which will complete once all returns are completed
(according to minions), or one of the passed in "finish_chunk_ret_future" completes
'''
if minions is None:
minions = []
# Remove redundant minions
redundant_minion_futures = [future for future in future_minion_map.keys() if future_minion_map[future] not in minions]
for redundant_minion_future in redundant_minion_futures:
try:
redundant_minion_future.set_result(None)
except Exception:
pass
del future_minion_map[redundant_minion_future]
def more_todo():
'''Check if there are any more minions we are waiting on returns from
'''
return any(x is False for x in six.itervalues(minions))
# here we want to follow the behavior of LocalClient.get_iter_returns
# namely we want to wait at least syndic_wait (assuming we are a syndic)
# and that there are no more jobs running on minions. We are allowed to exit
# early if gather_job_timeout has been exceeded
chunk_ret = {}
while True:
f = yield Any(list(future_minion_map.keys()) + [is_finished])
to_wait = events+[is_finished]
if not min_wait_time.done():
to_wait += [min_wait_time]
def cancel_inflight_futures():
for event in to_wait:
if not event.done():
event.set_result(None)
f = yield Any(to_wait)
try:
# When finished entire routine, cleanup other futures and return result
if f is is_finished:
for event in future_minion_map.keys():
if not event.done():
event.set_result(None)
cancel_inflight_futures()
raise tornado.gen.Return(chunk_ret)
elif f is min_wait_time:
if not more_todo():
cancel_inflight_futures()
raise tornado.gen.Return(chunk_ret)
continue
f_result = f.result()
chunk_ret[f_result['data']['id']] = f_result['data']['return']
# if this is a start, then we need to add it to the pile
if f_result['tag'].endswith('/new'):
for minion_id in f_result['data']['minions']:
if minion_id not in minions:
minions[minion_id] = False
else:
chunk_ret[f_result['data']['id']] = f_result['data']['return']
# clear finished event future
minions[f_result['data']['id']] = True
# if there are no more minions to wait for, then we are done
if not more_todo() and min_wait_time.done():
cancel_inflight_futures()
raise tornado.gen.Return(chunk_ret)
except TimeoutException:
pass
# clear finished event future
try:
minions.remove(future_minion_map[f])
del future_minion_map[f]
except ValueError:
pass
if not minions:
if not is_finished.done():
is_finished.set_result(True)
raise tornado.gen.Return(chunk_ret)
if f == events[0]:
events[0] = self.application.event_listener.get_event(self, tag='salt/job/'+chunk['jid'])
else:
events[1] = self.application.event_listener.get_event(self, tag='syndic/job/'+chunk['jid'])
@tornado.gen.coroutine
def job_not_running(self, jid, tgt, tgt_type, is_finished):
def job_not_running(self, jid, tgt, tgt_type, minions, is_finished):
'''
Return a future which will complete once jid (passed in) is no longer
running on tgt
@ -1044,8 +1050,6 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
event = f.result()
except TimeoutException:
if not minion_running:
if not is_finished.done():
is_finished.set_result(True)
raise tornado.gen.Return(True)
else:
ping_pub_data = yield self.saltclients['local'](tgt,
@ -1059,6 +1063,8 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
# Minions can return, we want to see if the job is running...
if event['data'].get('return', {}) == {}:
continue
if event['data']['id'] not in minions:
minions[event['data']['id']] = False
minion_running = True
@tornado.gen.coroutine

View file

@ -923,6 +923,11 @@ class Pillar(object):
decrypt_errors = self.decrypt_pillar(pillar)
if decrypt_errors:
pillar.setdefault('_errors', []).extend(decrypt_errors)
# Reset the file_roots for the renderers
for mod_name in sys.modules:
if mod_name.startswith('salt.loaded.int.render.'):
sys.modules[mod_name].__opts__['file_roots'] = self.actual_file_roots
return pillar
def decrypt_pillar(self, pillar):

View file

@ -154,7 +154,7 @@ def action(func=None,
info = {}
client = _get_client()
try:
info = client.action(func, cloudmap, instances, provider, instance, **_filter_kwargs(kwargs))
info = client.action(func, cloudmap, instances, provider, instance, _filter_kwargs(kwargs))
except SaltCloudConfigError as err:
log.error(err)
return info

View file

@ -150,7 +150,7 @@ def lookup_jid(jid,
try:
# Check if the return data has an 'out' key. We'll use that as the
# outputter in the absence of one being passed on the CLI.
outputter = data[next(iter(data))].get('out')
outputter = returns[next(iter(returns))].get('out')
except (StopIteration, AttributeError):
outputter = None

View file

@ -171,7 +171,9 @@ def init(
start=True,
disk='default',
saltenv='base',
enable_vnc=False):
enable_vnc=False,
seed_cmd='seed.apply',
enable_qcow=False):
'''
This routine is used to create a new virtual machine. This routines takes
a number of options to determine what the newly created virtual machine
@ -193,14 +195,14 @@ def init(
on the salt fileserver, but http, https and ftp can also be used.
hypervisor
The hypervisor to use for the new virtual machine. Default is 'kvm'.
The hypervisor to use for the new virtual machine. Default is `kvm`.
host
The host to use for the new virtual machine, if this is omitted
Salt will automatically detect what host to use.
seed
Set to False to prevent Salt from seeding the new virtual machine.
Set to `False` to prevent Salt from seeding the new virtual machine.
nic
The nic profile to use, defaults to the "default" nic profile which
@ -216,6 +218,17 @@ def init(
saltenv
The Salt environment to use
enable_vnc
Whether a VNC screen is attached to resulting VM. Default is `False`.
seed_cmd
If seed is `True`, use this execution module function to seed new VM.
Default is `seed.apply`.
enable_qcow
Clone disk image as a copy-on-write qcow2 image, using downloaded
`image` as backing file.
'''
__jid_event__.fire_event({'message': 'Searching for hosts'}, 'progress')
data = query(host, quiet=True)
@ -256,25 +269,29 @@ def init(
)
try:
cmd_ret = client.cmd_iter(
host,
'virt.init',
[
name,
cpu,
mem,
image,
nic,
hypervisor,
start,
disk,
saltenv,
seed,
install,
pub_key,
priv_key,
enable_vnc,
],
timeout=600)
host,
'virt.init',
[
name,
cpu,
mem
],
timeout=600,
kwarg={
'image': image,
'nic': nic,
'hypervisor': hypervisor,
'start': start,
'disk': disk,
'saltenv': saltenv,
'seed': seed,
'install': install,
'pub_key': pub_key,
'priv_key': priv_key,
'seed_cmd': seed_cmd,
'enable_vnc': enable_vnc,
'enable_qcow': enable_qcow,
})
except SaltClientError as client_error:
# Fall through to ret error handling below
print(client_error)

View file

@ -69,7 +69,7 @@ def set_(key, value, service=None, profile=None): # pylint: disable=W0613
'''
key, profile = _parse_key(key, profile)
cache = salt.cache.Cache(__opts__)
cache.set(profile['bank'], key=key, value=value)
cache.store(profile['bank'], key, value)
return get(key, service, profile)

View file

@ -49,6 +49,7 @@ def cert(name,
server=None,
owner='root',
group='root',
mode='0640',
certname=None):
'''
Obtain/renew a certificate from an ACME CA, probably Let's Encrypt.
@ -61,8 +62,9 @@ def cert(name,
:param renew: True/'force' to force a renewal, or a window of renewal before expiry in days
:param keysize: RSA key bits
:param server: API endpoint to talk to
:param owner: owner of private key
:param group: group of private key
:param owner: owner of the private key file
:param group: group of the private key file
:param mode: mode of the private key file
:param certname: Name of the certificate to save
'''
@ -105,7 +107,8 @@ def cert(name,
keysize=keysize,
server=server,
owner=owner,
group=group
group=group,
mode=mode
)
ret = {

View file

@ -80,6 +80,8 @@ def _checksum_file_path(path):
drive.rstrip(':'),
path.lstrip('/\\'),
)
elif str(exc).startswith('Cannot mix UNC'):
relpath = salt.utils.path_join('unc', path)
else:
raise
ret = salt.utils.path_join(__opts__['cachedir'], 'archive_hash', relpath)

View file

@ -1225,7 +1225,7 @@ def _makedirs(name,
Helper function for creating directories when the ``makedirs`` option is set
to ``True``. Handles Unix and Windows based systems
.. versionadded:: 2017.7.7
.. versionadded:: 2017.7.8
Args:
name (str): The directory path to create
@ -1396,19 +1396,25 @@ def symlink(
preflight_errors = []
if salt.utils.is_windows():
# Make sure the passed owner exists
if not salt.utils.win_functions.get_sid_from_name(win_owner):
try:
salt.utils.win_functions.get_sid_from_name(win_owner)
except CommandExecutionError as exc:
preflight_errors.append('User {0} does not exist'.format(win_owner))
# Make sure users passed in win_perms exist
if win_perms:
for name_check in win_perms:
if not salt.utils.win_functions.get_sid_from_name(name_check):
try:
salt.utils.win_functions.get_sid_from_name(name_check)
except CommandExecutionError as exc:
preflight_errors.append('User {0} does not exist'.format(name_check))
# Make sure users passed in win_deny_perms exist
if win_deny_perms:
for name_check in win_deny_perms:
if not salt.utils.win_functions.get_sid_from_name(name_check):
try:
salt.utils.win_functions.get_sid_from_name(name_check)
except CommandExecutionError as exc:
preflight_errors.append('User {0} does not exist'.format(name_check))
else:
uid = __salt__['file.user_to_uid'](user)
@ -5663,7 +5669,7 @@ def copy(
if not os.path.isdir(dname):
if makedirs:
try:
_makedirs(name=name)
_makedirs(name=name, user=user, group=group, dir_mode=mode)
except CommandExecutionError as exc:
return _error(ret, 'Drive {0} is not mapped'.format(exc.message))
else:

View file

@ -713,8 +713,8 @@ def repo_present(
ret['result'] = None
else:
result = __salt__['github.add_team_repo'](name, team_name,
permission,
profile=profile)
profile=profile,
permission=permission)
if result:
ret['changes'][team_name] = team_change
else:

View file

@ -72,9 +72,16 @@ def _changes(name,
delusers = [salt.utils.win_functions.get_sam_name(user).lower() for user in delusers]
change = {}
ret = {}
if gid:
if lgrp['gid'] != gid:
change['gid'] = gid
try:
gid = int(gid)
if lgrp['gid'] != gid:
change['gid'] = gid
except (TypeError, ValueError):
ret['result'] = False
ret['comment'] = 'Invalid gid'
return ret
if members:
# -- if new member list if different than the current

View file

@ -275,9 +275,13 @@ def bootstrap(name, user=None, silent=True):
if __opts__['test']:
try:
call = __salt__['npm.install'](dir=name, runas=user, pkg=None, silent=silent, dry_run=True)
ret['result'] = None
ret['changes'] = {'old': [], 'new': call}
ret['comment'] = '{0} is set to be bootstrapped'.format(name)
if call:
ret['result'] = None
ret['changes'] = {'old': [], 'new': call}
ret['comment'] = '{0} is set to be bootstrapped'.format(name)
else:
ret['result'] = True
ret['comment'] = '{0} is already bootstrapped'.format(name)
except (CommandNotFoundError, CommandExecutionError) as err:
ret['result'] = False
ret['comment'] = 'Error Bootstrapping \'{0}\': {1}'.format(name, err)

View file

@ -255,7 +255,12 @@ def _disable(name, started, result=True, **kwargs):
return ret
# Service can be disabled
before_toggle_disable_status = __salt__['service.disabled'](name)
if salt.utils.is_windows():
# service.disabled in Windows returns True for services that are set to
# Manual start, so we need to check specifically for Disabled
before_toggle_disable_status = __salt__['service.info'](name)['StartType'] in ['Disabled']
else:
before_toggle_disable_status = __salt__['service.disabled'](name)
if before_toggle_disable_status:
# Service is disabled
if started is True:
@ -549,7 +554,12 @@ def dead(name,
# command, so it is just an indicator but can not be fully trusted
before_toggle_status = __salt__['service.status'](name, sig)
if 'service.enabled' in __salt__:
before_toggle_enable_status = __salt__['service.enabled'](name)
if salt.utils.is_windows():
# service.enabled in Windows returns True for services that are set
# to Auto start, but services set to Manual can also be disabled
before_toggle_enable_status = __salt__['service.info'](name)['StartType'] in ['Auto', 'Manual']
else:
before_toggle_enable_status = __salt__['service.enabled'](name)
else:
before_toggle_enable_status = True

View file

@ -8,6 +8,7 @@ powercfg.
.. code-block:: yaml
# Set timeout to 30 minutes on battery power
monitor:
powercfg.set_timeout:
- value: 30
@ -18,82 +19,131 @@ powercfg.
from __future__ import absolute_import
import logging
# Import Salt Libs
import salt.utils
log = logging.getLogger(__name__)
__virtualname__ = "powercfg"
__virtualname__ = 'powercfg'
def __virtual__():
'''
Only work on Windows
'''
if __grains__['os'] == 'Windows':
return __virtualname__
return False
if not salt.utils.is_windows():
return False, 'PowerCFG: Module only works on Windows'
return __virtualname__
def _check_or_set(check_func, set_func, value, power):
values = check_func()
if values[power] == value:
return True
else:
set_func(value, power)
return False
def set_timeout(name, value, power="ac", scheme=None):
def set_timeout(name, value, power='ac', scheme=None):
'''
Set the sleep timeouts of specific items such as disk, monitor.
Set the sleep timeouts of specific items such as disk, monitor, etc.
Args:
name (str)
The setting to change, can be one of the following:
- ``monitor``
- ``disk``
- ``standby``
- ``hibernate``
value (int):
The amount of time in minutes before the item will timeout
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
CLI Example:
.. code-block:: yaml
# Set monitor timeout to 30 minutes on Battery
monitor:
powercfg.set_timeout:
- value: 30
- power: dc
powercfg.set_timeout:
- value: 30
- power: dc
# Set disk timeout to 10 minutes on AC Power
disk:
powercfg.set_timeout:
- value: 12
- power: ac
name
The setting to change, can be one of the following: monitor, disk, standby, hibernate
timeout
The amount of time in minutes before the item will timeout i.e the monitor
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
powercfg.set_timeout:
- value: 10
- power: ac
'''
ret = {'name': name,
'result': True,
'comment': '',
'changes': {}}
comment = []
# Validate name values
name = name.lower()
if name not in ['monitor', 'disk', 'standby', 'hibernate']:
ret['result'] = False
ret['comment'] = '"{0}" is not a valid setting'.format(name)
log.debug(ret['comment'])
return ret
if name not in ["monitor", "disk", "standby", "hibernate"]:
ret["result"] = False
comment.append("{0} is not a valid setting".format(name))
elif power not in ["ac", "dc"]:
ret["result"] = False
comment.append("{0} is not a power type".format(power))
# Validate power values
power = power.lower()
if power not in ['ac', 'dc']:
ret['result'] = False
ret['comment'] = '"{0}" is not a power type'.format(power)
log.debug(ret['comment'])
return ret
# Get current settings
old = __salt__['powercfg.get_{0}_timeout'.format(name)](scheme=scheme)
# Check current settings
if old[power] == value:
ret['comment'] = '{0} timeout on {1} power is already set to {2}' \
''.format(name.capitalize(), power.upper(), value)
return ret
else:
check_func = __salt__["powercfg.get_{0}_timeout".format(name)]
set_func = __salt__["powercfg.set_{0}_timeout".format(name)]
ret['comment'] = '{0} timeout on {1} power will be set to {2}' \
''.format(name.capitalize(), power.upper(), value)
values = check_func(scheme=scheme)
if values[power] == value:
comment.append("{0} {1} is already set with the value {2}.".format(name, power, value))
else:
ret['changes'] = {name: {power: value}}
set_func(value, power, scheme=scheme)
# Check for test=True
if __opts__['test']:
ret['result'] = None
return ret
# Set the timeout value
__salt__['powercfg.set_{0}_timeout'.format(name)](
timeout=value,
power=power,
scheme=scheme)
# Get the setting after the change
new = __salt__['powercfg.get_{0}_timeout'.format(name)](scheme=scheme)
changes = salt.utils.compare_dicts(old, new)
if changes:
ret['changes'] = {name: changes}
ret['comment'] = '{0} timeout on {1} power set to {2}' \
''.format(name.capitalize(), power.upper(), value)
log.debug(ret['comment'])
else:
ret['changes'] = {}
ret['comment'] = 'Failed to set {0} timeout on {1} power to {2}' \
''.format(name, power.upper(), value)
log.debug(ret['comment'])
ret['result'] = False
ret['comment'] = ' '.join(comment)
return ret

View file

@ -752,9 +752,9 @@ class IPCMessageSubscriber(IPCClient):
# This will prevent this message from showing up:
# '[ERROR ] Future exception was never retrieved:
# StreamClosedError'
if self._read_sync_future is not None:
if self._read_sync_future is not None and self._read_sync_future.done():
self._read_sync_future.exception()
if self._read_stream_future is not None:
if self._read_stream_future is not None and self._read_stream_future.done():
self._read_stream_future.exception()
def __del__(self):

View file

@ -896,10 +896,9 @@ class SaltMessageClient(object):
# This happens because the logic is always waiting to read
# the next message and the associated read future is marked
# 'StreamClosedError' when the stream is closed.
self._read_until_future.exception()
if (not self._stream_return_future.done() and
self.io_loop != tornado.ioloop.IOLoop.current(
instance=False)):
if self._read_until_future.done():
self._read_until_future.exception()
elif self.io_loop != tornado.ioloop.IOLoop.current(instance=False):
self.io_loop.add_future(
self._stream_return_future,
lambda future: self.io_loop.stop()
@ -1134,7 +1133,7 @@ class Subscriber(object):
self._closing = True
if not self.stream.closed():
self.stream.close()
if self._read_until_future is not None:
if self._read_until_future is not None and self._read_until_future.done():
# This will prevent this message from showing up:
# '[ERROR ] Future exception was never retrieved:
# StreamClosedError'

View file

@ -2360,7 +2360,7 @@ def alias_function(fun, name, doc=None):
orig_name = fun.__name__
alias_msg = ('\nThis function is an alias of '
'``{0}``.\n'.format(orig_name))
alias_fun.__doc__ = alias_msg + fun.__doc__
alias_fun.__doc__ = alias_msg + (fun.__doc__ or '')
return alias_fun

View file

@ -70,10 +70,9 @@ def _init_libcrypto():
libcrypto.RSA_public_decrypt.argtypes = (c_int, c_char_p, c_char_p, c_void_p, c_int)
try:
if libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS, None) != 1:
raise OSError("Failed to initialize OpenSSL library (OPENSSL_init_crypto failed)")
libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS, None)
except AttributeError:
# Support for OpenSSL < 1.1 (OPENSSL_API_COMPAT < 0x10100000L)
libcrypto.OPENSSL_no_config()

View file

@ -156,20 +156,23 @@ def query(key, keyid, method='GET', params=None, headers=None,
headers=headers,
data=data,
verify=verify_ssl,
stream=True)
stream=True,
timeout=300)
elif method == 'GET' and local_file and not return_bin:
result = requests.request(method,
requesturl,
headers=headers,
data=data,
verify=verify_ssl,
stream=True)
stream=True,
timeout=300)
else:
result = requests.request(method,
requesturl,
headers=headers,
data=data,
verify=verify_ssl)
verify=verify_ssl,
timeout=300)
finally:
if data is not None:
data.close()

View file

@ -14,6 +14,7 @@ import tarfile
import zipfile
import tempfile
import subprocess
import concurrent
# Import third party libs
import jinja2
@ -106,6 +107,8 @@ def get_tops(extra_mods='', so_mods=''):
os.path.dirname(msgpack.__file__),
]
if _six.PY2:
tops.append(os.path.dirname(concurrent.__file__))
tops.append(_six.__file__.replace('.pyc', '.py'))
tops.append(backports_abc.__file__.replace('.pyc', '.py'))

View file

@ -14,8 +14,8 @@
# Import python libs
from __future__ import absolute_import
# pylint: disable=blacklisted-module
from distutils.version import StrictVersion as _StrictVersion
from distutils.version import LooseVersion as _LooseVersion
from distutils.version import StrictVersion as _StrictVersion # pylint: disable=no-name-in-module
from distutils.version import LooseVersion as _LooseVersion # pylint: disable=no-name-in-module
# pylint: enable=blacklisted-module
# Import 3rd-party libs

Some files were not shown because too many files have changed in this diff Show more