summaryrefslogtreecommitdiffstats
path: root/meta/lib
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib')
-rw-r--r--meta/lib/oe/package_manager.py195
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"""
26This method parse the output from the package managerand return
27a dictionary with the information of the packages. This is used
28when the packages are in deb or ipk format.
29"""
30def opkg_query(cmd_output): 25def 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
909class OpkgDpkgPM(PackageManager): 907class 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
1708if __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 """