diff options
Diffstat (limited to 'meta/lib/oe/package_manager/deb/__init__.py')
-rw-r--r-- | meta/lib/oe/package_manager/deb/__init__.py | 122 |
1 files changed, 30 insertions, 92 deletions
diff --git a/meta/lib/oe/package_manager/deb/__init__.py b/meta/lib/oe/package_manager/deb/__init__.py index 2ee68fefb1..e09e81e490 100644 --- a/meta/lib/oe/package_manager/deb/__init__.py +++ b/meta/lib/oe/package_manager/deb/__init__.py | |||
@@ -1,10 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
2 | # SPDX-License-Identifier: GPL-2.0-only | 4 | # SPDX-License-Identifier: GPL-2.0-only |
3 | # | 5 | # |
4 | 6 | ||
5 | import re | 7 | import re |
6 | import subprocess | 8 | import subprocess |
7 | from oe.package_manager import * | 9 | from oe.package_manager import * |
10 | from oe.package_manager.common_deb_ipk import OpkgDpkgPM | ||
8 | 11 | ||
9 | class DpkgIndexer(Indexer): | 12 | class DpkgIndexer(Indexer): |
10 | def _create_configs(self): | 13 | def _create_configs(self): |
@@ -53,6 +56,7 @@ class DpkgIndexer(Indexer): | |||
53 | 56 | ||
54 | index_cmds = [] | 57 | index_cmds = [] |
55 | deb_dirs_found = False | 58 | deb_dirs_found = False |
59 | index_sign_files = set() | ||
56 | for arch in arch_list: | 60 | for arch in arch_list: |
57 | arch_dir = os.path.join(self.deploy_dir, arch) | 61 | arch_dir = os.path.join(self.deploy_dir, arch) |
58 | if not os.path.isdir(arch_dir): | 62 | if not os.path.isdir(arch_dir): |
@@ -62,7 +66,10 @@ class DpkgIndexer(Indexer): | |||
62 | 66 | ||
63 | cmd += "%s -fcn Packages > Packages.gz;" % gzip | 67 | cmd += "%s -fcn Packages > Packages.gz;" % gzip |
64 | 68 | ||
65 | with open(os.path.join(arch_dir, "Release"), "w+") as release: | 69 | release_file = os.path.join(arch_dir, "Release") |
70 | index_sign_files.add(release_file) | ||
71 | |||
72 | with open(release_file, "w+") as release: | ||
66 | release.write("Label: %s\n" % arch) | 73 | release.write("Label: %s\n" % arch) |
67 | 74 | ||
68 | cmd += "PSEUDO_UNLOAD=1 %s release . >> Release" % apt_ftparchive | 75 | cmd += "PSEUDO_UNLOAD=1 %s release . >> Release" % apt_ftparchive |
@@ -77,7 +84,16 @@ class DpkgIndexer(Indexer): | |||
77 | 84 | ||
78 | oe.utils.multiprocess_launch(create_index, index_cmds, self.d) | 85 | oe.utils.multiprocess_launch(create_index, index_cmds, self.d) |
79 | if self.d.getVar('PACKAGE_FEED_SIGN') == '1': | 86 | if self.d.getVar('PACKAGE_FEED_SIGN') == '1': |
80 | raise NotImplementedError('Package feed signing not implementd for dpkg') | 87 | signer = get_signer(self.d, self.d.getVar('PACKAGE_FEED_GPG_BACKEND')) |
88 | else: | ||
89 | signer = None | ||
90 | if signer: | ||
91 | for f in index_sign_files: | ||
92 | signer.detach_sign(f, | ||
93 | self.d.getVar('PACKAGE_FEED_GPG_NAME'), | ||
94 | self.d.getVar('PACKAGE_FEED_GPG_PASSPHRASE_FILE'), | ||
95 | output_suffix="gpg", | ||
96 | use_sha256=True) | ||
81 | 97 | ||
82 | class PMPkgsList(PkgsList): | 98 | class PMPkgsList(PkgsList): |
83 | 99 | ||
@@ -96,72 +112,6 @@ class PMPkgsList(PkgsList): | |||
96 | 112 | ||
97 | return opkg_query(cmd_output) | 113 | return opkg_query(cmd_output) |
98 | 114 | ||
99 | class OpkgDpkgPM(PackageManager): | ||
100 | def __init__(self, d, target_rootfs): | ||
101 | """ | ||
102 | This is an abstract class. Do not instantiate this directly. | ||
103 | """ | ||
104 | super(OpkgDpkgPM, self).__init__(d, target_rootfs) | ||
105 | |||
106 | def package_info(self, pkg, cmd): | ||
107 | """ | ||
108 | Returns a dictionary with the package info. | ||
109 | |||
110 | This method extracts the common parts for Opkg and Dpkg | ||
111 | """ | ||
112 | |||
113 | try: | ||
114 | output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8") | ||
115 | except subprocess.CalledProcessError as e: | ||
116 | bb.fatal("Unable to list available packages. Command '%s' " | ||
117 | "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8"))) | ||
118 | return opkg_query(output) | ||
119 | |||
120 | def extract(self, pkg, pkg_info): | ||
121 | """ | ||
122 | Returns the path to a tmpdir where resides the contents of a package. | ||
123 | |||
124 | Deleting the tmpdir is responsability of the caller. | ||
125 | |||
126 | This method extracts the common parts for Opkg and Dpkg | ||
127 | """ | ||
128 | |||
129 | ar_cmd = bb.utils.which(os.getenv("PATH"), "ar") | ||
130 | tar_cmd = bb.utils.which(os.getenv("PATH"), "tar") | ||
131 | pkg_path = pkg_info[pkg]["filepath"] | ||
132 | |||
133 | if not os.path.isfile(pkg_path): | ||
134 | bb.fatal("Unable to extract package for '%s'." | ||
135 | "File %s doesn't exists" % (pkg, pkg_path)) | ||
136 | |||
137 | tmp_dir = tempfile.mkdtemp() | ||
138 | current_dir = os.getcwd() | ||
139 | os.chdir(tmp_dir) | ||
140 | data_tar = 'data.tar.xz' | ||
141 | |||
142 | try: | ||
143 | cmd = [ar_cmd, 'x', pkg_path] | ||
144 | output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) | ||
145 | cmd = [tar_cmd, 'xf', data_tar] | ||
146 | output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) | ||
147 | except subprocess.CalledProcessError as e: | ||
148 | bb.utils.remove(tmp_dir, recurse=True) | ||
149 | bb.fatal("Unable to extract %s package. Command '%s' " | ||
150 | "returned %d:\n%s" % (pkg_path, ' '.join(cmd), e.returncode, e.output.decode("utf-8"))) | ||
151 | except OSError as e: | ||
152 | bb.utils.remove(tmp_dir, recurse=True) | ||
153 | bb.fatal("Unable to extract %s package. Command '%s' " | ||
154 | "returned %d:\n%s at %s" % (pkg_path, ' '.join(cmd), e.errno, e.strerror, e.filename)) | ||
155 | |||
156 | bb.note("Extracted %s to %s" % (pkg_path, tmp_dir)) | ||
157 | bb.utils.remove(os.path.join(tmp_dir, "debian-binary")) | ||
158 | bb.utils.remove(os.path.join(tmp_dir, "control.tar.gz")) | ||
159 | os.chdir(current_dir) | ||
160 | |||
161 | return tmp_dir | ||
162 | |||
163 | def _handle_intercept_failure(self, registered_pkgs): | ||
164 | self.mark_packages("unpacked", registered_pkgs.split()) | ||
165 | 115 | ||
166 | class DpkgPM(OpkgDpkgPM): | 116 | class DpkgPM(OpkgDpkgPM): |
167 | def __init__(self, d, target_rootfs, archs, base_archs, apt_conf_dir=None, deb_repo_workdir="oe-rootfs-repo", filterbydependencies=True): | 117 | def __init__(self, d, target_rootfs, archs, base_archs, apt_conf_dir=None, deb_repo_workdir="oe-rootfs-repo", filterbydependencies=True): |
@@ -214,7 +164,7 @@ class DpkgPM(OpkgDpkgPM): | |||
214 | 164 | ||
215 | tmp_sf.write(status) | 165 | tmp_sf.write(status) |
216 | 166 | ||
217 | os.rename(status_file + ".tmp", status_file) | 167 | bb.utils.rename(status_file + ".tmp", status_file) |
218 | 168 | ||
219 | def run_pre_post_installs(self, package_name=None): | 169 | def run_pre_post_installs(self, package_name=None): |
220 | """ | 170 | """ |
@@ -276,14 +226,18 @@ class DpkgPM(OpkgDpkgPM): | |||
276 | 226 | ||
277 | self.deploy_dir_unlock() | 227 | self.deploy_dir_unlock() |
278 | 228 | ||
279 | def install(self, pkgs, attempt_only=False): | 229 | def install(self, pkgs, attempt_only=False, hard_depends_only=False): |
280 | if attempt_only and len(pkgs) == 0: | 230 | if attempt_only and len(pkgs) == 0: |
281 | return | 231 | return |
282 | 232 | ||
283 | os.environ['APT_CONFIG'] = self.apt_conf_file | 233 | os.environ['APT_CONFIG'] = self.apt_conf_file |
284 | 234 | ||
285 | cmd = "%s %s install --allow-downgrades --allow-remove-essential --allow-change-held-packages --allow-unauthenticated --no-remove %s" % \ | 235 | extra_args = "" |
286 | (self.apt_get_cmd, self.apt_args, ' '.join(pkgs)) | 236 | if hard_depends_only: |
237 | extra_args = "--no-install-recommends" | ||
238 | |||
239 | cmd = "%s %s install --allow-downgrades --allow-remove-essential --allow-change-held-packages --allow-unauthenticated --no-remove %s %s" % \ | ||
240 | (self.apt_get_cmd, self.apt_args, extra_args, ' '.join(pkgs)) | ||
287 | 241 | ||
288 | try: | 242 | try: |
289 | bb.note("Installing the following packages: %s" % ' '.join(pkgs)) | 243 | bb.note("Installing the following packages: %s" % ' '.join(pkgs)) |
@@ -299,13 +253,13 @@ class DpkgPM(OpkgDpkgPM): | |||
299 | for dir in dirs: | 253 | for dir in dirs: |
300 | new_dir = re.sub(r"\.dpkg-new", "", dir) | 254 | new_dir = re.sub(r"\.dpkg-new", "", dir) |
301 | if dir != new_dir: | 255 | if dir != new_dir: |
302 | os.rename(os.path.join(root, dir), | 256 | bb.utils.rename(os.path.join(root, dir), |
303 | os.path.join(root, new_dir)) | 257 | os.path.join(root, new_dir)) |
304 | 258 | ||
305 | for file in files: | 259 | for file in files: |
306 | new_file = re.sub(r"\.dpkg-new", "", file) | 260 | new_file = re.sub(r"\.dpkg-new", "", file) |
307 | if file != new_file: | 261 | if file != new_file: |
308 | os.rename(os.path.join(root, file), | 262 | bb.utils.rename(os.path.join(root, file), |
309 | os.path.join(root, new_file)) | 263 | os.path.join(root, new_file)) |
310 | 264 | ||
311 | 265 | ||
@@ -422,7 +376,7 @@ class DpkgPM(OpkgDpkgPM): | |||
422 | multilib_variants = self.d.getVar("MULTILIB_VARIANTS"); | 376 | multilib_variants = self.d.getVar("MULTILIB_VARIANTS"); |
423 | for variant in multilib_variants.split(): | 377 | for variant in multilib_variants.split(): |
424 | localdata = bb.data.createCopy(self.d) | 378 | localdata = bb.data.createCopy(self.d) |
425 | variant_tune = localdata.getVar("DEFAULTTUNE_virtclass-multilib-" + variant, False) | 379 | variant_tune = localdata.getVar("DEFAULTTUNE:virtclass-multilib-" + variant, False) |
426 | orig_arch = localdata.getVar("DPKG_ARCH") | 380 | orig_arch = localdata.getVar("DPKG_ARCH") |
427 | localdata.setVar("DEFAULTTUNE", variant_tune) | 381 | localdata.setVar("DEFAULTTUNE", variant_tune) |
428 | variant_arch = localdata.getVar("DPKG_ARCH") | 382 | variant_arch = localdata.getVar("DPKG_ARCH") |
@@ -477,7 +431,7 @@ class DpkgPM(OpkgDpkgPM): | |||
477 | Returns a dictionary with the package info. | 431 | Returns a dictionary with the package info. |
478 | """ | 432 | """ |
479 | cmd = "%s show %s" % (self.apt_cache_cmd, pkg) | 433 | cmd = "%s show %s" % (self.apt_cache_cmd, pkg) |
480 | pkg_info = super(DpkgPM, self).package_info(pkg, cmd) | 434 | pkg_info = self._common_package_info(cmd) |
481 | 435 | ||
482 | pkg_arch = pkg_info[pkg]["pkgarch"] | 436 | pkg_arch = pkg_info[pkg]["pkgarch"] |
483 | pkg_filename = pkg_info[pkg]["filename"] | 437 | pkg_filename = pkg_info[pkg]["filename"] |
@@ -485,19 +439,3 @@ class DpkgPM(OpkgDpkgPM): | |||
485 | os.path.join(self.deploy_dir, pkg_arch, pkg_filename) | 439 | os.path.join(self.deploy_dir, pkg_arch, pkg_filename) |
486 | 440 | ||
487 | return pkg_info | 441 | return pkg_info |
488 | |||
489 | def extract(self, pkg): | ||
490 | """ | ||
491 | Returns the path to a tmpdir where resides the contents of a package. | ||
492 | |||
493 | Deleting the tmpdir is responsability of the caller. | ||
494 | """ | ||
495 | pkg_info = self.package_info(pkg) | ||
496 | if not pkg_info: | ||
497 | bb.fatal("Unable to get information for package '%s' while " | ||
498 | "trying to extract the package." % pkg) | ||
499 | |||
500 | tmp_dir = super(DpkgPM, self).extract(pkg, pkg_info) | ||
501 | bb.utils.remove(os.path.join(tmp_dir, "data.tar.xz")) | ||
502 | |||
503 | return tmp_dir | ||