Edit file File name : chocolatey.py Content :""" Manage Chocolatey package installs .. 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 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). 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 if you want 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 64 bit systems. Default is False. package_args (str): Arguments you want to pass to the package. Default is None. allow_multiple (bool): Allow mulitiple 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. .. code-block:: yaml Installsomepackage: 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["changes"] = {name: "Version {} will be installed".format(version)} else: ret["changes"] = {name: "Latest version 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]["installed"][0] if version: if salt.utils.versions.compare( ver1=installed_version, oper="==", ver2=version ): if force: ret["changes"] = { name: "Version {} will be reinstalled".format(version) } ret["comment"] = "Reinstall {} {}".format(full_name, version) else: ret["comment"] = "{} {} is already installed".format(name, version) if __opts__["test"]: ret["result"] = None return ret else: if allow_multiple: ret["changes"] = { name: ( "Version {} will be installed side by side with " "Version {} if supported".format(version, installed_version) ) } ret["comment"] = "Install {0} {1} side-by-side with {0} {2}".format( full_name, version, installed_version ) else: ret["changes"] = { name: "Version {} will be installed over Version {}".format( version, installed_version ) } ret["comment"] = "Install {0} {1} over {0} {2}".format( full_name, version, installed_version ) force = True else: version = installed_version if force: ret["changes"] = { name: "Version {} will be reinstalled".format(version) } ret["comment"] = "Reinstall {} {}".format(full_name, version) else: ret["comment"] = "{} {} is already installed".format(name, version) if __opts__["test"]: ret["result"] = None return ret if __opts__["test"]: ret["result"] = None ret["comment"] = "The installation was tested" 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["result"] = True else: ret["result"] = False if not ret["result"]: ret["comment"] = "Failed to install the package {}".format(name) # 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 package name The name of the package to be uninstalled version Uninstalls a specific version of the package. Defaults to latest version installed. uninstall_args A list of uninstall arguments you want to pass to the uninstallation process i.e product key or feature list override_args 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 .. code-block:: yaml Removemypackage: 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["changes"] = { name: "{} version {} will be removed".format( name, pre_uninstall[name][0] ) } except KeyError: ret["changes"] = {name: "{} will be removed".format(name)} else: ret["comment"] = "The package {} is not installed".format(name) return ret if __opts__["test"]: ret["result"] = None ret["comment"] = "The uninstall was tested" return ret # Uninstall the package result = __salt__["chocolatey.uninstall"]( name, version, uninstall_args, override_args ) if "Running chocolatey failed" not in result: ret["result"] = True else: ret["result"] = False if not ret["result"]: ret["comment"] = "Failed to uninstall the package {}".format(name) # 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 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 nclude 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 64 bit systems. Default is ``False``. package_args (str): Arguments you want to pass to the package. Default is ``None``. .. 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["changes"][name] = "Version {} will be installed".format(version) ret["comment"] = "Install version {}".format(version) else: ret["changes"][name] = "Latest version will be installed" ret["comment"] = "Install latest version" # Package installed else: version_info = __salt__["chocolatey.version"](name, check_remote=True) # 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["changes"][name] = "Version {} will be reinstalled".format( version ) ret["comment"] = "Reinstall {} {}".format(full_name, version) else: ret["comment"] = "{} {} is already installed".format( name, installed_version ) else: # If installed version is older than new version if salt.utils.versions.compare( ver1=installed_version, oper="<", ver2=version ): ret["changes"][ name ] = "Version {} will be upgraded to Version {}".format( installed_version, version ) ret["comment"] = "Upgrade {} {} to {}".format( full_name, installed_version, version ) # If installed version is newer than new version else: ret["comment"] = "{} {} (newer) is already installed".format( name, installed_version ) # 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 if there are no changes to be made if not ret["changes"]: 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"] = "Package {} upgraded successfully".format(name) ret["result"] = True else: ret["comment"] = "Failed to upgrade the package {}".format(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): """ Instructs Chocolatey to add a source if not already present. name The name of the source to be added as a chocolatey repository. source Location of the source you want to work with. username Provide username for chocolatey sources that need authentication credentials. password Provide password for chocolatey sources that need authentication credentials. force Salt will not modify a existing repository with the same name. Set this option to true to update an existing repository. CLI Example: .. code-block:: yaml add_some_source: chocolatey.source_present: - name: reponame - source: https://repo.exemple.com - username: myuser - password: mypassword """ 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"] = "Add the source {}".format(name) # Source with same name already present else: if force: ret["comment"] = "Update the source {}".format(name) else: ret["comment"] = "A source with the name {} is already present".format(name) if __opts__["test"]: ret["result"] = None return ret if __opts__["test"]: ret["result"] = None ret["comment"] = "The installation was tested" return ret # Add the source result = __salt__["chocolatey.add_source"]( name=name, source_location=source_location, username=username, password=password ) if "Running chocolatey failed" not in result: ret["result"] = True ret["comment"] = "Source {} added successfully".format(name) else: ret["result"] = False ret["comment"] = "Failed to add the source {}".format(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 Save