Mini Shell
"""
Installation of Cygwin packages.
A state module to manage cygwin packages. Packages can be installed
or removed.
.. code-block:: yaml
dos2unix:
cyg.installed
"""
import logging
log = logging.getLogger(__name__)
def __virtual__():
"""
Only load if cyg module is available in __salt__.
"""
if "cyg.list" in __salt__:
return True
return (False, "cyg module could not be loaded")
def installed(name, cyg_arch="x86_64", mirrors=None):
"""
Make sure that a package is installed.
name
The name of the package to install
cyg_arch : x86_64
The cygwin architecture to install the package into.
Current options are x86 and x86_64
mirrors : None
List of mirrors to check.
None will use a default mirror (kernel.org)
CLI Example:
.. code-block:: yaml
rsync:
cyg.installed:
- mirrors:
- http://mirror/without/public/key: ""
- http://mirror/with/public/key: http://url/of/public/key
"""
ret = {"name": name, "result": None, "comment": "", "changes": {}}
if cyg_arch not in ["x86", "x86_64"]:
ret["result"] = False
ret["comment"] = "The 'cyg_arch' argument must be one of 'x86' or 'x86_64'"
return ret
log.debug("Installed State: Initial Mirror list: %s", mirrors)
if not __salt__["cyg.check_valid_package"](
name, cyg_arch=cyg_arch, mirrors=mirrors
):
ret["result"] = False
ret["comment"] = "Invalid package name."
return ret
pkgs = __salt__["cyg.list"](name, cyg_arch)
if name in pkgs:
ret["result"] = True
ret["comment"] = "Package is already installed."
return ret
if __opts__["test"]:
ret["comment"] = f"The package {name} would have been installed"
return ret
if __salt__["cyg.install"](name, cyg_arch=cyg_arch, mirrors=mirrors):
ret["result"] = True
ret["changes"][name] = "Installed"
ret["comment"] = "Package was successfully installed"
else:
ret["result"] = False
ret["comment"] = "Could not install package."
return ret
def removed(name, cyg_arch="x86_64", mirrors=None):
"""
Make sure that a package is not installed.
name
The name of the package to uninstall
cyg_arch : x86_64
The cygwin architecture to remove the package from.
Current options are x86 and x86_64
mirrors : None
List of mirrors to check.
None will use a default mirror (kernel.org)
CLI Example:
.. code-block:: yaml
rsync:
cyg.removed:
- mirrors:
- http://mirror/without/public/key: ""
- http://mirror/with/public/key: http://url/of/public/key
"""
ret = {"name": name, "result": None, "comment": "", "changes": {}}
if cyg_arch not in ["x86", "x86_64"]:
ret["result"] = False
ret["comment"] = "The 'cyg_arch' argument must be one of 'x86' or 'x86_64'"
return ret
if not __salt__["cyg.check_valid_package"](
name, cyg_arch=cyg_arch, mirrors=mirrors
):
ret["result"] = False
ret["comment"] = "Invalid package name."
return ret
if name not in __salt__["cyg.list"](name, cyg_arch):
ret["result"] = True
ret["comment"] = "Package is not installed."
return ret
if __opts__["test"]:
ret["comment"] = f"The package {name} would have been removed"
return ret
if __salt__["cyg.uninstall"](name, cyg_arch):
ret["result"] = True
ret["changes"][name] = "Removed"
ret["comment"] = "Package was successfully removed."
else:
ret["result"] = False
ret["comment"] = "Could not remove package."
return ret
def updated(name=None, cyg_arch="x86_64", mirrors=None):
"""
Make sure all packages are up to date.
name : None
No affect, salt fails poorly without the arg available
cyg_arch : x86_64
The cygwin architecture to update.
Current options are x86 and x86_64
mirrors : None
List of mirrors to check.
None will use a default mirror (kernel.org)
CLI Example:
.. code-block:: yaml
rsync:
cyg.updated:
- mirrors:
- http://mirror/without/public/key: ""
- http://mirror/with/public/key: http://url/of/public/key
"""
ret = {"name": "cyg.updated", "result": None, "comment": "", "changes": {}}
if cyg_arch not in ["x86", "x86_64"]:
ret["result"] = False
ret["comment"] = "The 'cyg_arch' argument must be one of 'x86' or 'x86_64'"
return ret
if __opts__["test"]:
ret["comment"] = "All packages would have been updated"
return ret
if not mirrors:
log.warning("No mirror given, using the default.")
before = __salt__["cyg.list"](cyg_arch=cyg_arch)
if __salt__["cyg.update"](cyg_arch, mirrors=mirrors):
after = __salt__["cyg.list"](cyg_arch=cyg_arch)
differ = DictDiffer(after, before)
ret["result"] = True
if differ.same():
ret["comment"] = "Nothing to update."
else:
ret["changes"]["added"] = list(differ.added())
ret["changes"]["removed"] = list(differ.removed())
ret["changes"]["changed"] = list(differ.changed())
ret["comment"] = "All packages successfully updated."
else:
ret["result"] = False
ret["comment"] = "Could not update packages."
return ret
# https://github.com/hughdbrown/dictdiffer
# DictDiffer is licensed as MIT code
# A dictionary difference calculator
# Originally posted as:
# http://stackoverflow.com/a/1165552
class DictDiffer:
"""
Calculate the difference between two dictionaries.
(1) items added
(2) items removed
(3) keys same in both but changed values
(4) keys same in both and unchanged values
"""
def __init__(self, current_dict, past_dict):
"""
Iitialize the differ.
"""
self.current_dict, self.past_dict = current_dict, past_dict
self.current_keys, self.past_keys = (
set(d.keys()) for d in (current_dict, past_dict)
)
self.intersect = self.current_keys.intersection(self.past_keys)
def same(self):
"""
True if the two dicts are the same.
"""
return self.current_dict == self.past_dict
def added(self):
"""
Return a set of additions to past_dict.
"""
return self.current_keys - self.intersect
def removed(self):
"""
Return a set of things removed from past_dict.
"""
return self.past_keys - self.intersect
def changed(self):
"""
Return a set of the keys with changed values.
"""
return {o for o in self.intersect if self.past_dict[o] != self.current_dict[o]}
def unchanged(self):
"""
Return a set of the keys with unchanged values.
"""
return {o for o in self.intersect if self.past_dict[o] == self.current_dict[o]}
Zerion Mini Shell 1.0