D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
proc
/
self
/
root
/
opt
/
saltstack
/
salt
/
lib
/
python3.10
/
site-packages
/
salt
/
states
/
Filename :
chocolatey.py
back
Copy
""" Manage Windows Packages using Chocolatey .. versionadded:: 2016.3.0 .. note:: Chocolatey pulls data from the Chocolatey internet database to determine current versions, find available versions, etc. This is normally a slow operation and may be optimized by specifying a local, smaller chocolatey repo. """ import salt.utils.data import salt.utils.versions from salt.exceptions import SaltInvocationError def __virtual__(): """ Load only if chocolatey is loaded """ if "chocolatey.install" in __salt__: return "chocolatey" return False, "chocolatey module could not be loaded" def installed( name, version=None, source=None, force=False, pre_versions=False, install_args=None, override_args=False, force_x86=False, package_args=None, allow_multiple=False, execution_timeout=None, ): """ Installs a package if not already installed Args: name (str): The name of the package to be installed. Required. version (str): Install a specific version of the package. Defaults to the latest version. If the version is different to the one installed, then the specified version will be installed. Default is ``None``. source (str): Chocolatey repository (directory, share or remote URL, feed). ``None`` defaults to the official Chocolatey feed. Default is ``None``. force (bool): Reinstall the current version of an existing package. Do not use with ``allow_multiple``. Default is ``False``. pre_versions (bool): Include pre-release packages. Default is ``False``. install_args (str): Install arguments you want to pass to the installation process, i.e. product key or feature list. Default is ``None``. override_args (bool): Set to ``True`` to override the original install arguments (for the native installer) in the package and use your own. When this is set to ``False``, install_args will be appended to the end of the default arguments. Default is ``False``. force_x86 (bool): Force x86 (32bit) installation on 64bit systems. Default is ``False``. package_args (str): Arguments you want to pass to the package. Default is ``None``. allow_multiple (bool): Allow multiple versions of the package to be installed. Do not use with ``force``. Does not work with all packages. Default is ``False``. .. versionadded:: 2017.7.0 execution_timeout (str): Chocolatey execution timeout value you want to pass to the installation process. Default is ``None``. Example: .. code-block:: yaml install_some_package: chocolatey.installed: - name: packagename - version: '12.04' - source: 'mychocolatey/source' - force: True """ if force and allow_multiple: raise SaltInvocationError( "Cannot use 'force' in conjunction with 'allow_multiple'" ) ret = {"name": name, "result": True, "changes": {}, "comment": ""} # Get list of currently installed packages pre_install = __salt__["chocolatey.list"](local_only=True) # Determine action # Package not installed if name.lower() not in [package.lower() for package in pre_install.keys()]: if version: ret["comment"] = f"{name} {version} will be installed" else: ret["comment"] = f"Latest version of {name} will be installed" # Package installed else: version_info = __salt__["chocolatey.version"]( name=name, check_remote=True, source=source ) full_name = name for pkg in version_info: if name.lower() == pkg.lower(): full_name = pkg installed_version = version_info[full_name].get("installed")[0] if version: if salt.utils.versions.compare( ver1=installed_version, oper="==", ver2=version ): if force: ret["comment"] = f"{name} {version} will be reinstalled" else: ret["comment"] = f"{name} {version} is already installed" else: if allow_multiple: ret[ "comment" ] = f"{name} {version} will be installed side by side with {name} {installed_version} if supported" else: ret[ "comment" ] = f"{name} {version} will be installed over {name} {installed_version}" force = True else: version = installed_version if force: ret["comment"] = f"{name} {version} will be reinstalled" else: ret["comment"] = f"{name} {version} is already installed" return ret if __opts__["test"]: ret["result"] = None return ret # Install the package result = __salt__["chocolatey.install"]( name=name, version=version, source=source, force=force, pre_versions=pre_versions, install_args=install_args, override_args=override_args, force_x86=force_x86, package_args=package_args, allow_multiple=allow_multiple, execution_timeout=execution_timeout, ) if "Running chocolatey failed" not in result: ret["comment"] = f"{name} installed successfully" ret["result"] = True else: ret["comment"] = f"Failed to install {name}" ret["result"] = False # Get list of installed packages after 'chocolatey.install' post_install = __salt__["chocolatey.list"](local_only=True) ret["changes"] = salt.utils.data.compare_dicts(pre_install, post_install) return ret def uninstalled(name, version=None, uninstall_args=None, override_args=False): """ Uninstalls a chocolatey package Args: name (str): The name of the package to be uninstalled. Required. version (str): Uninstalls a specific version of the package. Defaults to the latest version installed. uninstall_args (str): A list of uninstall arguments you want to pass to the uninstallation process, i.e. product key or feature list override_args (str): Set to ``True`` if you want to override the original uninstall arguments (for the native uninstaller) in the package and use your own. When this is set to ``False``, uninstall_args will be appended to the end of the default arguments Example: .. code-block:: yaml remove_my_package: chocolatey.uninstalled: - name: mypackage - version: '21.5' """ ret = {"name": name, "result": True, "changes": {}, "comment": ""} # Get list of currently installed packages pre_uninstall = __salt__["chocolatey.list"](local_only=True) # Determine if package is installed if name.lower() in [package.lower() for package in pre_uninstall.keys()]: try: ret["comment"] = f"{name} {pre_uninstall[name][0]} will be removed" except KeyError: ret["comment"] = f"{name} will be removed" else: ret["comment"] = f"The package {name} is not installed" return ret if __opts__["test"]: ret["result"] = None return ret # Uninstall the package result = __salt__["chocolatey.uninstall"]( name, version, uninstall_args, override_args ) if "Running chocolatey failed" not in result: ret["comment"] = f"{name} uninstalled successfully" ret["result"] = True else: ret["comment"] = f"Failed to uninstall {name}" ret["result"] = False # Get list of installed packages after 'chocolatey.uninstall' post_uninstall = __salt__["chocolatey.list"](local_only=True) ret["changes"] = salt.utils.data.compare_dicts(pre_uninstall, post_uninstall) return ret def upgraded( name, version=None, source=None, force=False, pre_versions=False, install_args=None, override_args=False, force_x86=False, package_args=None, ): """ Upgrades a chocolatey package. Will install the package if not installed. .. versionadded:: 2018.3.0 Args: name (str): The name of the package to be installed. Required. version (str): Install a specific version of the package. Defaults to latest version. If the version is greater than the one installed then the specified version will be installed. Default is ``None``. source (str): Chocolatey repository (directory, share or remote URL, feed). Defaults to the official Chocolatey feed. Default is ``None``. force (bool): ``True`` will reinstall an existing package with the same version. Default is ``False``. pre_versions (bool): ``True`` will include pre-release packages. Default is ``False``. install_args (str): Install arguments you want to pass to the installation process, i.e product key or feature list. Default is ``None``. override_args (bool): ``True`` will override the original install arguments (for the native installer) in the package and use those specified in ``install_args``. ``False`` will append install_args to the end of the default arguments. Default is ``False``. force_x86 (bool): ``True`` forces 32bit installation on 64bit systems. Default is ``False``. package_args (str): Arguments you want to pass to the package. Default is ``None``. Example: .. code-block:: yaml upgrade_some_package: chocolatey.upgraded: - name: packagename - version: '12.04' - source: 'mychocolatey/source' """ ret = {"name": name, "result": True, "changes": {}, "comment": ""} # Get list of currently installed packages pre_install = __salt__["chocolatey.list"](local_only=True) # Determine if there are changes # Package not installed if name.lower() not in [package.lower() for package in pre_install.keys()]: if version: ret["comment"] = f"{name} {version} will be installed" else: ret["comment"] = f"Latest version of {name} will be installed" # Package installed else: version_info = __salt__["chocolatey.version"]( name=name, check_remote=True, source=source ) # Get the actual full name out of version_info full_name = name for pkg in version_info: if name.lower() == pkg.lower(): full_name = pkg installed_version = version_info[full_name]["installed"][0] # If version is not passed, use available... if available is available if not version: if "available" in version_info[full_name]: version = version_info[full_name]["available"][0] if version: # If installed version and new version are the same if salt.utils.versions.compare( ver1=installed_version, oper="==", ver2=version ): if force: ret["comment"] = f"{name} {version} will be reinstalled" else: ret["comment"] = f"{name} {version} is already installed" return ret else: # If installed version is older than new version if salt.utils.versions.compare( ver1=installed_version, oper="<", ver2=version ): ret[ "comment" ] = f"{name} {installed_version} will be upgraded to version {version}" # If installed version is newer than new version else: ret[ "comment" ] = f"{name} {installed_version} (newer) is already installed" return ret # Catch all for a condition where version is not passed and there is no # available version else: ret["comment"] = "No version found to install" return ret # Return if running in test mode if __opts__["test"]: ret["result"] = None return ret # Install the package result = __salt__["chocolatey.upgrade"]( name=name, version=version, source=source, force=force, pre_versions=pre_versions, install_args=install_args, override_args=override_args, force_x86=force_x86, package_args=package_args, ) if "Running chocolatey failed" not in result: ret["comment"] = f"{name} upgraded successfully" ret["result"] = True else: ret["comment"] = f"Failed to upgrade {name}" ret["result"] = False # Get list of installed packages after 'chocolatey.install' post_install = __salt__["chocolatey.list"](local_only=True) # Prior to this, ret['changes'] would have contained expected changes, # replace them with the actual changes now that we have completed the # installation. ret["changes"] = salt.utils.data.compare_dicts(pre_install, post_install) return ret def source_present( name, source_location, username=None, password=None, force=False, priority=None ): """ Adds a Chocolatey source if not already present. Args: name (str): The name of the source to be added as a chocolatey repository. source (str): Location of the source you want to work with. username (str): The username for a chocolatey source that needs authentication credentials. password (str): The password for a chocolatey source that needx authentication credentials. force (bool): Salt will not modify an existing repository with the same name. Set this option to ``True`` to update an existing repository. priority (int): The priority order of this source as compared to other sources. Lower is better. Defaults to 0 (no priority). All priorities above 0 will be evaluated first, then zero-based values will be evaluated in config file order. Example: .. code-block:: yaml add_some_source: chocolatey.source_present: - name: reponame - source: https://repo.exemple.com - username: myuser - password: mypassword - priority: 100 """ ret = {"name": name, "result": True, "changes": {}, "comment": ""} # Get list of currently present sources pre_install = __salt__["chocolatey.list_sources"]() # Determine action # Source with same name not present if name.lower() not in [present.lower() for present in pre_install.keys()]: ret["comment"] = f"{name} will be added" # Source with same name already present else: if force: ret["comment"] = f"{name} will be updated" else: ret["comment"] = f"{name} is already present" return ret if __opts__["test"]: ret["result"] = None return ret # Add the source result = __salt__["chocolatey.add_source"]( name=name, source_location=source_location, username=username, password=password, priority=priority, ) if "Running chocolatey failed" not in result: ret["result"] = True ret["comment"] = f"Source {name} added successfully" else: ret["result"] = False ret["comment"] = f"Failed to add the source {name}" # Get list of present sources after 'chocolatey.add_source' post_install = __salt__["chocolatey.list_sources"]() ret["changes"] = salt.utils.data.compare_dicts(pre_install, post_install) return ret