From 1d6bc094cf460a374d0e7da75954ea91bd41caa0 Mon Sep 17 00:00:00 2001 From: Dmitry Ulyanov Date: Wed, 21 Mar 2018 19:55:36 +0300 Subject: [PATCH] Add http(s)_proxy support in yum module (#36800) * added set_env_proxy function for setting proxy environment Added set_env_proxy function, that set system http(s)_proxy environment for fetching RPM if proxy settings set in yum.conf file that fix Issue - #18979 * fix automatic field numbering specification * changed if statement in setting http_proxy environment * Change set_env_proxy function to function with decorator That decorator set system proxy environment from yum.conf and revert back to system configuration after fetching RPM * Minor fix - rename variable schem to scheme - change 'in' to 'startswith' * change decorator set_env_proxy to decorating through contextmanager - added import contextmanager from contextlib - set_env_proxy now decorating through contextmanager - fix http/https setting environment principle --- lib/ansible/modules/packaging/os/yum.py | 39 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py index ba9dbe525a7..e872f692992 100644 --- a/lib/ansible/modules/packaging/os/yum.py +++ b/lib/ansible/modules/packaging/os/yum.py @@ -266,6 +266,8 @@ try: except ImportError: transaction_helpers = False +from contextlib import contextmanager + from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native from ansible.module_utils.urls import fetch_url @@ -640,6 +642,37 @@ def local_envra(path): header[rpm.RPMTAG_ARCH]) +@contextmanager +def set_env_proxy(conf_file, installroot): + # setting system proxy environment and saving old, if exists + my = yum_base(conf_file, installroot) + namepass = "" + scheme = ["http", "https"] + old_proxy_env = [os.getenv("http_proxy"), os.getenv("https_proxy")] + try: + if my.conf.proxy: + if my.conf.proxy_username: + namepass = namepass + my.conf.proxy_username + if my.conf.proxy_password: + namepass = namepass + ":" + my.conf.proxy_password + namepass = namepass + '@' + for item in scheme: + os.environ[item + "_proxy"] = re.sub(r"(http://)", + r"\1" + namepass, my.conf.proxy) + yield + except yum.Errors.YumBaseError: + raise + finally: + # revert back to previously system configuration + for item in scheme: + if os.getenv("{0}_proxy".format(item)): + del os.environ["{0}_proxy".format(item)] + if old_proxy_env[0]: + os.environ["http_proxy"] = old_proxy_env[0] + if old_proxy_env[1]: + os.environ["https_proxy"] = old_proxy_env[1] + + def pkg_to_dict(pkgstr): if pkgstr.strip(): n, e, v, r, a, repo = pkgstr.split('|') @@ -762,7 +795,8 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, i module.fail_json(**res) if '://' in spec: - package = fetch_rpm_from_url(spec, module=module) + with set_env_proxy(conf_file, installroot): + package = fetch_rpm_from_url(spec, module=module) else: package = spec @@ -1075,7 +1109,8 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos, up # URL elif '://' in spec: # download package so that we can check if it's already installed - package = fetch_rpm_from_url(spec, module=module) + with set_env_proxy(conf_file, installroot): + package = fetch_rpm_from_url(spec, module=module) envra = local_envra(package) if envra is None: