diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/lib/oe/package_manager.py | 195 |
1 files changed, 92 insertions, 103 deletions
diff --git a/meta/lib/oe/package_manager.py b/meta/lib/oe/package_manager.py index 0c5cf3cf7f..b80ea5e75c 100644 --- a/meta/lib/oe/package_manager.py +++ b/meta/lib/oe/package_manager.py | |||
@@ -22,12 +22,12 @@ def create_index(arg): | |||
22 | if result: | 22 | if result: |
23 | bb.note(result) | 23 | bb.note(result) |
24 | 24 | ||
25 | """ | ||
26 | This method parse the output from the package managerand return | ||
27 | a dictionary with the information of the packages. This is used | ||
28 | when the packages are in deb or ipk format. | ||
29 | """ | ||
30 | def opkg_query(cmd_output): | 25 | def opkg_query(cmd_output): |
26 | """ | ||
27 | This method parse the output from the package managerand return | ||
28 | a dictionary with the information of the packages. This is used | ||
29 | when the packages are in deb or ipk format. | ||
30 | """ | ||
31 | verregex = re.compile(' \([=<>]* [^ )]*\)') | 31 | verregex = re.compile(' \([=<>]* [^ )]*\)') |
32 | output = dict() | 32 | output = dict() |
33 | pkg = "" | 33 | pkg = "" |
@@ -317,34 +317,34 @@ class PackageManager(object, metaclass=ABCMeta): | |||
317 | self.deploy_dir = None | 317 | self.deploy_dir = None |
318 | self.deploy_lock = None | 318 | self.deploy_lock = None |
319 | 319 | ||
320 | """ | ||
321 | Update the package manager package database. | ||
322 | """ | ||
323 | @abstractmethod | 320 | @abstractmethod |
324 | def update(self): | 321 | def update(self): |
322 | """ | ||
323 | Update the package manager package database. | ||
324 | """ | ||
325 | pass | 325 | pass |
326 | 326 | ||
327 | """ | ||
328 | Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is | ||
329 | True, installation failures are ignored. | ||
330 | """ | ||
331 | @abstractmethod | 327 | @abstractmethod |
332 | def install(self, pkgs, attempt_only=False): | 328 | def install(self, pkgs, attempt_only=False): |
329 | """ | ||
330 | Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is | ||
331 | True, installation failures are ignored. | ||
332 | """ | ||
333 | pass | 333 | pass |
334 | 334 | ||
335 | """ | ||
336 | Remove a list of packages. 'pkgs' is a list object. If 'with_dependencies' | ||
337 | is False, the any dependencies are left in place. | ||
338 | """ | ||
339 | @abstractmethod | 335 | @abstractmethod |
340 | def remove(self, pkgs, with_dependencies=True): | 336 | def remove(self, pkgs, with_dependencies=True): |
337 | """ | ||
338 | Remove a list of packages. 'pkgs' is a list object. If 'with_dependencies' | ||
339 | is False, then any dependencies are left in place. | ||
340 | """ | ||
341 | pass | 341 | pass |
342 | 342 | ||
343 | """ | ||
344 | This function creates the index files | ||
345 | """ | ||
346 | @abstractmethod | 343 | @abstractmethod |
347 | def write_index(self): | 344 | def write_index(self): |
345 | """ | ||
346 | This function creates the index files | ||
347 | """ | ||
348 | pass | 348 | pass |
349 | 349 | ||
350 | @abstractmethod | 350 | @abstractmethod |
@@ -355,30 +355,28 @@ class PackageManager(object, metaclass=ABCMeta): | |||
355 | def list_installed(self): | 355 | def list_installed(self): |
356 | pass | 356 | pass |
357 | 357 | ||
358 | """ | ||
359 | Returns the path to a tmpdir where resides the contents of a package. | ||
360 | |||
361 | Deleting the tmpdir is responsability of the caller. | ||
362 | |||
363 | """ | ||
364 | @abstractmethod | 358 | @abstractmethod |
365 | def extract(self, pkg): | 359 | def extract(self, pkg): |
360 | """ | ||
361 | Returns the path to a tmpdir where resides the contents of a package. | ||
362 | Deleting the tmpdir is responsability of the caller. | ||
363 | """ | ||
366 | pass | 364 | pass |
367 | 365 | ||
368 | """ | ||
369 | Add remote package feeds into repository manager configuration. The parameters | ||
370 | for the feeds are set by feed_uris, feed_base_paths and feed_archs. | ||
371 | See http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PACKAGE_FEED_URIS | ||
372 | for their description. | ||
373 | """ | ||
374 | @abstractmethod | 366 | @abstractmethod |
375 | def insert_feeds_uris(self, feed_uris, feed_base_paths, feed_archs): | 367 | def insert_feeds_uris(self, feed_uris, feed_base_paths, feed_archs): |
368 | """ | ||
369 | Add remote package feeds into repository manager configuration. The parameters | ||
370 | for the feeds are set by feed_uris, feed_base_paths and feed_archs. | ||
371 | See http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PACKAGE_FEED_URIS | ||
372 | for their description. | ||
373 | """ | ||
376 | pass | 374 | pass |
377 | 375 | ||
378 | """ | ||
379 | Install all packages that match a glob. | ||
380 | """ | ||
381 | def install_glob(self, globs, sdk=False): | 376 | def install_glob(self, globs, sdk=False): |
377 | """ | ||
378 | Install all packages that match a glob. | ||
379 | """ | ||
382 | # TODO don't have sdk here but have a property on the superclass | 380 | # TODO don't have sdk here but have a property on the superclass |
383 | # (and respect in install_complementary) | 381 | # (and respect in install_complementary) |
384 | if sdk: | 382 | if sdk: |
@@ -398,14 +396,14 @@ class PackageManager(object, metaclass=ABCMeta): | |||
398 | "'%s' returned %d:\n%s" % | 396 | "'%s' returned %d:\n%s" % |
399 | (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) | 397 | (' '.join(cmd), e.returncode, e.output.decode("utf-8"))) |
400 | 398 | ||
401 | """ | ||
402 | Install complementary packages based upon the list of currently installed | ||
403 | packages e.g. locales, *-dev, *-dbg, etc. This will only attempt to install | ||
404 | these packages, if they don't exist then no error will occur. Note: every | ||
405 | backend needs to call this function explicitly after the normal package | ||
406 | installation | ||
407 | """ | ||
408 | def install_complementary(self, globs=None): | 399 | def install_complementary(self, globs=None): |
400 | """ | ||
401 | Install complementary packages based upon the list of currently installed | ||
402 | packages e.g. locales, *-dev, *-dbg, etc. This will only attempt to install | ||
403 | these packages, if they don't exist then no error will occur. Note: every | ||
404 | backend needs to call this function explicitly after the normal package | ||
405 | installation | ||
406 | """ | ||
409 | if globs is None: | 407 | if globs is None: |
410 | globs = self.d.getVar('IMAGE_INSTALL_COMPLEMENTARY') | 408 | globs = self.d.getVar('IMAGE_INSTALL_COMPLEMENTARY') |
411 | split_linguas = set() | 409 | split_linguas = set() |
@@ -462,13 +460,13 @@ class PackageManager(object, metaclass=ABCMeta): | |||
462 | 460 | ||
463 | self.deploy_lock = None | 461 | self.deploy_lock = None |
464 | 462 | ||
465 | """ | ||
466 | Construct URIs based on the following pattern: uri/base_path where 'uri' | ||
467 | and 'base_path' correspond to each element of the corresponding array | ||
468 | argument leading to len(uris) x len(base_paths) elements on the returned | ||
469 | array | ||
470 | """ | ||
471 | def construct_uris(self, uris, base_paths): | 463 | def construct_uris(self, uris, base_paths): |
464 | """ | ||
465 | Construct URIs based on the following pattern: uri/base_path where 'uri' | ||
466 | and 'base_path' correspond to each element of the corresponding array | ||
467 | argument leading to len(uris) x len(base_paths) elements on the returned | ||
468 | array | ||
469 | """ | ||
472 | def _append(arr1, arr2, sep='/'): | 470 | def _append(arr1, arr2, sep='/'): |
473 | res = [] | 471 | res = [] |
474 | narr1 = [a.rstrip(sep) for a in arr1] | 472 | narr1 = [a.rstrip(sep) for a in arr1] |
@@ -907,18 +905,18 @@ class RpmPM(PackageManager): | |||
907 | 905 | ||
908 | 906 | ||
909 | class OpkgDpkgPM(PackageManager): | 907 | class OpkgDpkgPM(PackageManager): |
910 | """ | ||
911 | This is an abstract class. Do not instantiate this directly. | ||
912 | """ | ||
913 | def __init__(self, d): | 908 | def __init__(self, d): |
909 | """ | ||
910 | This is an abstract class. Do not instantiate this directly. | ||
911 | """ | ||
914 | super(OpkgDpkgPM, self).__init__(d) | 912 | super(OpkgDpkgPM, self).__init__(d) |
915 | 913 | ||
916 | """ | ||
917 | Returns a dictionary with the package info. | ||
918 | |||
919 | This method extracts the common parts for Opkg and Dpkg | ||
920 | """ | ||
921 | def package_info(self, pkg, cmd): | 914 | def package_info(self, pkg, cmd): |
915 | """ | ||
916 | Returns a dictionary with the package info. | ||
917 | |||
918 | This method extracts the common parts for Opkg and Dpkg | ||
919 | """ | ||
922 | 920 | ||
923 | try: | 921 | try: |
924 | output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8") | 922 | output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8") |
@@ -927,14 +925,14 @@ class OpkgDpkgPM(PackageManager): | |||
927 | "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8"))) | 925 | "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8"))) |
928 | return opkg_query(output) | 926 | return opkg_query(output) |
929 | 927 | ||
930 | """ | 928 | def extract(self, pkg, pkg_info): |
931 | Returns the path to a tmpdir where resides the contents of a package. | 929 | """ |
930 | Returns the path to a tmpdir where resides the contents of a package. | ||
932 | 931 | ||
933 | Deleting the tmpdir is responsability of the caller. | 932 | Deleting the tmpdir is responsability of the caller. |
934 | 933 | ||
935 | This method extracts the common parts for Opkg and Dpkg | 934 | This method extracts the common parts for Opkg and Dpkg |
936 | """ | 935 | """ |
937 | def extract(self, pkg, pkg_info): | ||
938 | 936 | ||
939 | ar_cmd = bb.utils.which(os.getenv("PATH"), "ar") | 937 | ar_cmd = bb.utils.which(os.getenv("PATH"), "ar") |
940 | tar_cmd = bb.utils.which(os.getenv("PATH"), "tar") | 938 | tar_cmd = bb.utils.which(os.getenv("PATH"), "tar") |
@@ -1009,12 +1007,12 @@ class OpkgPM(OpkgDpkgPM): | |||
1009 | 1007 | ||
1010 | self.indexer = OpkgIndexer(self.d, self.deploy_dir) | 1008 | self.indexer = OpkgIndexer(self.d, self.deploy_dir) |
1011 | 1009 | ||
1012 | """ | ||
1013 | This function will change a package's status in /var/lib/opkg/status file. | ||
1014 | If 'packages' is None then the new_status will be applied to all | ||
1015 | packages | ||
1016 | """ | ||
1017 | def mark_packages(self, status_tag, packages=None): | 1010 | def mark_packages(self, status_tag, packages=None): |
1011 | """ | ||
1012 | This function will change a package's status in /var/lib/opkg/status file. | ||
1013 | If 'packages' is None then the new_status will be applied to all | ||
1014 | packages | ||
1015 | """ | ||
1018 | status_file = os.path.join(self.opkg_dir, "status") | 1016 | status_file = os.path.join(self.opkg_dir, "status") |
1019 | 1017 | ||
1020 | with open(status_file, "r") as sf: | 1018 | with open(status_file, "r") as sf: |
@@ -1265,10 +1263,10 @@ class OpkgPM(OpkgDpkgPM): | |||
1265 | # is separated from the following entry | 1263 | # is separated from the following entry |
1266 | status.write("\n") | 1264 | status.write("\n") |
1267 | 1265 | ||
1268 | ''' | ||
1269 | The following function dummy installs pkgs and returns the log of output. | ||
1270 | ''' | ||
1271 | def dummy_install(self, pkgs): | 1266 | def dummy_install(self, pkgs): |
1267 | """ | ||
1268 | The following function dummy installs pkgs and returns the log of output. | ||
1269 | """ | ||
1272 | if len(pkgs) == 0: | 1270 | if len(pkgs) == 0: |
1273 | return | 1271 | return |
1274 | 1272 | ||
@@ -1323,10 +1321,10 @@ class OpkgPM(OpkgDpkgPM): | |||
1323 | self.opkg_dir, | 1321 | self.opkg_dir, |
1324 | symlinks=True) | 1322 | symlinks=True) |
1325 | 1323 | ||
1326 | """ | ||
1327 | Returns a dictionary with the package info. | ||
1328 | """ | ||
1329 | def package_info(self, pkg): | 1324 | def package_info(self, pkg): |
1325 | """ | ||
1326 | Returns a dictionary with the package info. | ||
1327 | """ | ||
1330 | cmd = "%s %s info %s" % (self.opkg_cmd, self.opkg_args, pkg) | 1328 | cmd = "%s %s info %s" % (self.opkg_cmd, self.opkg_args, pkg) |
1331 | pkg_info = super(OpkgPM, self).package_info(pkg, cmd) | 1329 | pkg_info = super(OpkgPM, self).package_info(pkg, cmd) |
1332 | 1330 | ||
@@ -1337,12 +1335,12 @@ class OpkgPM(OpkgDpkgPM): | |||
1337 | 1335 | ||
1338 | return pkg_info | 1336 | return pkg_info |
1339 | 1337 | ||
1340 | """ | ||
1341 | Returns the path to a tmpdir where resides the contents of a package. | ||
1342 | |||
1343 | Deleting the tmpdir is responsability of the caller. | ||
1344 | """ | ||
1345 | def extract(self, pkg): | 1338 | def extract(self, pkg): |
1339 | """ | ||
1340 | Returns the path to a tmpdir where resides the contents of a package. | ||
1341 | |||
1342 | Deleting the tmpdir is responsability of the caller. | ||
1343 | """ | ||
1346 | pkg_info = self.package_info(pkg) | 1344 | pkg_info = self.package_info(pkg) |
1347 | if not pkg_info: | 1345 | if not pkg_info: |
1348 | bb.fatal("Unable to get information for package '%s' while " | 1346 | bb.fatal("Unable to get information for package '%s' while " |
@@ -1376,12 +1374,12 @@ class DpkgPM(OpkgDpkgPM): | |||
1376 | 1374 | ||
1377 | self.indexer = DpkgIndexer(self.d, self.deploy_dir) | 1375 | self.indexer = DpkgIndexer(self.d, self.deploy_dir) |
1378 | 1376 | ||
1379 | """ | ||
1380 | This function will change a package's status in /var/lib/dpkg/status file. | ||
1381 | If 'packages' is None then the new_status will be applied to all | ||
1382 | packages | ||
1383 | """ | ||
1384 | def mark_packages(self, status_tag, packages=None): | 1377 | def mark_packages(self, status_tag, packages=None): |
1378 | """ | ||
1379 | This function will change a package's status in /var/lib/dpkg/status file. | ||
1380 | If 'packages' is None then the new_status will be applied to all | ||
1381 | packages | ||
1382 | """ | ||
1385 | status_file = self.target_rootfs + "/var/lib/dpkg/status" | 1383 | status_file = self.target_rootfs + "/var/lib/dpkg/status" |
1386 | 1384 | ||
1387 | with open(status_file, "r") as sf: | 1385 | with open(status_file, "r") as sf: |
@@ -1404,11 +1402,11 @@ class DpkgPM(OpkgDpkgPM): | |||
1404 | 1402 | ||
1405 | os.rename(status_file + ".tmp", status_file) | 1403 | os.rename(status_file + ".tmp", status_file) |
1406 | 1404 | ||
1407 | """ | ||
1408 | Run the pre/post installs for package "package_name". If package_name is | ||
1409 | None, then run all pre/post install scriptlets. | ||
1410 | """ | ||
1411 | def run_pre_post_installs(self, package_name=None): | 1405 | def run_pre_post_installs(self, package_name=None): |
1406 | """ | ||
1407 | Run the pre/post installs for package "package_name". If package_name is | ||
1408 | None, then run all pre/post install scriptlets. | ||
1409 | """ | ||
1412 | info_dir = self.target_rootfs + "/var/lib/dpkg/info" | 1410 | info_dir = self.target_rootfs + "/var/lib/dpkg/info" |
1413 | ControlScript = collections.namedtuple("ControlScript", ["suffix", "name", "argument"]) | 1411 | ControlScript = collections.namedtuple("ControlScript", ["suffix", "name", "argument"]) |
1414 | control_scripts = [ | 1412 | control_scripts = [ |
@@ -1654,10 +1652,10 @@ class DpkgPM(OpkgDpkgPM): | |||
1654 | def list_installed(self): | 1652 | def list_installed(self): |
1655 | return DpkgPkgsList(self.d, self.target_rootfs).list_pkgs() | 1653 | return DpkgPkgsList(self.d, self.target_rootfs).list_pkgs() |
1656 | 1654 | ||
1657 | """ | ||
1658 | Returns a dictionary with the package info. | ||
1659 | """ | ||
1660 | def package_info(self, pkg): | 1655 | def package_info(self, pkg): |
1656 | """ | ||
1657 | Returns a dictionary with the package info. | ||
1658 | """ | ||
1661 | cmd = "%s show %s" % (self.apt_cache_cmd, pkg) | 1659 | cmd = "%s show %s" % (self.apt_cache_cmd, pkg) |
1662 | pkg_info = super(DpkgPM, self).package_info(pkg, cmd) | 1660 | pkg_info = super(DpkgPM, self).package_info(pkg, cmd) |
1663 | 1661 | ||
@@ -1668,12 +1666,12 @@ class DpkgPM(OpkgDpkgPM): | |||
1668 | 1666 | ||
1669 | return pkg_info | 1667 | return pkg_info |
1670 | 1668 | ||
1671 | """ | ||
1672 | Returns the path to a tmpdir where resides the contents of a package. | ||
1673 | |||
1674 | Deleting the tmpdir is responsability of the caller. | ||
1675 | """ | ||
1676 | def extract(self, pkg): | 1669 | def extract(self, pkg): |
1670 | """ | ||
1671 | Returns the path to a tmpdir where resides the contents of a package. | ||
1672 | |||
1673 | Deleting the tmpdir is responsability of the caller. | ||
1674 | """ | ||
1677 | pkg_info = self.package_info(pkg) | 1675 | pkg_info = self.package_info(pkg) |
1678 | if not pkg_info: | 1676 | if not pkg_info: |
1679 | bb.fatal("Unable to get information for package '%s' while " | 1677 | bb.fatal("Unable to get information for package '%s' while " |
@@ -1704,12 +1702,3 @@ def generate_index_files(d): | |||
1704 | 1702 | ||
1705 | if result is not None: | 1703 | if result is not None: |
1706 | bb.fatal(result) | 1704 | bb.fatal(result) |
1707 | |||
1708 | if __name__ == "__main__": | ||
1709 | """ | ||
1710 | We should be able to run this as a standalone script, from outside bitbake | ||
1711 | environment. | ||
1712 | """ | ||
1713 | """ | ||
1714 | TBD | ||
1715 | """ | ||