mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add Win WUSA management, to install Windows Update files (.msu).
Fixes #46292
This commit is contained in:
parent
12e0d80271
commit
16525e4312
2 changed files with 167 additions and 0 deletions
52
salt/modules/win_wusa.py
Normal file
52
salt/modules/win_wusa.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Microsoft Update files management via wusa.exe
|
||||
|
||||
:maintainer: Thomas Lemarchand
|
||||
:platform: Windows
|
||||
:depends: PowerShell
|
||||
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.platform
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Define the module's virtual name
|
||||
__virtualname__ = 'win_wusa'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Load only on Windows
|
||||
'''
|
||||
if not salt.utils.platform.is_windows():
|
||||
return False, 'Only available on Windows systems'
|
||||
|
||||
powershell_info = __salt__['cmd.shell_info']('powershell', True)
|
||||
if not powershell_info['installed']:
|
||||
return False, 'PowerShell not available'
|
||||
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def is_installed(kb):
|
||||
|
||||
get_hotfix_result = __salt__['cmd.powershell_all']('Get-HotFix -Id {0}'.format(kb), ignore_retcode=True)
|
||||
|
||||
return get_hotfix_result['retcode'] == 0
|
||||
|
||||
|
||||
def install(path):
|
||||
|
||||
return __salt__['cmd.run_all']('wusa.exe {0} /quiet /norestart'.format(path), ignore_retcode=True)
|
||||
|
||||
|
||||
def uninstall(kb):
|
||||
|
||||
return __salt__['cmd.run_all']('wusa.exe /uninstall /kb:{0} /quiet /norestart'.format(kb[2:]), ignore_retcode=True)
|
115
salt/states/win_wusa.py
Normal file
115
salt/states/win_wusa.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Microsoft Updates (KB) Management
|
||||
|
||||
This module provides the ability to enforce KB installations
|
||||
from files (.msu), without WSUS.
|
||||
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.platform
|
||||
import salt.exceptions
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Define the module's virtual name
|
||||
__virtualname__ = 'win_wusa'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Load only on Windows
|
||||
'''
|
||||
if not salt.utils.platform.is_windows():
|
||||
return False, 'Only available on Windows systems'
|
||||
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def installed(name, source):
|
||||
'''
|
||||
Enforce the installed state of a KB
|
||||
|
||||
name
|
||||
Name of the Windows KB ("KB123456")
|
||||
source
|
||||
Source of .msu file corresponding to the KB
|
||||
|
||||
'''
|
||||
ret = {
|
||||
'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': '',
|
||||
'pchanges': {},
|
||||
}
|
||||
|
||||
# Start with basic error-checking. Do all the passed parameters make sense
|
||||
# and agree with each-other?
|
||||
if not name or not source:
|
||||
raise salt.exceptions.SaltInvocationError(
|
||||
'Arguments "name" and "source" are mandatory.')
|
||||
|
||||
# Check the current state of the system. Does anything need to change?
|
||||
current_state = __salt__['win_wusa.is_installed'](name)
|
||||
|
||||
if current_state:
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'KB already installed'
|
||||
return ret
|
||||
|
||||
# The state of the system does need to be changed. Check if we're running
|
||||
# in ``test=true`` mode.
|
||||
if __opts__['test'] is True:
|
||||
ret['comment'] = 'The KB "{0}" will be installed.'.format(name)
|
||||
ret['pchanges'] = {
|
||||
'old': current_state,
|
||||
'new': True,
|
||||
}
|
||||
|
||||
# Return ``None`` when running with ``test=true``.
|
||||
ret['result'] = None
|
||||
|
||||
return ret
|
||||
|
||||
try:
|
||||
result = __states__['file.cached'](source,
|
||||
skip_verify=True,
|
||||
saltenv=__env__)
|
||||
except Exception as exc:
|
||||
msg = 'Failed to cache {0}: {1}'.format(
|
||||
salt.utils.url.redact_http_basic_auth(source),
|
||||
exc.__str__())
|
||||
log.exception(msg)
|
||||
ret['comment'] = msg
|
||||
return ret
|
||||
|
||||
if result['result']:
|
||||
# Get the path of the file in the minion cache
|
||||
cached = __salt__['cp.is_cached'](source, saltenv=__env__)
|
||||
else:
|
||||
log.debug(
|
||||
'failed to download %s',
|
||||
salt.utils.url.redact_http_basic_auth(source)
|
||||
)
|
||||
return result
|
||||
|
||||
# Finally, make the actual change and return the result.
|
||||
new_state = __salt__['win_wusa.install'](cached)
|
||||
|
||||
ret['comment'] = 'The KB "{0}" was installed!'.format(name)
|
||||
|
||||
ret['changes'] = {
|
||||
'old': current_state,
|
||||
'new': new_state,
|
||||
}
|
||||
|
||||
ret['result'] = True
|
||||
|
||||
return ret
|
Loading…
Add table
Reference in a new issue