mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2018.3' into '2019.2'
Conflicts: - doc/conf.py - salt/modules/win_system.py - salt/states/boto3_route53.py
This commit is contained in:
commit
a16891347c
18 changed files with 265 additions and 145 deletions
|
@ -2,7 +2,7 @@
|
|||
Salt Release Process
|
||||
====================
|
||||
|
||||
The goal for Salt projects is to cut a new feature release every four to six
|
||||
The goal for Salt projects is to cut a new feature release every six
|
||||
months. This document outlines the process for these releases, and the
|
||||
subsequent bug fix releases which follow.
|
||||
|
||||
|
@ -11,29 +11,66 @@ Feature Release Process
|
|||
=======================
|
||||
|
||||
When a new release is ready to be cut, the person responsible for cutting the
|
||||
release will follow the following steps (written using the 0.16 release as an
|
||||
release will follow the following steps (written using the 2019.2.0 release as an
|
||||
example):
|
||||
|
||||
#. All open issues on the release milestone should be moved to the next release
|
||||
milestone. (e.g. from the ``0.16`` milestone to the ``0.17`` milestone)
|
||||
#. Release notes should be created documenting the major new features and
|
||||
bugfixes in the release.
|
||||
#. Create an annotated tag with only the major and minor version numbers,
|
||||
preceded by the letter ``v``. (e.g. ``v0.16``) This tag will reside on the
|
||||
``develop`` branch.
|
||||
#. Create a branch for the new release, using only the major and minor version
|
||||
numbers. (e.g. ``0.16``)
|
||||
#. On this new branch, create an annotated tag for the first revision release,
|
||||
which is generally a release candidate. It should be preceded by the letter
|
||||
``v``. (e.g. ``v0.16.0rc1``)
|
||||
#. The release should be packaged from this annotated tag and uploaded to PyPI
|
||||
as well as the GitHub releases page for this tag.
|
||||
#. The packagers should be notified on the `salt-packagers`_ mailing list so
|
||||
they can create packages for all the major operating systems. (note that
|
||||
release candidates should go in the testing repositories)
|
||||
#. After the packagers have been given a few days to compile the packages, the
|
||||
release is announced on the `salt-users`_ mailing list.
|
||||
#. Log into RTD and add the new release there. (Have to do it manually)
|
||||
#. Create first public draft of release notes with major features.
|
||||
#. Remove any deprecations for the upcoming release.
|
||||
#. Notify salt-users and salt-announce google groups when the feature freeze
|
||||
branch creation will occur so they can try to get their work merged.
|
||||
#. Create QA test plan. Review features planned for the release and determine if
|
||||
there is sufficient test coverage.
|
||||
#. Ensure all required features are merged.
|
||||
#. Complete one last merge forward from the previous branch.
|
||||
#. Create feature release branch with the name of the release. (ex. fluorine)
|
||||
#. Create issue to start the process of deprecating for the next feature release.
|
||||
#. Create jenkins jobs to test the new feature release branch.
|
||||
#. Inform salt-users and salt-announce google groups feature branch and
|
||||
freeze is complete.
|
||||
#. Add new feature branch to salt-jenkins repo and the kitchen yaml file.
|
||||
#. Fix tests failing in jenkins test runs.
|
||||
#. Finalize QA test plan and add all required tests.
|
||||
#. Run through a manual test run based off of the head of the feature branch.
|
||||
#. Convert the feature release branch to the version number. For example (v2019.2)
|
||||
This is based off of the year and month that is planned to release.
|
||||
#. Migrate both the jenkins test jobs and salt-jenkins repo to the new branch number.
|
||||
#. Notify salt-users and salt-announce google groups of the new version branch
|
||||
number and migrate any PRs to the new branch.
|
||||
#. Delete old feature release branch name (ex. fluorine)
|
||||
#. Update all name references to version number in the docs. For example
|
||||
all fluorine references in the docs needs to be moved to v2019.2.0
|
||||
#. Create RC release branch. (ex. 2019.2.0.rc)
|
||||
#. Create new jenkins test jobs with new RC release branch
|
||||
#. Notify salt-users and salt-announce google groups of the new RC branch.
|
||||
#. Fix tests failing in jenkins test runs.
|
||||
#. Review the release notes with major features.
|
||||
#. Generate the new man pages for the release.
|
||||
#. Create internal RC tag for testing.
|
||||
#. Build latest windows, mac, ubuntu, debian and redhat packages.
|
||||
#. Run manual and package tests against new RC packages.
|
||||
#. Update release candidate docs with the new version. (ex. 2019.2.0rc1)
|
||||
#. Push the internal tag live to salt's repo.
|
||||
#. Publish release archive to pypi based off tag.
|
||||
#. Push the RC packages live.
|
||||
#. Announce new RC to salt-users and salt-announce google groups.
|
||||
#. Triage incoming issues based on the new RC release.
|
||||
#. Fix RC issues once they are categorized as a release blocker.
|
||||
#. Depending on the issues found during the RC process make a decesion
|
||||
on whether to release based off the RC or go through another RC process,
|
||||
repeating the steps starting at ensuring the tests are not failing.
|
||||
#. If a RC is categorized as stable, build all required packages.
|
||||
#. Test all release packages.
|
||||
#. Test links from `repo.saltstack.com`_.
|
||||
#. Update installation instructions with new release number at `repo.saltstack.com`_.
|
||||
#. Update and build docs to include new version (2019.2) as the latest.
|
||||
#. Pre-announce on salt-users google group that we are about to update our repo.
|
||||
#. Publish release (v2019.2.0) archive to pypi based off tag.
|
||||
#. Publish all packages live to repo.
|
||||
#. Publish the docs.
|
||||
#. Create release at `github`_
|
||||
#. Update win-repo-ng with new salt versions.
|
||||
#. Announce release is live to irc, salt-users, salt-announce and release slack
|
||||
community channel.
|
||||
|
||||
|
||||
Maintenance and Bugfix Releases
|
||||
|
@ -44,16 +81,34 @@ into a "feature freeze" state. The new release branch enters the ``merge-forward
|
|||
chain and only bugfixes should be applied against the new branch. Once major bugs
|
||||
have been fixed, a bugfix release can be cut:
|
||||
|
||||
#. On the release branch (i.e. ``0.16``), create an annotated tag for the
|
||||
revision release. It should be preceded by the letter ``v``. (e.g.
|
||||
``v0.16.2``) Release candidates are unnecessary for bugfix releases.
|
||||
#. The release should be packaged from this annotated tag and uploaded to PyPI.
|
||||
#. The packagers should be notified on the `salt-packagers`_ mailing list so
|
||||
they can create packages for all the major operating systems.
|
||||
#. After the packagers have been given a few days to compile the packages, the
|
||||
release is announced on the `salt-users`_ mailing list.
|
||||
#. Ensure all required bug fixes are merged.
|
||||
#. Inform salt-users and salt-announce we are going to branch for the release.
|
||||
#. Complete one last merge forward from the previous branch.
|
||||
#. Create release branch with the version of the release. (ex. 2019.2.1)
|
||||
#. Create jenkins jobs that test the new release branch.
|
||||
#. Fix tests failing in jeknins test runs.
|
||||
#. Run through a manual test run based off of the head of the branch.
|
||||
#. Generate the new man pages for the release.
|
||||
#. Create internal tag for testing.(ex v2019.2.1)
|
||||
#. Build all release packages.
|
||||
#. Run manual and package tests against new packages.
|
||||
#. Update installation instructions with new release number at `repo.saltstack.com`_.
|
||||
#. Update and build docs to include new version. (ex. 2019.2.1)
|
||||
#. Pre-announce on salt-users google groups that we are about to update our repo.
|
||||
#. Push the internal tag live to salt's repo.
|
||||
#. Publish release archive to pypi based off tag.
|
||||
#. Push the packages live.
|
||||
#. Publish release (v2019.2.1) archive to pypi based off tag.
|
||||
#. Publish all packages live to repo.
|
||||
#. Publish the docs.
|
||||
#. Create release at `github`_
|
||||
#. Update win-repo-ng with new salt versions.
|
||||
#. Announce release is live to irc, salt-users, salt-announce and release slack channel.
|
||||
|
||||
For more information about the difference between the ``develop`` branch and
|
||||
bugfix release branches, please refer to the :ref:`Which Salt Branch?
|
||||
<which-salt-branch>` section of Salt's :ref:`Contributing <contributing>`
|
||||
documentation.
|
||||
|
||||
.. _`github`: https://github.com/saltstack/salt/releases
|
||||
.. _`repo.saltstack.com`: https://repo.saltstack.com
|
||||
|
|
|
@ -68,11 +68,10 @@ related release branches.
|
|||
For more information, please see the :ref:`Which Salt Branch? <which-salt-branch>`
|
||||
section of Salt's :ref:`Contributing <contributing>` documentation.
|
||||
|
||||
Determining when a point release is going to be made is up to the project
|
||||
leader (Thomas Hatch). Generally point releases are made every 2-4 weeks or
|
||||
if there is a security fix they can be made sooner.
|
||||
Generally point releases are made every 2 months or if there is a security fix
|
||||
they can be made sooner.
|
||||
|
||||
The point release is only designated by tagging the commit on the release
|
||||
branch with a release number using the existing convention (version 2015.8.1
|
||||
is tagged with v2015.8.1). From the tag point a new source tarball is generated
|
||||
and published to PyPI, and a release announcement is made.
|
||||
The point release is designated by branching (ex 2019.2.1) and then tagging (v2019.2.1)
|
||||
from that newly created release branch when its determined the release is stable.
|
||||
From the tag point a new source tarball is generated and published to PyPI,
|
||||
and a release announcement is made.
|
||||
|
|
6
doc/topics/releases/2018.3.5.rst
Normal file
6
doc/topics/releases/2018.3.5.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
========================================
|
||||
In Progress: Salt 2018.3.5 Release Notes
|
||||
========================================
|
||||
|
||||
Version 2018.3.5 is an **unreleased** bugfix release for :ref:`2018.3.0 <release-2018-3-0>`.
|
||||
This release is still in progress and has not been released yet.
|
|
@ -495,8 +495,6 @@ If Exist "%BinDir%\Lib\site-packages\salt\modules\xfs.py"^
|
|||
del /Q "%BinDir%\Lib\site-packages\salt\modules\xfs.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\modules\yumpkg.py"^
|
||||
del /Q "%BinDir%\Lib\site-packages\salt\modules\yum.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\modules\zabbix.py"^
|
||||
del /Q "%BinDir%\Lib\site-packages\salt\modules\zabbix.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\modules\zfs.py"^
|
||||
del /Q "%BinDir%\Lib\site-packages\salt\modules\zfs.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\modules\znc.py"^
|
||||
|
@ -601,8 +599,6 @@ If Exist "%BinDir%\Lib\site-packages\salt\states\vbox_guest.py"^
|
|||
del /Q "%BinDir%\Lib\site-packages\salt\states\vbox_guest.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\states\virt.py"^
|
||||
del /Q "%BinDir%\Lib\site-packages\salt\states\virt.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\states\zabbix*"^
|
||||
del /Q "%BinDir%\Lib\site-packages\salt\states\zabbix*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\states\zfs.py"^
|
||||
del /Q "%BinDir%\Lib\site-packages\salt\states\zfs.*" 1>nul
|
||||
If Exist "%BinDir%\Lib\site-packages\salt\states\zpool.py"^
|
||||
|
|
|
@ -97,7 +97,13 @@ def beacon(config):
|
|||
mount_re = '{0}$'.format(mount)
|
||||
|
||||
if salt.utils.platform.is_windows():
|
||||
mount_re = re.sub('\\$', '\\\\', mount_re)
|
||||
# mount_re comes in formatted with a $ at the end
|
||||
# can be `C:\\$` or `C:\\\\$`
|
||||
# re string must be like `C:\\\\` regardless of \\ or \\\\
|
||||
# also, psutil returns uppercase
|
||||
mount_re = re.sub(r':\\\$', r':\\\\', mount_re)
|
||||
mount_re = re.sub(r':\\\\\$', r':\\\\', mount_re)
|
||||
mount_re = mount_re.upper()
|
||||
|
||||
for part in parts:
|
||||
if re.match(mount_re, part.mountpoint):
|
||||
|
|
|
@ -45,6 +45,9 @@ def __virtual__():
|
|||
'''
|
||||
# NOTE: we always load this grain so we can properly export
|
||||
# at least the zfs_support grain
|
||||
# except for Windows... don't try to load this on Windows (#51703)
|
||||
if salt.utils.platform.is_windows():
|
||||
return False, 'ZFS: Not available on Windows'
|
||||
return __virtualname__
|
||||
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ import logging
|
|||
# Import Salt libs
|
||||
import salt.utils.platform
|
||||
import salt.utils.win_functions
|
||||
import salt.utils.winapi
|
||||
|
||||
try:
|
||||
import win32api
|
||||
import win32com.client
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
HAS_DEPENDENCIES = True
|
||||
except ImportError:
|
||||
|
@ -46,8 +46,8 @@ def _get_computer_object():
|
|||
Returns:
|
||||
object: Returns the computer object for the local machine
|
||||
'''
|
||||
pythoncom.CoInitialize()
|
||||
nt = win32com.client.Dispatch('AdsNameSpaces')
|
||||
with salt.utils.winapi.Com():
|
||||
nt = win32com.client.Dispatch('AdsNameSpaces')
|
||||
return nt.GetObject('', 'WinNT://.,computer')
|
||||
|
||||
|
||||
|
@ -62,8 +62,8 @@ def _get_group_object(name):
|
|||
Returns:
|
||||
object: The specified group object
|
||||
'''
|
||||
pythoncom.CoInitialize()
|
||||
nt = win32com.client.Dispatch('AdsNameSpaces')
|
||||
with salt.utils.winapi.Com():
|
||||
nt = win32com.client.Dispatch('AdsNameSpaces')
|
||||
return nt.GetObject('', 'WinNT://./' + name + ',group')
|
||||
|
||||
|
||||
|
@ -75,8 +75,8 @@ def _get_all_groups():
|
|||
Returns:
|
||||
iter: A list of objects for all groups on the machine
|
||||
'''
|
||||
pythoncom.CoInitialize()
|
||||
nt = win32com.client.Dispatch('AdsNameSpaces')
|
||||
with salt.utils.winapi.Com():
|
||||
nt = win32com.client.Dispatch('AdsNameSpaces')
|
||||
results = nt.GetObject('', 'WinNT://.')
|
||||
results.Filter = ['group']
|
||||
return results
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
Module for managing windows systems.
|
||||
|
||||
:depends:
|
||||
- pythoncom
|
||||
- pywintypes
|
||||
- win32api
|
||||
- win32con
|
||||
|
@ -25,12 +24,12 @@ from datetime import datetime
|
|||
import salt.utils.functools
|
||||
import salt.utils.locales
|
||||
import salt.utils.platform
|
||||
import salt.utils.winapi
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
# Import 3rd-party Libs
|
||||
from salt.ext import six
|
||||
try:
|
||||
import pythoncom
|
||||
import wmi
|
||||
import win32net
|
||||
import win32api
|
||||
|
@ -527,15 +526,14 @@ def get_system_info():
|
|||
else:
|
||||
return '{0:.3f}TB'.format(val / 2**40)
|
||||
|
||||
# Connect to WMI
|
||||
pythoncom.CoInitialize()
|
||||
conn = wmi.WMI()
|
||||
|
||||
# Lookup dicts for Win32_OperatingSystem
|
||||
os_type = {1: 'Work Station',
|
||||
2: 'Domain Controller',
|
||||
3: 'Server'}
|
||||
|
||||
# Connect to WMI
|
||||
with salt.utils.winapi.Com():
|
||||
conn = wmi.WMI()
|
||||
system = conn.Win32_OperatingSystem()[0]
|
||||
ret = {'name': get_computer_name(),
|
||||
'description': system.Description,
|
||||
|
@ -835,8 +833,8 @@ def _join_domain(domain,
|
|||
if not account_exists:
|
||||
join_options |= NETSETUP_ACCOUNT_CREATE
|
||||
|
||||
pythoncom.CoInitialize()
|
||||
conn = wmi.WMI()
|
||||
with salt.utils.winapi.Com():
|
||||
conn = wmi.WMI()
|
||||
comp = conn.Win32_ComputerSystem()[0]
|
||||
|
||||
# Return the results of the command as an error
|
||||
|
@ -927,8 +925,8 @@ def unjoin_domain(username=None,
|
|||
if disable:
|
||||
unjoin_options |= NETSETUP_ACCT_DELETE
|
||||
|
||||
pythoncom.CoInitialize()
|
||||
conn = wmi.WMI()
|
||||
with salt.utils.winapi.Com():
|
||||
conn = wmi.WMI()
|
||||
comp = conn.Win32_ComputerSystem()[0]
|
||||
err = comp.UnjoinDomainOrWorkgroup(Password=password,
|
||||
UserName=username,
|
||||
|
@ -971,8 +969,8 @@ def get_domain_workgroup():
|
|||
|
||||
salt 'minion-id' system.get_domain_workgroup
|
||||
'''
|
||||
pythoncom.CoInitialize()
|
||||
conn = wmi.WMI()
|
||||
with salt.utils.winapi.Com():
|
||||
conn = wmi.WMI()
|
||||
for computer in conn.Win32_ComputerSystem():
|
||||
if computer.PartOfDomain:
|
||||
return {'Domain': computer.Domain}
|
||||
|
|
|
@ -17,6 +17,7 @@ from datetime import datetime
|
|||
|
||||
# Import Salt libs
|
||||
import salt.utils.platform
|
||||
import salt.utils.winapi
|
||||
|
||||
# Import 3rd-party libraries
|
||||
try:
|
||||
|
@ -334,8 +335,8 @@ def list_tasks(location='\\'):
|
|||
salt 'minion-id' task.list_tasks
|
||||
'''
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the folder to list tasks from
|
||||
|
@ -367,8 +368,8 @@ def list_folders(location='\\'):
|
|||
salt 'minion-id' task.list_folders
|
||||
'''
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the folder to list folders from
|
||||
|
@ -402,8 +403,8 @@ def list_triggers(name, location='\\'):
|
|||
salt 'minion-id' task.list_triggers <task_name>
|
||||
'''
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the folder to list folders from
|
||||
|
@ -438,8 +439,8 @@ def list_actions(name, location='\\'):
|
|||
salt 'minion-id' task.list_actions <task_name>
|
||||
'''
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the folder to list folders from
|
||||
|
@ -500,8 +501,8 @@ def create_task(name,
|
|||
return '{0} already exists'.format(name)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Create a new task definition
|
||||
|
@ -585,8 +586,8 @@ def create_task_from_xml(name,
|
|||
return 'Must specify either xml_text or xml_path'
|
||||
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Load xml from file, overrides xml_text
|
||||
|
@ -665,8 +666,8 @@ def create_folder(name, location='\\'):
|
|||
return '{0} already exists'.format(name)
|
||||
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the folder to list folders from
|
||||
|
@ -880,8 +881,8 @@ def edit_task(name=None,
|
|||
if name in list_tasks(location):
|
||||
|
||||
# Connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to create the task in
|
||||
|
@ -1046,8 +1047,8 @@ def delete_task(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to delete the task from
|
||||
|
@ -1086,8 +1087,8 @@ def delete_folder(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to delete the folder from
|
||||
|
@ -1127,8 +1128,8 @@ def run(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to delete the folder from
|
||||
|
@ -1166,8 +1167,8 @@ def run_wait(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to delete the folder from
|
||||
|
@ -1223,8 +1224,8 @@ def stop(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to delete the folder from
|
||||
|
@ -1269,8 +1270,8 @@ def status(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder where the task is defined
|
||||
|
@ -1304,8 +1305,8 @@ def info(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to delete the folder from
|
||||
|
@ -1500,8 +1501,8 @@ def add_action(name=None,
|
|||
if name in list_tasks(location):
|
||||
|
||||
# Connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to create the task in
|
||||
|
@ -1607,8 +1608,8 @@ def _clear_actions(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the actions from the task
|
||||
|
@ -2011,8 +2012,8 @@ def add_trigger(name=None,
|
|||
if name in list_tasks(location):
|
||||
|
||||
# Connect to the task scheduler
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# get the folder to create the task in
|
||||
|
@ -2190,8 +2191,8 @@ def clear_triggers(name, location='\\'):
|
|||
return '{0} not found in {1}'.format(name, location)
|
||||
|
||||
# Create the task service object
|
||||
pythoncom.CoInitialize()
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
with salt.utils.winapi.Com():
|
||||
task_service = win32com.client.Dispatch("Schedule.Service")
|
||||
task_service.Connect()
|
||||
|
||||
# Get the triggers from the task
|
||||
|
|
|
@ -9,7 +9,6 @@ Module for managing Windows Users
|
|||
<module-provider-override>`.
|
||||
|
||||
:depends:
|
||||
- pythoncom
|
||||
- pywintypes
|
||||
- win32api
|
||||
- win32con
|
||||
|
@ -38,6 +37,7 @@ except Exception:
|
|||
import salt.utils.args
|
||||
import salt.utils.dateutils
|
||||
import salt.utils.platform
|
||||
import salt.utils.winapi
|
||||
from salt.ext import six
|
||||
from salt.ext.six import string_types
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
@ -47,7 +47,6 @@ log = logging.getLogger(__name__)
|
|||
try:
|
||||
import pywintypes
|
||||
import wmi
|
||||
import pythoncom
|
||||
import win32api
|
||||
import win32con
|
||||
import win32net
|
||||
|
@ -989,8 +988,8 @@ def rename(name, new_name):
|
|||
|
||||
# Rename the user account
|
||||
# Connect to WMI
|
||||
pythoncom.CoInitialize()
|
||||
c = wmi.WMI(find_classes=0)
|
||||
with salt.utils.winapi.Com():
|
||||
c = wmi.WMI(find_classes=0)
|
||||
|
||||
# Get the user object
|
||||
try:
|
||||
|
|
|
@ -62,12 +62,12 @@ import logging
|
|||
# Import Salt libs
|
||||
import salt.utils.platform
|
||||
import salt.utils.win_update
|
||||
import salt.utils.winapi
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
try:
|
||||
import pythoncom
|
||||
import win32com.client
|
||||
HAS_PYWIN32 = True
|
||||
except ImportError:
|
||||
|
@ -704,6 +704,7 @@ def set_wu_settings(level=None,
|
|||
# work on Windows 10 / Server 2016. It is called in throughout this function
|
||||
# like this:
|
||||
#
|
||||
# with salt.utils.winapi.Com():
|
||||
# obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||
# obj_au_settings = obj_au.Settings
|
||||
# obj_au_settings.Save()
|
||||
|
@ -724,10 +725,10 @@ def set_wu_settings(level=None,
|
|||
ret = {'Success': True}
|
||||
|
||||
# Initialize the PyCom system
|
||||
pythoncom.CoInitialize()
|
||||
with salt.utils.winapi.Com():
|
||||
|
||||
# Create an AutoUpdate object
|
||||
obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||
# Create an AutoUpdate object
|
||||
obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||
|
||||
# Create an AutoUpdate Settings Object
|
||||
obj_au_settings = obj_au.Settings
|
||||
|
@ -821,7 +822,8 @@ def set_wu_settings(level=None,
|
|||
if msupdate is not None:
|
||||
# Microsoft Update requires special handling
|
||||
# First load the MS Update Service Manager
|
||||
obj_sm = win32com.client.Dispatch('Microsoft.Update.ServiceManager')
|
||||
with salt.utils.winapi.Com():
|
||||
obj_sm = win32com.client.Dispatch('Microsoft.Update.ServiceManager')
|
||||
|
||||
# Give it a bogus name
|
||||
obj_sm.ClientApplicationID = "My App"
|
||||
|
@ -922,10 +924,9 @@ def get_wu_settings():
|
|||
'Saturday']
|
||||
|
||||
# Initialize the PyCom system
|
||||
pythoncom.CoInitialize()
|
||||
|
||||
# Create an AutoUpdate object
|
||||
obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||
with salt.utils.winapi.Com():
|
||||
# Create an AutoUpdate object
|
||||
obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||
|
||||
# Create an AutoUpdate Settings Object
|
||||
obj_au_settings = obj_au.Settings
|
||||
|
@ -959,8 +960,10 @@ def _get_msupdate_status():
|
|||
'''
|
||||
# To get the status of Microsoft Update we actually have to check the
|
||||
# Microsoft Update Service Manager
|
||||
# Create a ServiceManager Object
|
||||
obj_sm = win32com.client.Dispatch('Microsoft.Update.ServiceManager')
|
||||
# Initialize the PyCom system
|
||||
with salt.utils.winapi.Com():
|
||||
# Create a ServiceManager Object
|
||||
obj_sm = win32com.client.Dispatch('Microsoft.Update.ServiceManager')
|
||||
|
||||
# Return a collection of loaded Services
|
||||
col_services = obj_sm.Services
|
||||
|
|
|
@ -14,7 +14,6 @@ import datetime
|
|||
|
||||
# Import salt libs
|
||||
import salt.log
|
||||
import salt.crypt
|
||||
import salt.transport.frame
|
||||
import salt.utils.immutabletypes as immutabletypes
|
||||
import salt.utils.stringutils
|
||||
|
|
|
@ -634,8 +634,12 @@ def rr_present(name, HostedZoneId=None, DomainName=None, PrivateZone=False, Name
|
|||
if locals().get(u) != rrset.get(u):
|
||||
update = True
|
||||
break
|
||||
if 'ResourceRecords' in rrset and ResourceRecords != sorted(rrset.get('ResourceRecords'), key=lambda x: x['Value']):
|
||||
update = True
|
||||
if rrset.get('ResourceRecords') is not None:
|
||||
if ResourceRecords != sorted(rrset.get('ResourceRecords'), key=lambda x: x['Value']):
|
||||
update = True
|
||||
elif (AliasTarget is not None) and (rrset.get('AliasTarget') is not None):
|
||||
if sorted(AliasTarget) != sorted(rrset.get('AliasTarget')):
|
||||
update = True
|
||||
|
||||
if not create and not update:
|
||||
ret['comment'] = ('Route 53 resource record {} with type {} is already in the desired state.'
|
||||
|
|
|
@ -301,6 +301,7 @@ from salt.state import get_accumulator_dir as _get_accumulator_dir
|
|||
if salt.utils.platform.is_windows():
|
||||
import salt.utils.win_dacl
|
||||
import salt.utils.win_functions
|
||||
import salt.utils.winapi
|
||||
|
||||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
|
@ -1214,7 +1215,8 @@ def _shortcut_check(name,
|
|||
), pchanges
|
||||
|
||||
if os.path.isfile(name):
|
||||
shell = win32com.client.Dispatch("WScript.Shell")
|
||||
with salt.utils.winapi.Com():
|
||||
shell = win32com.client.Dispatch("WScript.Shell")
|
||||
scut = shell.CreateShortcut(name)
|
||||
state_checks = [scut.TargetPath.lower() == target.lower()]
|
||||
if arguments is not None:
|
||||
|
@ -7434,7 +7436,8 @@ def shortcut(
|
|||
|
||||
# This will just load the shortcut if it already exists
|
||||
# It won't create the file until calling scut.Save()
|
||||
shell = win32com.client.Dispatch("WScript.Shell")
|
||||
with salt.utils.winapi.Com():
|
||||
shell = win32com.client.Dispatch("WScript.Shell")
|
||||
scut = shell.CreateShortcut(name)
|
||||
|
||||
# The shortcut target will automatically be created with its
|
||||
|
|
|
@ -71,9 +71,7 @@ def _init_libcrypto():
|
|||
libcrypto.RSA_public_decrypt.argtypes = (c_int, c_char_p, c_char_p, c_void_p, c_int)
|
||||
|
||||
try:
|
||||
libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
|
||||
OPENSSL_INIT_ADD_ALL_CIPHERS |
|
||||
OPENSSL_INIT_ADD_ALL_DIGESTS, None)
|
||||
libcrypto.OPENSSL_init_crypto()
|
||||
except AttributeError:
|
||||
# Support for OpenSSL < 1.1 (OPENSSL_API_COMPAT < 0x10100000L)
|
||||
libcrypto.OPENSSL_no_config()
|
||||
|
|
|
@ -10,6 +10,7 @@ import subprocess
|
|||
# Import Salt libs
|
||||
import salt.utils.args
|
||||
import salt.utils.data
|
||||
import salt.utils.winapi
|
||||
from salt.ext import six
|
||||
from salt.ext.six.moves import range
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
@ -17,7 +18,6 @@ from salt.exceptions import CommandExecutionError
|
|||
# Import 3rd-party libs
|
||||
try:
|
||||
import win32com.client
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
HAS_PYWIN32 = True
|
||||
except ImportError:
|
||||
|
@ -68,7 +68,8 @@ class Updates(object):
|
|||
Initialize the updates collection. Can be accessed via
|
||||
``Updates.updates``
|
||||
'''
|
||||
self.updates = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
with salt.utils.winapi.Com():
|
||||
self.updates = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
|
||||
def count(self):
|
||||
'''
|
||||
|
@ -274,13 +275,13 @@ class WindowsUpdateAgent(object):
|
|||
Need to look at the possibility of loading this into ``__context__``
|
||||
'''
|
||||
# Initialize the PyCom system
|
||||
pythoncom.CoInitialize()
|
||||
with salt.utils.winapi.Com():
|
||||
|
||||
# Create a session with the Windows Update Agent
|
||||
self._session = win32com.client.Dispatch('Microsoft.Update.Session')
|
||||
# Create a session with the Windows Update Agent
|
||||
self._session = win32com.client.Dispatch('Microsoft.Update.Session')
|
||||
|
||||
# Create Collection for Updates
|
||||
self._updates = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
# Create Collection for Updates
|
||||
self._updates = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
|
||||
self.refresh()
|
||||
|
||||
|
@ -572,7 +573,8 @@ class WindowsUpdateAgent(object):
|
|||
# Initialize the downloader object and list collection
|
||||
downloader = self._session.CreateUpdateDownloader()
|
||||
self._session.ClientApplicationID = 'Salt: Download Update'
|
||||
download_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
with salt.utils.winapi.Com():
|
||||
download_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
|
||||
ret = {'Updates': {}}
|
||||
|
||||
|
@ -683,7 +685,8 @@ class WindowsUpdateAgent(object):
|
|||
|
||||
installer = self._session.CreateUpdateInstaller()
|
||||
self._session.ClientApplicationID = 'Salt: Install Update'
|
||||
install_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
with salt.utils.winapi.Com():
|
||||
install_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
|
||||
ret = {'Updates': {}}
|
||||
|
||||
|
@ -802,7 +805,8 @@ class WindowsUpdateAgent(object):
|
|||
|
||||
installer = self._session.CreateUpdateInstaller()
|
||||
self._session.ClientApplicationID = 'Salt: Install Update'
|
||||
uninstall_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
with salt.utils.winapi.Com():
|
||||
uninstall_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')
|
||||
|
||||
ret = {'Updates': {}}
|
||||
|
||||
|
@ -999,8 +1003,7 @@ def needs_reboot():
|
|||
|
||||
'''
|
||||
# Initialize the PyCom system
|
||||
pythoncom.CoInitialize()
|
||||
|
||||
# Create an AutoUpdate object
|
||||
obj_sys = win32com.client.Dispatch('Microsoft.Update.SystemInfo')
|
||||
with salt.utils.winapi.Com():
|
||||
# Create an AutoUpdate object
|
||||
obj_sys = win32com.client.Dispatch('Microsoft.Update.SystemInfo')
|
||||
return salt.utils.data.is_true(obj_sys.RebootRequired)
|
||||
|
|
|
@ -120,7 +120,10 @@ class DiskUsageBeaconTestCase(TestCase, LoaderModuleMockMixin):
|
|||
ret = diskusage.beacon(config)
|
||||
self.assertEqual(ret, [{'diskusage': 50, 'mount': '/'}])
|
||||
|
||||
def test_diskusage_windows(self):
|
||||
def test_diskusage_windows_single_slash(self):
|
||||
r'''
|
||||
This tests new behavior (C:\)
|
||||
'''
|
||||
disk_usage_mock = Mock(return_value=WINDOWS_STUB_DISK_USAGE)
|
||||
with patch('salt.utils.platform.is_windows',
|
||||
MagicMock(return_value=True)):
|
||||
|
@ -136,6 +139,44 @@ class DiskUsageBeaconTestCase(TestCase, LoaderModuleMockMixin):
|
|||
ret = diskusage.beacon(config)
|
||||
self.assertEqual(ret, [{'diskusage': 50, 'mount': 'C:\\'}])
|
||||
|
||||
def test_diskusage_windows_double_slash(self):
|
||||
'''
|
||||
This tests original behavior (C:\\)
|
||||
'''
|
||||
disk_usage_mock = Mock(return_value=WINDOWS_STUB_DISK_USAGE)
|
||||
with patch('salt.utils.platform.is_windows',
|
||||
MagicMock(return_value=True)):
|
||||
with patch('psutil.disk_partitions',
|
||||
MagicMock(return_value=WINDOWS_STUB_DISK_PARTITION)), \
|
||||
patch('psutil.disk_usage', disk_usage_mock):
|
||||
config = [{'C:\\\\': '50%'}]
|
||||
|
||||
ret = diskusage.validate(config)
|
||||
|
||||
self.assertEqual(ret, (True, 'Valid beacon configuration'))
|
||||
|
||||
ret = diskusage.beacon(config)
|
||||
self.assertEqual(ret, [{'diskusage': 50, 'mount': 'C:\\'}])
|
||||
|
||||
def test_diskusage_windows_lowercase(self):
|
||||
r'''
|
||||
This tests lowercase drive letter (c:\)
|
||||
'''
|
||||
disk_usage_mock = Mock(return_value=WINDOWS_STUB_DISK_USAGE)
|
||||
with patch('salt.utils.platform.is_windows',
|
||||
MagicMock(return_value=True)):
|
||||
with patch('psutil.disk_partitions',
|
||||
MagicMock(return_value=WINDOWS_STUB_DISK_PARTITION)), \
|
||||
patch('psutil.disk_usage', disk_usage_mock):
|
||||
config = [{'c:\\': '50%'}]
|
||||
|
||||
ret = diskusage.validate(config)
|
||||
|
||||
self.assertEqual(ret, (True, 'Valid beacon configuration'))
|
||||
|
||||
ret = diskusage.beacon(config)
|
||||
self.assertEqual(ret, [{'diskusage': 50, 'mount': 'C:\\'}])
|
||||
|
||||
def test_diskusage_windows_match_regex(self):
|
||||
disk_usage_mock = Mock(return_value=WINDOWS_STUB_DISK_USAGE)
|
||||
with patch('salt.utils.platform.is_windows',
|
||||
|
|
|
@ -38,6 +38,11 @@ class WinSystemTestCase(TestCase, LoaderModuleMockMixin):
|
|||
now.day, now.hour, now.minute,
|
||||
now.second, now.microsecond])
|
||||
modules_globals['win32api'] = win32api
|
||||
win32net = types.ModuleType(str('win32net')) # future lint: disable=blacklisted-function
|
||||
win32net.NetServerGetInfo = MagicMock()
|
||||
win32net.NetServerSetInfo = MagicMock()
|
||||
modules_globals['win32net'] = win32net
|
||||
|
||||
return {win_system: modules_globals}
|
||||
|
||||
def test_halt(self):
|
||||
|
@ -177,14 +182,15 @@ class WinSystemTestCase(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
Test to set the Windows computer description
|
||||
'''
|
||||
mock = MagicMock(return_value=True)
|
||||
with patch.dict(win_system.__salt__, {'cmd.run': mock}):
|
||||
mock = MagicMock(return_value="Salt's comp")
|
||||
with patch.object(win_system, 'get_computer_desc', mock):
|
||||
self.assertDictEqual(win_system.set_computer_desc(
|
||||
"Salt's comp"
|
||||
),
|
||||
{'Computer Description': "Salt's comp"})
|
||||
mock = MagicMock()
|
||||
mock_get_info = MagicMock(return_value={'comment': ''})
|
||||
mock_get_desc = MagicMock(return_value="Salt's comp")
|
||||
with patch('salt.modules.win_system.win32net.NetServerGetInfo', mock_get_info), \
|
||||
patch('salt.modules.win_system.win32net.NetServerSetInfo', mock), \
|
||||
patch.object(win_system, 'get_computer_desc', mock_get_desc):
|
||||
self.assertDictEqual(
|
||||
win_system.set_computer_desc("Salt's comp"),
|
||||
{'Computer Description': "Salt's comp"})
|
||||
|
||||
@skipIf(not win_system.HAS_WIN32NET_MODS, 'Missing win32 libraries')
|
||||
def test_get_computer_desc(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue