diff options
| author | Hongxu Jia <hongxu.jia@windriver.com> | 2017-07-20 03:44:29 -0400 |
|---|---|---|
| committer | Martin Jansa <Martin.Jansa@gmail.com> | 2017-07-24 18:58:53 +0200 |
| commit | 6e445ba8291d58f20e6a6b61afeabed85bd7b953 (patch) | |
| tree | d996994aed8466e2c5005119b5143f8aefdc4f3c /meta-python/recipes-extended/python-pykickstart | |
| parent | baa7758845df8c6adc445ace7c025f691a243d31 (diff) | |
| download | meta-openembedded-6e445ba8291d58f20e6a6b61afeabed85bd7b953.tar.gz | |
python3-pykickstart: add recipe 2.35
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'meta-python/recipes-extended/python-pykickstart')
5 files changed, 383 insertions, 0 deletions
diff --git a/meta-python/recipes-extended/python-pykickstart/files/0001-support-authentication-for-kickstart.patch b/meta-python/recipes-extended/python-pykickstart/files/0001-support-authentication-for-kickstart.patch new file mode 100644 index 0000000000..617699db07 --- /dev/null +++ b/meta-python/recipes-extended/python-pykickstart/files/0001-support-authentication-for-kickstart.patch | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | From d0d8890b5ef74c315381c9e1cff4b1d32892116b Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 3 | Date: Thu, 1 Jun 2017 15:07:36 +0800 | ||
| 4 | Subject: [PATCH 1/4] support authentication for kickstart | ||
| 5 | |||
| 6 | While download kickstart file from web server, | ||
| 7 | we support basic/digest authentication. | ||
| 8 | |||
| 9 | Add KickstartAuthError to report authentication failure, | ||
| 10 | which the invoker could parse this specific error. | ||
| 11 | |||
| 12 | Upstream-Status: inappropriate [oe specific] | ||
| 13 | |||
| 14 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 15 | --- | ||
| 16 | pykickstart/errors.py | 19 +++++++++++++++++++ | ||
| 17 | pykickstart/load.py | 32 +++++++++++++++++++++++++++----- | ||
| 18 | pykickstart/parser.py | 4 ++-- | ||
| 19 | 3 files changed, 48 insertions(+), 7 deletions(-) | ||
| 20 | |||
| 21 | diff --git a/pykickstart/errors.py b/pykickstart/errors.py | ||
| 22 | index b76e84c..fd81bc8 100644 | ||
| 23 | --- a/pykickstart/errors.py | ||
| 24 | +++ b/pykickstart/errors.py | ||
| 25 | @@ -35,6 +35,10 @@ It also exports several exception classes: | ||
| 26 | |||
| 27 | KickstartVersionError - An exception for errors relating to unsupported | ||
| 28 | syntax versions. | ||
| 29 | + | ||
| 30 | + KickstartAuthError - An exception for errors relating to authentication | ||
| 31 | + failed while downloading kickstart from web server | ||
| 32 | + | ||
| 33 | """ | ||
| 34 | import warnings | ||
| 35 | |||
| 36 | @@ -103,3 +107,18 @@ class KickstartVersionError(KickstartError): | ||
| 37 | |||
| 38 | def __str__ (self): | ||
| 39 | return self.value | ||
| 40 | + | ||
| 41 | +class KickstartAuthError(KickstartError): | ||
| 42 | + """An exception for errors relating to authentication failed while | ||
| 43 | + downloading kickstart from web server | ||
| 44 | + """ | ||
| 45 | + def __init__(self, msg): | ||
| 46 | + """Create a new KickstartAuthError exception instance with the | ||
| 47 | + descriptive message val. val should be the return value of | ||
| 48 | + formatErrorMsg. | ||
| 49 | + """ | ||
| 50 | + KickstartError.__init__(self, msg) | ||
| 51 | + | ||
| 52 | + def __str__(self): | ||
| 53 | + return self.value | ||
| 54 | + | ||
| 55 | diff --git a/pykickstart/load.py b/pykickstart/load.py | ||
| 56 | index 1f69b9c..0f5741b 100644 | ||
| 57 | --- a/pykickstart/load.py | ||
| 58 | +++ b/pykickstart/load.py | ||
| 59 | @@ -18,10 +18,13 @@ | ||
| 60 | # with the express permission of Red Hat, Inc. | ||
| 61 | # | ||
| 62 | import requests | ||
| 63 | +from requests.auth import HTTPDigestAuth | ||
| 64 | +from requests.auth import HTTPBasicAuth | ||
| 65 | + | ||
| 66 | import shutil | ||
| 67 | import six | ||
| 68 | |||
| 69 | -from pykickstart.errors import KickstartError | ||
| 70 | +from pykickstart.errors import KickstartError, KickstartAuthError | ||
| 71 | from pykickstart.i18n import _ | ||
| 72 | from requests.exceptions import SSLError, RequestException | ||
| 73 | |||
| 74 | @@ -29,7 +32,7 @@ _is_url = lambda location: '://' in location # RFC 3986 | ||
| 75 | |||
| 76 | SSL_VERIFY = True | ||
| 77 | |||
| 78 | -def load_to_str(location): | ||
| 79 | +def load_to_str(location, user=None, passwd=None): | ||
| 80 | '''Load a destination URL or file into a string. | ||
| 81 | Type of input is inferred automatically. | ||
| 82 | |||
| 83 | @@ -40,7 +43,7 @@ def load_to_str(location): | ||
| 84 | Raises: KickstartError on error reading''' | ||
| 85 | |||
| 86 | if _is_url(location): | ||
| 87 | - return _load_url(location) | ||
| 88 | + return _load_url(location, user=user, passwd=passwd) | ||
| 89 | else: | ||
| 90 | return _load_file(location) | ||
| 91 | |||
| 92 | @@ -71,13 +74,32 @@ def load_to_file(location, destination): | ||
| 93 | _copy_file(location, destination) | ||
| 94 | return destination | ||
| 95 | |||
| 96 | +def _get_auth(location, user=None, passwd=None): | ||
| 97 | + | ||
| 98 | + auth = None | ||
| 99 | + request = requests.get(location, verify=SSL_VERIFY) | ||
| 100 | + if request.status_code == requests.codes.unauthorized: | ||
| 101 | + if user is None or passwd is None: | ||
| 102 | + log.info("Require Authentication") | ||
| 103 | + raise KickstartAuthError("Require Authentication.\nAppend 'ksuser=<username> kspasswd=<password>' to boot command") | ||
| 104 | |||
| 105 | + reasons = request.headers.get("WWW-Authenticate", "").split() | ||
| 106 | + if reasons: | ||
| 107 | + auth_type = reasons[0] | ||
| 108 | + if auth_type == "Basic": | ||
| 109 | + auth = HTTPBasicAuth(user, passwd) | ||
| 110 | + elif auth_type == "Digest": | ||
| 111 | + auth=HTTPDigestAuth(user, passwd) | ||
| 112 | |||
| 113 | -def _load_url(location): | ||
| 114 | + return auth | ||
| 115 | + | ||
| 116 | +def _load_url(location, user=None, passwd=None): | ||
| 117 | '''Load a location (URL or filename) and return contents as string''' | ||
| 118 | |||
| 119 | + auth = _get_auth(location, user=user, passwd=passwd) | ||
| 120 | + | ||
| 121 | try: | ||
| 122 | - request = requests.get(location, verify=SSL_VERIFY) | ||
| 123 | + request = requests.get(location, verify=SSL_VERIFY, auth=auth) | ||
| 124 | except SSLError as e: | ||
| 125 | raise KickstartError(_('Error securely accessing URL "%s"') % location + ': {e}'.format(e=str(e))) | ||
| 126 | except RequestException as e: | ||
| 127 | diff --git a/pykickstart/parser.py b/pykickstart/parser.py | ||
| 128 | index d2b0fbe..26b5de9 100644 | ||
| 129 | --- a/pykickstart/parser.py | ||
| 130 | +++ b/pykickstart/parser.py | ||
| 131 | @@ -773,7 +773,7 @@ class KickstartParser(object): | ||
| 132 | i = PutBackIterator(s.splitlines(True) + [""]) | ||
| 133 | self._stateMachine (i) | ||
| 134 | |||
| 135 | - def readKickstart(self, f, reset=True): | ||
| 136 | + def readKickstart(self, f, reset=True, username=None, password=None): | ||
| 137 | """Process a kickstart file, given by the filename f.""" | ||
| 138 | if reset: | ||
| 139 | self._reset() | ||
| 140 | @@ -794,7 +794,7 @@ class KickstartParser(object): | ||
| 141 | self.currentdir[self._includeDepth] = cd | ||
| 142 | |||
| 143 | try: | ||
| 144 | - s = load_to_str(f) | ||
| 145 | + s = load_to_str(f, user=username, passwd=password) | ||
| 146 | except KickstartError as e: | ||
| 147 | raise KickstartError(formatErrorMsg(0, msg=_("Unable to open input kickstart file: %s") % str(e))) | ||
| 148 | |||
| 149 | -- | ||
| 150 | 2.7.4 | ||
| 151 | |||
diff --git a/meta-python/recipes-extended/python-pykickstart/files/0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch b/meta-python/recipes-extended/python-pykickstart/files/0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch new file mode 100644 index 0000000000..cb21235460 --- /dev/null +++ b/meta-python/recipes-extended/python-pykickstart/files/0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | From e6e747b883114bfad51ad93f823e65f5a4d6438a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 3 | Date: Thu, 1 Jun 2017 15:12:29 +0800 | ||
| 4 | Subject: [PATCH 2/4] pykickstart/parser.py: add lock for readKickstart and | ||
| 5 | support https without certification | ||
| 6 | |||
| 7 | - Add lock for readKickstart to fix race issue | ||
| 8 | |||
| 9 | - Support to download kickstart file through https without certification | ||
| 10 | |||
| 11 | Upstream-Status: Inappropriate[oe specific] | ||
| 12 | |||
| 13 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 14 | --- | ||
| 15 | pykickstart/load.py | 2 +- | ||
| 16 | pykickstart/parser.py | 24 ++++++++++++++++++++++++ | ||
| 17 | 2 files changed, 25 insertions(+), 1 deletion(-) | ||
| 18 | |||
| 19 | diff --git a/pykickstart/load.py b/pykickstart/load.py | ||
| 20 | index 0f5741b..48c8276 100644 | ||
| 21 | --- a/pykickstart/load.py | ||
| 22 | +++ b/pykickstart/load.py | ||
| 23 | @@ -30,7 +30,7 @@ from requests.exceptions import SSLError, RequestException | ||
| 24 | |||
| 25 | _is_url = lambda location: '://' in location # RFC 3986 | ||
| 26 | |||
| 27 | -SSL_VERIFY = True | ||
| 28 | +SSL_VERIFY = False | ||
| 29 | |||
| 30 | def load_to_str(location, user=None, passwd=None): | ||
| 31 | '''Load a destination URL or file into a string. | ||
| 32 | diff --git a/pykickstart/parser.py b/pykickstart/parser.py | ||
| 33 | index 26b5de9..264ba05 100644 | ||
| 34 | --- a/pykickstart/parser.py | ||
| 35 | +++ b/pykickstart/parser.py | ||
| 36 | @@ -57,6 +57,26 @@ STATE_COMMANDS = "commands" | ||
| 37 | |||
| 38 | ver = version.DEVEL | ||
| 39 | |||
| 40 | +import logging | ||
| 41 | +log = logging.getLogger("anaconda") | ||
| 42 | + | ||
| 43 | +import inspect | ||
| 44 | +import threading | ||
| 45 | +_private_ks_lock = threading.RLock() | ||
| 46 | + | ||
| 47 | +class KsLock(object): | ||
| 48 | + def __enter__(self): | ||
| 49 | + log.info("%s %s" % (self.__class__.__name__, inspect.stack()[0][3])) | ||
| 50 | + _private_ks_lock.acquire() | ||
| 51 | + return _private_ks_lock | ||
| 52 | + | ||
| 53 | + def __exit__(self, exc_type, exc_val, exc_tb): | ||
| 54 | + log.info("%s %s" % (self.__class__.__name__, inspect.stack()[0][3])) | ||
| 55 | + _private_ks_lock.release() | ||
| 56 | + | ||
| 57 | + | ||
| 58 | +_ks_lock = KsLock() | ||
| 59 | + | ||
| 60 | def _preprocessStateMachine (lineIter): | ||
| 61 | l = None | ||
| 62 | lineno = 0 | ||
| 63 | @@ -774,6 +794,10 @@ class KickstartParser(object): | ||
| 64 | self._stateMachine (i) | ||
| 65 | |||
| 66 | def readKickstart(self, f, reset=True, username=None, password=None): | ||
| 67 | + with _ks_lock: | ||
| 68 | + self._readKickstart(f, reset=reset, username=username, password=password) | ||
| 69 | + | ||
| 70 | + def _readKickstart(self, f, reset=True, username=None, password=None): | ||
| 71 | """Process a kickstart file, given by the filename f.""" | ||
| 72 | if reset: | ||
| 73 | self._reset() | ||
| 74 | -- | ||
| 75 | 2.7.4 | ||
| 76 | |||
diff --git a/meta-python/recipes-extended/python-pykickstart/files/0003-comment-out-sections-shutdown-and-environment-in-gen.patch b/meta-python/recipes-extended/python-pykickstart/files/0003-comment-out-sections-shutdown-and-environment-in-gen.patch new file mode 100644 index 0000000000..9fb25fb18f --- /dev/null +++ b/meta-python/recipes-extended/python-pykickstart/files/0003-comment-out-sections-shutdown-and-environment-in-gen.patch | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | From be6012a5dd49ae5e8ac035654ab1c6f37f0dc8f4 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 3 | Date: Thu, 1 Jun 2017 15:15:15 +0800 | ||
| 4 | Subject: [PATCH 3/4] comment out sections shutdown and environment in | ||
| 5 | generated kickstart file | ||
| 6 | |||
| 7 | Both of them is disabled by default. | ||
| 8 | |||
| 9 | Upstream-Status: Inappropriate[oe specific] | ||
| 10 | |||
| 11 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 12 | |||
| 13 | fixup! add comments of shutdown for user | ||
| 14 | --- | ||
| 15 | pykickstart/commands/reboot.py | 3 +++ | ||
| 16 | pykickstart/parser.py | 2 +- | ||
| 17 | 2 files changed, 4 insertions(+), 1 deletion(-) | ||
| 18 | |||
| 19 | diff --git a/pykickstart/commands/reboot.py b/pykickstart/commands/reboot.py | ||
| 20 | index 88799ba..2d0cea9 100644 | ||
| 21 | --- a/pykickstart/commands/reboot.py | ||
| 22 | +++ b/pykickstart/commands/reboot.py | ||
| 23 | @@ -41,6 +41,9 @@ class FC3_Reboot(KickstartCommand): | ||
| 24 | elif self.action == KS_SHUTDOWN: | ||
| 25 | retval += "# Shutdown after installation\nshutdown" | ||
| 26 | retval += self._getArgsAsStr() + "\n" | ||
| 27 | + else: | ||
| 28 | + retval += "# Shutdown after installation\n#shutdown" | ||
| 29 | + retval += self._getArgsAsStr() + "\n" | ||
| 30 | |||
| 31 | return retval | ||
| 32 | |||
| 33 | diff --git a/pykickstart/parser.py b/pykickstart/parser.py | ||
| 34 | index 264ba05..b3f33d7 100644 | ||
| 35 | --- a/pykickstart/parser.py | ||
| 36 | +++ b/pykickstart/parser.py | ||
| 37 | @@ -383,7 +383,7 @@ class Packages(KickstartObject): | ||
| 38 | |||
| 39 | if not self.default: | ||
| 40 | if self.environment: | ||
| 41 | - pkgs += "@^%s\n" % self.environment | ||
| 42 | + pkgs += "#@^%s\n" % self.environment | ||
| 43 | |||
| 44 | grps = self.groupList | ||
| 45 | grps.sort() | ||
| 46 | -- | ||
| 47 | 2.7.4 | ||
| 48 | |||
diff --git a/meta-python/recipes-extended/python-pykickstart/files/0004-load.py-retry-to-invoke-request-with-timeout.patch b/meta-python/recipes-extended/python-pykickstart/files/0004-load.py-retry-to-invoke-request-with-timeout.patch new file mode 100644 index 0000000000..70254f6fda --- /dev/null +++ b/meta-python/recipes-extended/python-pykickstart/files/0004-load.py-retry-to-invoke-request-with-timeout.patch | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | From c0e63f0d3c09bdabb0ad2c88b7cc73e7618dd86a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 3 | Date: Thu, 15 Jun 2017 17:35:33 +0800 | ||
| 4 | Subject: [PATCH 4/4] load.py: retry to invoke request with timeout | ||
| 5 | |||
| 6 | While networkless, use request to fetch kickstart file from | ||
| 7 | network, it failed and wait 300s to break, we should retry | ||
| 8 | to invoke request with timeout explicitly. So if it the | ||
| 9 | network is up, the fetch works. | ||
| 10 | |||
| 11 | Upstream-Status: inappropriate [oe specific] | ||
| 12 | |||
| 13 | Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> | ||
| 14 | --- | ||
| 15 | pykickstart/load.py | 30 ++++++++++++++++++++++++++++++ | ||
| 16 | 1 file changed, 30 insertions(+) | ||
| 17 | |||
| 18 | diff --git a/pykickstart/load.py b/pykickstart/load.py | ||
| 19 | index 48c8276..74b266b 100644 | ||
| 20 | --- a/pykickstart/load.py | ||
| 21 | +++ b/pykickstart/load.py | ||
| 22 | @@ -21,6 +21,7 @@ import requests | ||
| 23 | from requests.auth import HTTPDigestAuth | ||
| 24 | from requests.auth import HTTPBasicAuth | ||
| 25 | |||
| 26 | +import time | ||
| 27 | import shutil | ||
| 28 | import six | ||
| 29 | |||
| 30 | @@ -28,6 +29,9 @@ from pykickstart.errors import KickstartError, KickstartAuthError | ||
| 31 | from pykickstart.i18n import _ | ||
| 32 | from requests.exceptions import SSLError, RequestException | ||
| 33 | |||
| 34 | +import logging | ||
| 35 | +log = logging.getLogger("anaconda") | ||
| 36 | + | ||
| 37 | _is_url = lambda location: '://' in location # RFC 3986 | ||
| 38 | |||
| 39 | SSL_VERIFY = False | ||
| 40 | @@ -74,6 +78,29 @@ def load_to_file(location, destination): | ||
| 41 | _copy_file(location, destination) | ||
| 42 | return destination | ||
| 43 | |||
| 44 | +def _access_url(location): | ||
| 45 | + status = False | ||
| 46 | + | ||
| 47 | + # Retry 45 times, wait 45s~135s | ||
| 48 | + i = 0 | ||
| 49 | + while i < 45: | ||
| 50 | + | ||
| 51 | + try: | ||
| 52 | + request = requests.get(location, verify=SSL_VERIFY, timeout=2) | ||
| 53 | + except RequestException as e: | ||
| 54 | + log.info("Try '%s' %d times, %s" % (location, i, str(e))) | ||
| 55 | + status = False | ||
| 56 | + i += 1 | ||
| 57 | + time.sleep(1) | ||
| 58 | + continue | ||
| 59 | + | ||
| 60 | + else: | ||
| 61 | + status = True | ||
| 62 | + return status | ||
| 63 | + | ||
| 64 | + return status | ||
| 65 | + | ||
| 66 | + | ||
| 67 | def _get_auth(location, user=None, passwd=None): | ||
| 68 | |||
| 69 | auth = None | ||
| 70 | @@ -96,6 +123,9 @@ def _get_auth(location, user=None, passwd=None): | ||
| 71 | def _load_url(location, user=None, passwd=None): | ||
| 72 | '''Load a location (URL or filename) and return contents as string''' | ||
| 73 | |||
| 74 | + if not _access_url(location): | ||
| 75 | + raise KickstartError(_("Connection %s failed" % location)) | ||
| 76 | + | ||
| 77 | auth = _get_auth(location, user=user, passwd=passwd) | ||
| 78 | |||
| 79 | try: | ||
| 80 | -- | ||
| 81 | 2.7.4 | ||
| 82 | |||
diff --git a/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_2.35.bb b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_2.35.bb new file mode 100644 index 0000000000..e96af43914 --- /dev/null +++ b/meta-python/recipes-extended/python-pykickstart/python3-pykickstart_2.35.bb | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | DESCRIPTION = "A python library for manipulating kickstart files" | ||
| 2 | HOMEPAGE = "http://fedoraproject.org/wiki/pykickstart" | ||
| 3 | LICENSE = "GPLv2+" | ||
| 4 | |||
| 5 | LIC_FILES_CHKSUM = "file://COPYING;md5=8ca43cbc842c2336e835926c2166c28b" | ||
| 6 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" | ||
| 7 | |||
| 8 | DEPENDS = "python3" | ||
| 9 | RDEPENDS_${PN} = "python3 \ | ||
| 10 | python3-requests \ | ||
| 11 | python3-six \ | ||
| 12 | " | ||
| 13 | |||
| 14 | S = "${WORKDIR}/git" | ||
| 15 | SRC_URI = "git://github.com/rhinstaller/pykickstart.git;protocol=https;branch=pykickstart-2 \ | ||
| 16 | file://0001-support-authentication-for-kickstart.patch \ | ||
| 17 | file://0002-pykickstart-parser.py-add-lock-for-readKickstart-and.patch \ | ||
| 18 | file://0003-comment-out-sections-shutdown-and-environment-in-gen.patch \ | ||
| 19 | file://0004-load.py-retry-to-invoke-request-with-timeout.patch \ | ||
| 20 | " | ||
| 21 | SRCREV = "b2787a818540e678c2f9c5dca0c6bbd65b8b55e5" | ||
| 22 | |||
| 23 | inherit setuptools3 | ||
| 24 | |||
| 25 | PROVIDES = "pykickstart" | ||
| 26 | RPROVIDES_${PN} = "pykickstart" | ||
