summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorFredrik Gustafsson <fredrik.gustafsson@axis.com>2020-07-24 16:42:41 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-07-27 19:58:10 +0100
commitf5f6ae2986badb895776196647c00f12a2cd6ba7 (patch)
tree8c4dd7853b0a4437946505652702140037b274b2 /meta
parent5bc67f55028407de78ac09f97f9a47b165ae8760 (diff)
downloadpoky-f5f6ae2986badb895776196647c00f12a2cd6ba7.tar.gz
deb: Move package manager to its own dir
This is a part of a refactor that will split the package manager code so that it's possible to use other package managers in other layers. RP: Fixes to parse/build (From OE-Core rev: 510d5c48c0496f23a3d7aede76ea8735da2d371d) Signed-off-by: Fredrik Gustafsson <fredrigu@axis.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/lib/oe/package_manager/__init__.py488
-rw-r--r--meta/lib/oe/package_manager/deb/__init__.py487
-rw-r--r--meta/lib/oe/package_manager/deb/rootfs.py2
-rw-r--r--meta/lib/oe/package_manager/deb/sdk.py2
-rw-r--r--meta/lib/oe/rootfs.py1
-rw-r--r--meta/lib/oe/sdk.py1
-rw-r--r--meta/lib/oeqa/utils/package_manager.py3
7 files changed, 493 insertions, 491 deletions
diff --git a/meta/lib/oe/package_manager/__init__.py b/meta/lib/oe/package_manager/__init__.py
index 4deb12837a..865d6f9493 100644
--- a/meta/lib/oe/package_manager/__init__.py
+++ b/meta/lib/oe/package_manager/__init__.py
@@ -149,81 +149,6 @@ class Indexer(object, metaclass=ABCMeta):
149 def write_index(self): 149 def write_index(self):
150 pass 150 pass
151 151
152class DpkgIndexer(Indexer):
153 def _create_configs(self):
154 bb.utils.mkdirhier(self.apt_conf_dir)
155 bb.utils.mkdirhier(os.path.join(self.apt_conf_dir, "lists", "partial"))
156 bb.utils.mkdirhier(os.path.join(self.apt_conf_dir, "apt.conf.d"))
157 bb.utils.mkdirhier(os.path.join(self.apt_conf_dir, "preferences.d"))
158
159 with open(os.path.join(self.apt_conf_dir, "preferences"),
160 "w") as prefs_file:
161 pass
162 with open(os.path.join(self.apt_conf_dir, "sources.list"),
163 "w+") as sources_file:
164 pass
165
166 with open(self.apt_conf_file, "w") as apt_conf:
167 with open(os.path.join(self.d.expand("${STAGING_ETCDIR_NATIVE}"),
168 "apt", "apt.conf.sample")) as apt_conf_sample:
169 for line in apt_conf_sample.read().split("\n"):
170 line = re.sub(r"#ROOTFS#", "/dev/null", line)
171 line = re.sub(r"#APTCONF#", self.apt_conf_dir, line)
172 apt_conf.write(line + "\n")
173
174 def write_index(self):
175 self.apt_conf_dir = os.path.join(self.d.expand("${APTCONF_TARGET}"),
176 "apt-ftparchive")
177 self.apt_conf_file = os.path.join(self.apt_conf_dir, "apt.conf")
178 self._create_configs()
179
180 os.environ['APT_CONFIG'] = self.apt_conf_file
181
182 pkg_archs = self.d.getVar('PACKAGE_ARCHS')
183 if pkg_archs is not None:
184 arch_list = pkg_archs.split()
185 sdk_pkg_archs = self.d.getVar('SDK_PACKAGE_ARCHS')
186 if sdk_pkg_archs is not None:
187 for a in sdk_pkg_archs.split():
188 if a not in pkg_archs:
189 arch_list.append(a)
190
191 all_mlb_pkg_arch_list = (self.d.getVar('ALL_MULTILIB_PACKAGE_ARCHS') or "").split()
192 arch_list.extend(arch for arch in all_mlb_pkg_arch_list if arch not in arch_list)
193
194 apt_ftparchive = bb.utils.which(os.getenv('PATH'), "apt-ftparchive")
195 gzip = bb.utils.which(os.getenv('PATH'), "gzip")
196
197 index_cmds = []
198 deb_dirs_found = False
199 for arch in arch_list:
200 arch_dir = os.path.join(self.deploy_dir, arch)
201 if not os.path.isdir(arch_dir):
202 continue
203
204 cmd = "cd %s; PSEUDO_UNLOAD=1 %s packages . > Packages;" % (arch_dir, apt_ftparchive)
205
206 cmd += "%s -fcn Packages > Packages.gz;" % gzip
207
208 with open(os.path.join(arch_dir, "Release"), "w+") as release:
209 release.write("Label: %s\n" % arch)
210
211 cmd += "PSEUDO_UNLOAD=1 %s release . >> Release" % apt_ftparchive
212
213 index_cmds.append(cmd)
214
215 deb_dirs_found = True
216
217 if not deb_dirs_found:
218 bb.note("There are no packages in %s" % self.deploy_dir)
219 return
220
221 oe.utils.multiprocess_launch(create_index, index_cmds, self.d)
222 if self.d.getVar('PACKAGE_FEED_SIGN') == '1':
223 raise NotImplementedError('Package feed signing not implementd for dpkg')
224
225
226
227class PkgsList(object, metaclass=ABCMeta): 152class PkgsList(object, metaclass=ABCMeta):
228 def __init__(self, d, rootfs_dir): 153 def __init__(self, d, rootfs_dir):
229 self.d = d 154 self.d = d
@@ -233,24 +158,6 @@ class PkgsList(object, metaclass=ABCMeta):
233 def list_pkgs(self): 158 def list_pkgs(self):
234 pass 159 pass
235 160
236class DpkgPkgsList(PkgsList):
237
238 def list_pkgs(self):
239 cmd = [bb.utils.which(os.getenv('PATH'), "dpkg-query"),
240 "--admindir=%s/var/lib/dpkg" % self.rootfs_dir,
241 "-W"]
242
243 cmd.append("-f=Package: ${Package}\nArchitecture: ${PackageArch}\nVersion: ${Version}\nFile: ${Package}_${Version}_${Architecture}.deb\nDepends: ${Depends}\nRecommends: ${Recommends}\nProvides: ${Provides}\n\n")
244
245 try:
246 cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip().decode("utf-8")
247 except subprocess.CalledProcessError as e:
248 bb.fatal("Cannot get the installed packages list. Command '%s' "
249 "returned %d:\n%s" % (' '.join(cmd), e.returncode, e.output.decode("utf-8")))
250
251 return opkg_query(cmd_output)
252
253
254class PackageManager(object, metaclass=ABCMeta): 161class PackageManager(object, metaclass=ABCMeta):
255 """ 162 """
256 This is an abstract class. Do not instantiate this directly. 163 This is an abstract class. Do not instantiate this directly.
@@ -616,404 +523,11 @@ def create_packages_dir(d, subrepo_dir, deploydir, taskname, filterbydependencie
616 else: 523 else:
617 raise 524 raise
618 525
619class OpkgDpkgPM(PackageManager):
620 def __init__(self, d, target_rootfs):
621 """
622 This is an abstract class. Do not instantiate this directly.
623 """
624 super(OpkgDpkgPM, self).__init__(d, target_rootfs)
625
626 def package_info(self, pkg, cmd):
627 """
628 Returns a dictionary with the package info.
629
630 This method extracts the common parts for Opkg and Dpkg
631 """
632
633 try:
634 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8")
635 except subprocess.CalledProcessError as e:
636 bb.fatal("Unable to list available packages. Command '%s' "
637 "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8")))
638 return opkg_query(output)
639
640 def extract(self, pkg, pkg_info):
641 """
642 Returns the path to a tmpdir where resides the contents of a package.
643
644 Deleting the tmpdir is responsability of the caller.
645
646 This method extracts the common parts for Opkg and Dpkg
647 """
648
649 ar_cmd = bb.utils.which(os.getenv("PATH"), "ar")
650 tar_cmd = bb.utils.which(os.getenv("PATH"), "tar")
651 pkg_path = pkg_info[pkg]["filepath"]
652
653 if not os.path.isfile(pkg_path):
654 bb.fatal("Unable to extract package for '%s'."
655 "File %s doesn't exists" % (pkg, pkg_path))
656
657 tmp_dir = tempfile.mkdtemp()
658 current_dir = os.getcwd()
659 os.chdir(tmp_dir)
660 data_tar = 'data.tar.xz'
661
662 try:
663 cmd = [ar_cmd, 'x', pkg_path]
664 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
665 cmd = [tar_cmd, 'xf', data_tar]
666 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
667 except subprocess.CalledProcessError as e:
668 bb.utils.remove(tmp_dir, recurse=True)
669 bb.fatal("Unable to extract %s package. Command '%s' "
670 "returned %d:\n%s" % (pkg_path, ' '.join(cmd), e.returncode, e.output.decode("utf-8")))
671 except OSError as e:
672 bb.utils.remove(tmp_dir, recurse=True)
673 bb.fatal("Unable to extract %s package. Command '%s' "
674 "returned %d:\n%s at %s" % (pkg_path, ' '.join(cmd), e.errno, e.strerror, e.filename))
675
676 bb.note("Extracted %s to %s" % (pkg_path, tmp_dir))
677 bb.utils.remove(os.path.join(tmp_dir, "debian-binary"))
678 bb.utils.remove(os.path.join(tmp_dir, "control.tar.gz"))
679 os.chdir(current_dir)
680
681 return tmp_dir
682
683 def _handle_intercept_failure(self, registered_pkgs):
684 self.mark_packages("unpacked", registered_pkgs.split())
685
686class DpkgPM(OpkgDpkgPM):
687 def __init__(self, d, target_rootfs, archs, base_archs, apt_conf_dir=None, deb_repo_workdir="oe-rootfs-repo", filterbydependencies=True):
688 super(DpkgPM, self).__init__(d, target_rootfs)
689 self.deploy_dir = oe.path.join(self.d.getVar('WORKDIR'), deb_repo_workdir)
690
691 create_packages_dir(self.d, self.deploy_dir, d.getVar("DEPLOY_DIR_DEB"), "package_write_deb", filterbydependencies)
692
693 if apt_conf_dir is None:
694 self.apt_conf_dir = self.d.expand("${APTCONF_TARGET}/apt")
695 else:
696 self.apt_conf_dir = apt_conf_dir
697 self.apt_conf_file = os.path.join(self.apt_conf_dir, "apt.conf")
698 self.apt_get_cmd = bb.utils.which(os.getenv('PATH'), "apt-get")
699 self.apt_cache_cmd = bb.utils.which(os.getenv('PATH'), "apt-cache")
700
701 self.apt_args = d.getVar("APT_ARGS")
702
703 self.all_arch_list = archs.split()
704 all_mlb_pkg_arch_list = (self.d.getVar('ALL_MULTILIB_PACKAGE_ARCHS') or "").split()
705 self.all_arch_list.extend(arch for arch in all_mlb_pkg_arch_list if arch not in self.all_arch_list)
706
707 self._create_configs(archs, base_archs)
708
709 self.indexer = DpkgIndexer(self.d, self.deploy_dir)
710
711 def mark_packages(self, status_tag, packages=None):
712 """
713 This function will change a package's status in /var/lib/dpkg/status file.
714 If 'packages' is None then the new_status will be applied to all
715 packages
716 """
717 status_file = self.target_rootfs + "/var/lib/dpkg/status"
718
719 with open(status_file, "r") as sf:
720 with open(status_file + ".tmp", "w+") as tmp_sf:
721 if packages is None:
722 tmp_sf.write(re.sub(r"Package: (.*?)\n((?:[^\n]+\n)*?)Status: (.*)(?:unpacked|installed)",
723 r"Package: \1\n\2Status: \3%s" % status_tag,
724 sf.read()))
725 else:
726 if type(packages).__name__ != "list":
727 raise TypeError("'packages' should be a list object")
728
729 status = sf.read()
730 for pkg in packages:
731 status = re.sub(r"Package: %s\n((?:[^\n]+\n)*?)Status: (.*)(?:unpacked|installed)" % pkg,
732 r"Package: %s\n\1Status: \2%s" % (pkg, status_tag),
733 status)
734
735 tmp_sf.write(status)
736
737 os.rename(status_file + ".tmp", status_file)
738
739 def run_pre_post_installs(self, package_name=None):
740 """
741 Run the pre/post installs for package "package_name". If package_name is
742 None, then run all pre/post install scriptlets.
743 """
744 info_dir = self.target_rootfs + "/var/lib/dpkg/info"
745 ControlScript = collections.namedtuple("ControlScript", ["suffix", "name", "argument"])
746 control_scripts = [
747 ControlScript(".preinst", "Preinstall", "install"),
748 ControlScript(".postinst", "Postinstall", "configure")]
749 status_file = self.target_rootfs + "/var/lib/dpkg/status"
750 installed_pkgs = []
751
752 with open(status_file, "r") as status:
753 for line in status.read().split('\n'):
754 m = re.match(r"^Package: (.*)", line)
755 if m is not None:
756 installed_pkgs.append(m.group(1))
757
758 if package_name is not None and not package_name in installed_pkgs:
759 return
760
761 os.environ['D'] = self.target_rootfs
762 os.environ['OFFLINE_ROOT'] = self.target_rootfs
763 os.environ['IPKG_OFFLINE_ROOT'] = self.target_rootfs
764 os.environ['OPKG_OFFLINE_ROOT'] = self.target_rootfs
765 os.environ['INTERCEPT_DIR'] = self.intercepts_dir
766 os.environ['NATIVE_ROOT'] = self.d.getVar('STAGING_DIR_NATIVE')
767
768 for pkg_name in installed_pkgs:
769 for control_script in control_scripts:
770 p_full = os.path.join(info_dir, pkg_name + control_script.suffix)
771 if os.path.exists(p_full):
772 try:
773 bb.note("Executing %s for package: %s ..." %
774 (control_script.name.lower(), pkg_name))
775 output = subprocess.check_output([p_full, control_script.argument],
776 stderr=subprocess.STDOUT).decode("utf-8")
777 bb.note(output)
778 except subprocess.CalledProcessError as e:
779 bb.warn("%s for package %s failed with %d:\n%s" %
780 (control_script.name, pkg_name, e.returncode,
781 e.output.decode("utf-8")))
782 failed_postinsts_abort([pkg_name], self.d.expand("${T}/log.do_${BB_CURRENTTASK}"))
783
784 def update(self):
785 os.environ['APT_CONFIG'] = self.apt_conf_file
786
787 self.deploy_dir_lock()
788
789 cmd = "%s update" % self.apt_get_cmd
790
791 try:
792 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
793 except subprocess.CalledProcessError as e:
794 bb.fatal("Unable to update the package index files. Command '%s' "
795 "returned %d:\n%s" % (e.cmd, e.returncode, e.output.decode("utf-8")))
796
797 self.deploy_dir_unlock()
798
799 def install(self, pkgs, attempt_only=False):
800 if attempt_only and len(pkgs) == 0:
801 return
802
803 os.environ['APT_CONFIG'] = self.apt_conf_file
804
805 cmd = "%s %s install --force-yes --allow-unauthenticated --no-remove %s" % \
806 (self.apt_get_cmd, self.apt_args, ' '.join(pkgs))
807
808 try:
809 bb.note("Installing the following packages: %s" % ' '.join(pkgs))
810 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
811 except subprocess.CalledProcessError as e:
812 (bb.fatal, bb.warn)[attempt_only]("Unable to install packages. "
813 "Command '%s' returned %d:\n%s" %
814 (cmd, e.returncode, e.output.decode("utf-8")))
815
816 # rename *.dpkg-new files/dirs
817 for root, dirs, files in os.walk(self.target_rootfs):
818 for dir in dirs:
819 new_dir = re.sub(r"\.dpkg-new", "", dir)
820 if dir != new_dir:
821 os.rename(os.path.join(root, dir),
822 os.path.join(root, new_dir))
823
824 for file in files:
825 new_file = re.sub(r"\.dpkg-new", "", file)
826 if file != new_file:
827 os.rename(os.path.join(root, file),
828 os.path.join(root, new_file))
829
830
831 def remove(self, pkgs, with_dependencies=True):
832 if not pkgs:
833 return
834
835 if with_dependencies:
836 os.environ['APT_CONFIG'] = self.apt_conf_file
837 cmd = "%s purge %s" % (self.apt_get_cmd, ' '.join(pkgs))
838 else:
839 cmd = "%s --admindir=%s/var/lib/dpkg --instdir=%s" \
840 " -P --force-depends %s" % \
841 (bb.utils.which(os.getenv('PATH'), "dpkg"),
842 self.target_rootfs, self.target_rootfs, ' '.join(pkgs))
843
844 try:
845 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
846 except subprocess.CalledProcessError as e:
847 bb.fatal("Unable to remove packages. Command '%s' "
848 "returned %d:\n%s" % (e.cmd, e.returncode, e.output.decode("utf-8")))
849
850 def write_index(self):
851 self.deploy_dir_lock()
852
853 result = self.indexer.write_index()
854
855 self.deploy_dir_unlock()
856
857 if result is not None:
858 bb.fatal(result)
859
860 def insert_feeds_uris(self, feed_uris, feed_base_paths, feed_archs):
861 if feed_uris == "":
862 return
863
864 sources_conf = os.path.join("%s/etc/apt/sources.list"
865 % self.target_rootfs)
866 arch_list = []
867
868 if feed_archs is None:
869 for arch in self.all_arch_list:
870 if not os.path.exists(os.path.join(self.deploy_dir, arch)):
871 continue
872 arch_list.append(arch)
873 else:
874 arch_list = feed_archs.split()
875
876 feed_uris = self.construct_uris(feed_uris.split(), feed_base_paths.split())
877
878 with open(sources_conf, "w+") as sources_file:
879 for uri in feed_uris:
880 if arch_list:
881 for arch in arch_list:
882 bb.note('Adding dpkg channel at (%s)' % uri)
883 sources_file.write("deb %s/%s ./\n" %
884 (uri, arch))
885 else:
886 bb.note('Adding dpkg channel at (%s)' % uri)
887 sources_file.write("deb %s ./\n" % uri)
888
889 def _create_configs(self, archs, base_archs):
890 base_archs = re.sub(r"_", r"-", base_archs)
891
892 if os.path.exists(self.apt_conf_dir):
893 bb.utils.remove(self.apt_conf_dir, True)
894
895 bb.utils.mkdirhier(self.apt_conf_dir)
896 bb.utils.mkdirhier(self.apt_conf_dir + "/lists/partial/")
897 bb.utils.mkdirhier(self.apt_conf_dir + "/apt.conf.d/")
898 bb.utils.mkdirhier(self.apt_conf_dir + "/preferences.d/")
899
900 arch_list = []
901 for arch in self.all_arch_list:
902 if not os.path.exists(os.path.join(self.deploy_dir, arch)):
903 continue
904 arch_list.append(arch)
905
906 with open(os.path.join(self.apt_conf_dir, "preferences"), "w+") as prefs_file:
907 priority = 801
908 for arch in arch_list:
909 prefs_file.write(
910 "Package: *\n"
911 "Pin: release l=%s\n"
912 "Pin-Priority: %d\n\n" % (arch, priority))
913
914 priority += 5
915
916 pkg_exclude = self.d.getVar('PACKAGE_EXCLUDE') or ""
917 for pkg in pkg_exclude.split():
918 prefs_file.write(
919 "Package: %s\n"
920 "Pin: release *\n"
921 "Pin-Priority: -1\n\n" % pkg)
922
923 arch_list.reverse()
924
925 with open(os.path.join(self.apt_conf_dir, "sources.list"), "w+") as sources_file:
926 for arch in arch_list:
927 sources_file.write("deb file:%s/ ./\n" %
928 os.path.join(self.deploy_dir, arch))
929
930 base_arch_list = base_archs.split()
931 multilib_variants = self.d.getVar("MULTILIB_VARIANTS");
932 for variant in multilib_variants.split():
933 localdata = bb.data.createCopy(self.d)
934 variant_tune = localdata.getVar("DEFAULTTUNE_virtclass-multilib-" + variant, False)
935 orig_arch = localdata.getVar("DPKG_ARCH")
936 localdata.setVar("DEFAULTTUNE", variant_tune)
937 variant_arch = localdata.getVar("DPKG_ARCH")
938 if variant_arch not in base_arch_list:
939 base_arch_list.append(variant_arch)
940
941 with open(self.apt_conf_file, "w+") as apt_conf:
942 with open(self.d.expand("${STAGING_ETCDIR_NATIVE}/apt/apt.conf.sample")) as apt_conf_sample:
943 for line in apt_conf_sample.read().split("\n"):
944 match_arch = re.match(r" Architecture \".*\";$", line)
945 architectures = ""
946 if match_arch:
947 for base_arch in base_arch_list:
948 architectures += "\"%s\";" % base_arch
949 apt_conf.write(" Architectures {%s};\n" % architectures);
950 apt_conf.write(" Architecture \"%s\";\n" % base_archs)
951 else:
952 line = re.sub(r"#ROOTFS#", self.target_rootfs, line)
953 line = re.sub(r"#APTCONF#", self.apt_conf_dir, line)
954 apt_conf.write(line + "\n")
955
956 target_dpkg_dir = "%s/var/lib/dpkg" % self.target_rootfs
957 bb.utils.mkdirhier(os.path.join(target_dpkg_dir, "info"))
958
959 bb.utils.mkdirhier(os.path.join(target_dpkg_dir, "updates"))
960
961 if not os.path.exists(os.path.join(target_dpkg_dir, "status")):
962 open(os.path.join(target_dpkg_dir, "status"), "w+").close()
963 if not os.path.exists(os.path.join(target_dpkg_dir, "available")):
964 open(os.path.join(target_dpkg_dir, "available"), "w+").close()
965
966 def remove_packaging_data(self):
967 bb.utils.remove(self.target_rootfs + self.d.getVar('opkglibdir'), True)
968 bb.utils.remove(self.target_rootfs + "/var/lib/dpkg/", True)
969
970 def fix_broken_dependencies(self):
971 os.environ['APT_CONFIG'] = self.apt_conf_file
972
973 cmd = "%s %s --allow-unauthenticated -f install" % (self.apt_get_cmd, self.apt_args)
974
975 try:
976 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
977 except subprocess.CalledProcessError as e:
978 bb.fatal("Cannot fix broken dependencies. Command '%s' "
979 "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8")))
980
981 def list_installed(self):
982 return DpkgPkgsList(self.d, self.target_rootfs).list_pkgs()
983
984 def package_info(self, pkg):
985 """
986 Returns a dictionary with the package info.
987 """
988 cmd = "%s show %s" % (self.apt_cache_cmd, pkg)
989 pkg_info = super(DpkgPM, self).package_info(pkg, cmd)
990
991 pkg_arch = pkg_info[pkg]["pkgarch"]
992 pkg_filename = pkg_info[pkg]["filename"]
993 pkg_info[pkg]["filepath"] = \
994 os.path.join(self.deploy_dir, pkg_arch, pkg_filename)
995
996 return pkg_info
997
998 def extract(self, pkg):
999 """
1000 Returns the path to a tmpdir where resides the contents of a package.
1001
1002 Deleting the tmpdir is responsability of the caller.
1003 """
1004 pkg_info = self.package_info(pkg)
1005 if not pkg_info:
1006 bb.fatal("Unable to get information for package '%s' while "
1007 "trying to extract the package." % pkg)
1008
1009 tmp_dir = super(DpkgPM, self).extract(pkg, pkg_info)
1010 bb.utils.remove(os.path.join(tmp_dir, "data.tar.xz"))
1011
1012 return tmp_dir
1013 526
1014def generate_index_files(d): 527def generate_index_files(d):
1015 from oe.package_manager.rpm import RpmSubdirIndexer 528 from oe.package_manager.rpm import RpmSubdirIndexer
1016 from oe.package_manager.ipk import OpkgIndexer 529 from oe.package_manager.ipk import OpkgIndexer
530 from oe.package_manager.deb import DpkgIndexer
1017 531
1018 classes = d.getVar('PACKAGE_CLASSES').replace("package_", "").split() 532 classes = d.getVar('PACKAGE_CLASSES').replace("package_", "").split()
1019 533
diff --git a/meta/lib/oe/package_manager/deb/__init__.py b/meta/lib/oe/package_manager/deb/__init__.py
index a2094304c9..3c214e59dd 100644
--- a/meta/lib/oe/package_manager/deb/__init__.py
+++ b/meta/lib/oe/package_manager/deb/__init__.py
@@ -1,3 +1,490 @@
1# 1#
2# SPDX-License-Identifier: GPL-2.0-only 2# SPDX-License-Identifier: GPL-2.0-only
3# 3#
4
5from oe.package_manager import *
6
7class DpkgIndexer(Indexer):
8 def _create_configs(self):
9 bb.utils.mkdirhier(self.apt_conf_dir)
10 bb.utils.mkdirhier(os.path.join(self.apt_conf_dir, "lists", "partial"))
11 bb.utils.mkdirhier(os.path.join(self.apt_conf_dir, "apt.conf.d"))
12 bb.utils.mkdirhier(os.path.join(self.apt_conf_dir, "preferences.d"))
13
14 with open(os.path.join(self.apt_conf_dir, "preferences"),
15 "w") as prefs_file:
16 pass
17 with open(os.path.join(self.apt_conf_dir, "sources.list"),
18 "w+") as sources_file:
19 pass
20
21 with open(self.apt_conf_file, "w") as apt_conf:
22 with open(os.path.join(self.d.expand("${STAGING_ETCDIR_NATIVE}"),
23 "apt", "apt.conf.sample")) as apt_conf_sample:
24 for line in apt_conf_sample.read().split("\n"):
25 line = re.sub(r"#ROOTFS#", "/dev/null", line)
26 line = re.sub(r"#APTCONF#", self.apt_conf_dir, line)
27 apt_conf.write(line + "\n")
28
29 def write_index(self):
30 self.apt_conf_dir = os.path.join(self.d.expand("${APTCONF_TARGET}"),
31 "apt-ftparchive")
32 self.apt_conf_file = os.path.join(self.apt_conf_dir, "apt.conf")
33 self._create_configs()
34
35 os.environ['APT_CONFIG'] = self.apt_conf_file
36
37 pkg_archs = self.d.getVar('PACKAGE_ARCHS')
38 if pkg_archs is not None:
39 arch_list = pkg_archs.split()
40 sdk_pkg_archs = self.d.getVar('SDK_PACKAGE_ARCHS')
41 if sdk_pkg_archs is not None:
42 for a in sdk_pkg_archs.split():
43 if a not in pkg_archs:
44 arch_list.append(a)
45
46 all_mlb_pkg_arch_list = (self.d.getVar('ALL_MULTILIB_PACKAGE_ARCHS') or "").split()
47 arch_list.extend(arch for arch in all_mlb_pkg_arch_list if arch not in arch_list)
48
49 apt_ftparchive = bb.utils.which(os.getenv('PATH'), "apt-ftparchive")
50 gzip = bb.utils.which(os.getenv('PATH'), "gzip")
51
52 index_cmds = []
53 deb_dirs_found = False
54 for arch in arch_list:
55 arch_dir = os.path.join(self.deploy_dir, arch)
56 if not os.path.isdir(arch_dir):
57 continue
58
59 cmd = "cd %s; PSEUDO_UNLOAD=1 %s packages . > Packages;" % (arch_dir, apt_ftparchive)
60
61 cmd += "%s -fcn Packages > Packages.gz;" % gzip
62
63 with open(os.path.join(arch_dir, "Release"), "w+") as release:
64 release.write("Label: %s\n" % arch)
65
66 cmd += "PSEUDO_UNLOAD=1 %s release . >> Release" % apt_ftparchive
67
68 index_cmds.append(cmd)
69
70 deb_dirs_found = True
71
72 if not deb_dirs_found:
73 bb.note("There are no packages in %s" % self.deploy_dir)
74 return
75
76 oe.utils.multiprocess_launch(create_index, index_cmds, self.d)
77 if self.d.getVar('PACKAGE_FEED_SIGN') == '1':
78 raise NotImplementedError('Package feed signing not implementd for dpkg')
79
80class DpkgPkgsList(PkgsList):
81
82 def list_pkgs(self):
83 cmd = [bb.utils.which(os.getenv('PATH'), "dpkg-query"),
84 "--admindir=%s/var/lib/dpkg" % self.rootfs_dir,
85 "-W"]
86
87 cmd.append("-f=Package: ${Package}\nArchitecture: ${PackageArch}\nVersion: ${Version}\nFile: ${Package}_${Version}_${Architecture}.deb\nDepends: ${Depends}\nRecommends: ${Recommends}\nProvides: ${Provides}\n\n")
88
89 try:
90 cmd_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip().decode("utf-8")
91 except subprocess.CalledProcessError as e:
92 bb.fatal("Cannot get the installed packages list. Command '%s' "
93 "returned %d:\n%s" % (' '.join(cmd), e.returncode, e.output.decode("utf-8")))
94
95 return opkg_query(cmd_output)
96
97class OpkgDpkgPM(PackageManager):
98 def __init__(self, d, target_rootfs):
99 """
100 This is an abstract class. Do not instantiate this directly.
101 """
102 super(OpkgDpkgPM, self).__init__(d, target_rootfs)
103
104 def package_info(self, pkg, cmd):
105 """
106 Returns a dictionary with the package info.
107
108 This method extracts the common parts for Opkg and Dpkg
109 """
110
111 try:
112 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode("utf-8")
113 except subprocess.CalledProcessError as e:
114 bb.fatal("Unable to list available packages. Command '%s' "
115 "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8")))
116 return opkg_query(output)
117
118 def extract(self, pkg, pkg_info):
119 """
120 Returns the path to a tmpdir where resides the contents of a package.
121
122 Deleting the tmpdir is responsability of the caller.
123
124 This method extracts the common parts for Opkg and Dpkg
125 """
126
127 ar_cmd = bb.utils.which(os.getenv("PATH"), "ar")
128 tar_cmd = bb.utils.which(os.getenv("PATH"), "tar")
129 pkg_path = pkg_info[pkg]["filepath"]
130
131 if not os.path.isfile(pkg_path):
132 bb.fatal("Unable to extract package for '%s'."
133 "File %s doesn't exists" % (pkg, pkg_path))
134
135 tmp_dir = tempfile.mkdtemp()
136 current_dir = os.getcwd()
137 os.chdir(tmp_dir)
138 data_tar = 'data.tar.xz'
139
140 try:
141 cmd = [ar_cmd, 'x', pkg_path]
142 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
143 cmd = [tar_cmd, 'xf', data_tar]
144 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
145 except subprocess.CalledProcessError as e:
146 bb.utils.remove(tmp_dir, recurse=True)
147 bb.fatal("Unable to extract %s package. Command '%s' "
148 "returned %d:\n%s" % (pkg_path, ' '.join(cmd), e.returncode, e.output.decode("utf-8")))
149 except OSError as e:
150 bb.utils.remove(tmp_dir, recurse=True)
151 bb.fatal("Unable to extract %s package. Command '%s' "
152 "returned %d:\n%s at %s" % (pkg_path, ' '.join(cmd), e.errno, e.strerror, e.filename))
153
154 bb.note("Extracted %s to %s" % (pkg_path, tmp_dir))
155 bb.utils.remove(os.path.join(tmp_dir, "debian-binary"))
156 bb.utils.remove(os.path.join(tmp_dir, "control.tar.gz"))
157 os.chdir(current_dir)
158
159 return tmp_dir
160
161 def _handle_intercept_failure(self, registered_pkgs):
162 self.mark_packages("unpacked", registered_pkgs.split())
163
164class DpkgPM(OpkgDpkgPM):
165 def __init__(self, d, target_rootfs, archs, base_archs, apt_conf_dir=None, deb_repo_workdir="oe-rootfs-repo", filterbydependencies=True):
166 super(DpkgPM, self).__init__(d, target_rootfs)
167 self.deploy_dir = oe.path.join(self.d.getVar('WORKDIR'), deb_repo_workdir)
168
169 create_packages_dir(self.d, self.deploy_dir, d.getVar("DEPLOY_DIR_DEB"), "package_write_deb", filterbydependencies)
170
171 if apt_conf_dir is None:
172 self.apt_conf_dir = self.d.expand("${APTCONF_TARGET}/apt")
173 else:
174 self.apt_conf_dir = apt_conf_dir
175 self.apt_conf_file = os.path.join(self.apt_conf_dir, "apt.conf")
176 self.apt_get_cmd = bb.utils.which(os.getenv('PATH'), "apt-get")
177 self.apt_cache_cmd = bb.utils.which(os.getenv('PATH'), "apt-cache")
178
179 self.apt_args = d.getVar("APT_ARGS")
180
181 self.all_arch_list = archs.split()
182 all_mlb_pkg_arch_list = (self.d.getVar('ALL_MULTILIB_PACKAGE_ARCHS') or "").split()
183 self.all_arch_list.extend(arch for arch in all_mlb_pkg_arch_list if arch not in self.all_arch_list)
184
185 self._create_configs(archs, base_archs)
186
187 self.indexer = DpkgIndexer(self.d, self.deploy_dir)
188
189 def mark_packages(self, status_tag, packages=None):
190 """
191 This function will change a package's status in /var/lib/dpkg/status file.
192 If 'packages' is None then the new_status will be applied to all
193 packages
194 """
195 status_file = self.target_rootfs + "/var/lib/dpkg/status"
196
197 with open(status_file, "r") as sf:
198 with open(status_file + ".tmp", "w+") as tmp_sf:
199 if packages is None:
200 tmp_sf.write(re.sub(r"Package: (.*?)\n((?:[^\n]+\n)*?)Status: (.*)(?:unpacked|installed)",
201 r"Package: \1\n\2Status: \3%s" % status_tag,
202 sf.read()))
203 else:
204 if type(packages).__name__ != "list":
205 raise TypeError("'packages' should be a list object")
206
207 status = sf.read()
208 for pkg in packages:
209 status = re.sub(r"Package: %s\n((?:[^\n]+\n)*?)Status: (.*)(?:unpacked|installed)" % pkg,
210 r"Package: %s\n\1Status: \2%s" % (pkg, status_tag),
211 status)
212
213 tmp_sf.write(status)
214
215 os.rename(status_file + ".tmp", status_file)
216
217 def run_pre_post_installs(self, package_name=None):
218 """
219 Run the pre/post installs for package "package_name". If package_name is
220 None, then run all pre/post install scriptlets.
221 """
222 info_dir = self.target_rootfs + "/var/lib/dpkg/info"
223 ControlScript = collections.namedtuple("ControlScript", ["suffix", "name", "argument"])
224 control_scripts = [
225 ControlScript(".preinst", "Preinstall", "install"),
226 ControlScript(".postinst", "Postinstall", "configure")]
227 status_file = self.target_rootfs + "/var/lib/dpkg/status"
228 installed_pkgs = []
229
230 with open(status_file, "r") as status:
231 for line in status.read().split('\n'):
232 m = re.match(r"^Package: (.*)", line)
233 if m is not None:
234 installed_pkgs.append(m.group(1))
235
236 if package_name is not None and not package_name in installed_pkgs:
237 return
238
239 os.environ['D'] = self.target_rootfs
240 os.environ['OFFLINE_ROOT'] = self.target_rootfs
241 os.environ['IPKG_OFFLINE_ROOT'] = self.target_rootfs
242 os.environ['OPKG_OFFLINE_ROOT'] = self.target_rootfs
243 os.environ['INTERCEPT_DIR'] = self.intercepts_dir
244 os.environ['NATIVE_ROOT'] = self.d.getVar('STAGING_DIR_NATIVE')
245
246 for pkg_name in installed_pkgs:
247 for control_script in control_scripts:
248 p_full = os.path.join(info_dir, pkg_name + control_script.suffix)
249 if os.path.exists(p_full):
250 try:
251 bb.note("Executing %s for package: %s ..." %
252 (control_script.name.lower(), pkg_name))
253 output = subprocess.check_output([p_full, control_script.argument],
254 stderr=subprocess.STDOUT).decode("utf-8")
255 bb.note(output)
256 except subprocess.CalledProcessError as e:
257 bb.warn("%s for package %s failed with %d:\n%s" %
258 (control_script.name, pkg_name, e.returncode,
259 e.output.decode("utf-8")))
260 failed_postinsts_abort([pkg_name], self.d.expand("${T}/log.do_${BB_CURRENTTASK}"))
261
262 def update(self):
263 os.environ['APT_CONFIG'] = self.apt_conf_file
264
265 self.deploy_dir_lock()
266
267 cmd = "%s update" % self.apt_get_cmd
268
269 try:
270 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
271 except subprocess.CalledProcessError as e:
272 bb.fatal("Unable to update the package index files. Command '%s' "
273 "returned %d:\n%s" % (e.cmd, e.returncode, e.output.decode("utf-8")))
274
275 self.deploy_dir_unlock()
276
277 def install(self, pkgs, attempt_only=False):
278 if attempt_only and len(pkgs) == 0:
279 return
280
281 os.environ['APT_CONFIG'] = self.apt_conf_file
282
283 cmd = "%s %s install --force-yes --allow-unauthenticated --no-remove %s" % \
284 (self.apt_get_cmd, self.apt_args, ' '.join(pkgs))
285
286 try:
287 bb.note("Installing the following packages: %s" % ' '.join(pkgs))
288 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
289 except subprocess.CalledProcessError as e:
290 (bb.fatal, bb.warn)[attempt_only]("Unable to install packages. "
291 "Command '%s' returned %d:\n%s" %
292 (cmd, e.returncode, e.output.decode("utf-8")))
293
294 # rename *.dpkg-new files/dirs
295 for root, dirs, files in os.walk(self.target_rootfs):
296 for dir in dirs:
297 new_dir = re.sub(r"\.dpkg-new", "", dir)
298 if dir != new_dir:
299 os.rename(os.path.join(root, dir),
300 os.path.join(root, new_dir))
301
302 for file in files:
303 new_file = re.sub(r"\.dpkg-new", "", file)
304 if file != new_file:
305 os.rename(os.path.join(root, file),
306 os.path.join(root, new_file))
307
308
309 def remove(self, pkgs, with_dependencies=True):
310 if not pkgs:
311 return
312
313 if with_dependencies:
314 os.environ['APT_CONFIG'] = self.apt_conf_file
315 cmd = "%s purge %s" % (self.apt_get_cmd, ' '.join(pkgs))
316 else:
317 cmd = "%s --admindir=%s/var/lib/dpkg --instdir=%s" \
318 " -P --force-depends %s" % \
319 (bb.utils.which(os.getenv('PATH'), "dpkg"),
320 self.target_rootfs, self.target_rootfs, ' '.join(pkgs))
321
322 try:
323 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
324 except subprocess.CalledProcessError as e:
325 bb.fatal("Unable to remove packages. Command '%s' "
326 "returned %d:\n%s" % (e.cmd, e.returncode, e.output.decode("utf-8")))
327
328 def write_index(self):
329 self.deploy_dir_lock()
330
331 result = self.indexer.write_index()
332
333 self.deploy_dir_unlock()
334
335 if result is not None:
336 bb.fatal(result)
337
338 def insert_feeds_uris(self, feed_uris, feed_base_paths, feed_archs):
339 if feed_uris == "":
340 return
341
342 sources_conf = os.path.join("%s/etc/apt/sources.list"
343 % self.target_rootfs)
344 arch_list = []
345
346 if feed_archs is None:
347 for arch in self.all_arch_list:
348 if not os.path.exists(os.path.join(self.deploy_dir, arch)):
349 continue
350 arch_list.append(arch)
351 else:
352 arch_list = feed_archs.split()
353
354 feed_uris = self.construct_uris(feed_uris.split(), feed_base_paths.split())
355
356 with open(sources_conf, "w+") as sources_file:
357 for uri in feed_uris:
358 if arch_list:
359 for arch in arch_list:
360 bb.note('Adding dpkg channel at (%s)' % uri)
361 sources_file.write("deb %s/%s ./\n" %
362 (uri, arch))
363 else:
364 bb.note('Adding dpkg channel at (%s)' % uri)
365 sources_file.write("deb %s ./\n" % uri)
366
367 def _create_configs(self, archs, base_archs):
368 base_archs = re.sub(r"_", r"-", base_archs)
369
370 if os.path.exists(self.apt_conf_dir):
371 bb.utils.remove(self.apt_conf_dir, True)
372
373 bb.utils.mkdirhier(self.apt_conf_dir)
374 bb.utils.mkdirhier(self.apt_conf_dir + "/lists/partial/")
375 bb.utils.mkdirhier(self.apt_conf_dir + "/apt.conf.d/")
376 bb.utils.mkdirhier(self.apt_conf_dir + "/preferences.d/")
377
378 arch_list = []
379 for arch in self.all_arch_list:
380 if not os.path.exists(os.path.join(self.deploy_dir, arch)):
381 continue
382 arch_list.append(arch)
383
384 with open(os.path.join(self.apt_conf_dir, "preferences"), "w+") as prefs_file:
385 priority = 801
386 for arch in arch_list:
387 prefs_file.write(
388 "Package: *\n"
389 "Pin: release l=%s\n"
390 "Pin-Priority: %d\n\n" % (arch, priority))
391
392 priority += 5
393
394 pkg_exclude = self.d.getVar('PACKAGE_EXCLUDE') or ""
395 for pkg in pkg_exclude.split():
396 prefs_file.write(
397 "Package: %s\n"
398 "Pin: release *\n"
399 "Pin-Priority: -1\n\n" % pkg)
400
401 arch_list.reverse()
402
403 with open(os.path.join(self.apt_conf_dir, "sources.list"), "w+") as sources_file:
404 for arch in arch_list:
405 sources_file.write("deb file:%s/ ./\n" %
406 os.path.join(self.deploy_dir, arch))
407
408 base_arch_list = base_archs.split()
409 multilib_variants = self.d.getVar("MULTILIB_VARIANTS");
410 for variant in multilib_variants.split():
411 localdata = bb.data.createCopy(self.d)
412 variant_tune = localdata.getVar("DEFAULTTUNE_virtclass-multilib-" + variant, False)
413 orig_arch = localdata.getVar("DPKG_ARCH")
414 localdata.setVar("DEFAULTTUNE", variant_tune)
415 variant_arch = localdata.getVar("DPKG_ARCH")
416 if variant_arch not in base_arch_list:
417 base_arch_list.append(variant_arch)
418
419 with open(self.apt_conf_file, "w+") as apt_conf:
420 with open(self.d.expand("${STAGING_ETCDIR_NATIVE}/apt/apt.conf.sample")) as apt_conf_sample:
421 for line in apt_conf_sample.read().split("\n"):
422 match_arch = re.match(r" Architecture \".*\";$", line)
423 architectures = ""
424 if match_arch:
425 for base_arch in base_arch_list:
426 architectures += "\"%s\";" % base_arch
427 apt_conf.write(" Architectures {%s};\n" % architectures);
428 apt_conf.write(" Architecture \"%s\";\n" % base_archs)
429 else:
430 line = re.sub(r"#ROOTFS#", self.target_rootfs, line)
431 line = re.sub(r"#APTCONF#", self.apt_conf_dir, line)
432 apt_conf.write(line + "\n")
433
434 target_dpkg_dir = "%s/var/lib/dpkg" % self.target_rootfs
435 bb.utils.mkdirhier(os.path.join(target_dpkg_dir, "info"))
436
437 bb.utils.mkdirhier(os.path.join(target_dpkg_dir, "updates"))
438
439 if not os.path.exists(os.path.join(target_dpkg_dir, "status")):
440 open(os.path.join(target_dpkg_dir, "status"), "w+").close()
441 if not os.path.exists(os.path.join(target_dpkg_dir, "available")):
442 open(os.path.join(target_dpkg_dir, "available"), "w+").close()
443
444 def remove_packaging_data(self):
445 bb.utils.remove(self.target_rootfs + self.d.getVar('opkglibdir'), True)
446 bb.utils.remove(self.target_rootfs + "/var/lib/dpkg/", True)
447
448 def fix_broken_dependencies(self):
449 os.environ['APT_CONFIG'] = self.apt_conf_file
450
451 cmd = "%s %s --allow-unauthenticated -f install" % (self.apt_get_cmd, self.apt_args)
452
453 try:
454 subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
455 except subprocess.CalledProcessError as e:
456 bb.fatal("Cannot fix broken dependencies. Command '%s' "
457 "returned %d:\n%s" % (cmd, e.returncode, e.output.decode("utf-8")))
458
459 def list_installed(self):
460 return DpkgPkgsList(self.d, self.target_rootfs).list_pkgs()
461
462 def package_info(self, pkg):
463 """
464 Returns a dictionary with the package info.
465 """
466 cmd = "%s show %s" % (self.apt_cache_cmd, pkg)
467 pkg_info = super(DpkgPM, self).package_info(pkg, cmd)
468
469 pkg_arch = pkg_info[pkg]["pkgarch"]
470 pkg_filename = pkg_info[pkg]["filename"]
471 pkg_info[pkg]["filepath"] = \
472 os.path.join(self.deploy_dir, pkg_arch, pkg_filename)
473
474 return pkg_info
475
476 def extract(self, pkg):
477 """
478 Returns the path to a tmpdir where resides the contents of a package.
479
480 Deleting the tmpdir is responsability of the caller.
481 """
482 pkg_info = self.package_info(pkg)
483 if not pkg_info:
484 bb.fatal("Unable to get information for package '%s' while "
485 "trying to extract the package." % pkg)
486
487 tmp_dir = super(DpkgPM, self).extract(pkg, pkg_info)
488 bb.utils.remove(os.path.join(tmp_dir, "data.tar.xz"))
489
490 return tmp_dir
diff --git a/meta/lib/oe/package_manager/deb/rootfs.py b/meta/lib/oe/package_manager/deb/rootfs.py
index 0661ee7c5b..ac229f63d7 100644
--- a/meta/lib/oe/package_manager/deb/rootfs.py
+++ b/meta/lib/oe/package_manager/deb/rootfs.py
@@ -3,11 +3,11 @@
3# 3#
4 4
5from oe.rootfs import Rootfs 5from oe.rootfs import Rootfs
6from oe.package_manager import DpkgPM
7from oe.manifest import Manifest 6from oe.manifest import Manifest
8from oe.utils import execute_pre_post_process 7from oe.utils import execute_pre_post_process
9from oe.package_manager.deb.manifest import DpkgManifest 8from oe.package_manager.deb.manifest import DpkgManifest
10import re 9import re
10from oe.package_manager.deb import DpkgPM
11 11
12class DpkgOpkgRootfs(Rootfs): 12class DpkgOpkgRootfs(Rootfs):
13 def __init__(self, d, progress_reporter=None, logcatcher=None): 13 def __init__(self, d, progress_reporter=None, logcatcher=None):
diff --git a/meta/lib/oe/package_manager/deb/sdk.py b/meta/lib/oe/package_manager/deb/sdk.py
index aafcd259e5..3876f9b683 100644
--- a/meta/lib/oe/package_manager/deb/sdk.py
+++ b/meta/lib/oe/package_manager/deb/sdk.py
@@ -5,7 +5,7 @@
5from oe.utils import execute_pre_post_process 5from oe.utils import execute_pre_post_process
6from oe.sdk import Sdk 6from oe.sdk import Sdk
7from oe.manifest import Manifest 7from oe.manifest import Manifest
8from oe.package_manager import DpkgPM 8from oe.package_manager.deb import DpkgPM
9import shutil 9import shutil
10 10
11class DpkgSdk(Sdk): 11class DpkgSdk(Sdk):
diff --git a/meta/lib/oe/rootfs.py b/meta/lib/oe/rootfs.py
index 60c1e00a3d..3813f68e8b 100644
--- a/meta/lib/oe/rootfs.py
+++ b/meta/lib/oe/rootfs.py
@@ -15,6 +15,7 @@ from oe.package_manager.ipk.manifest import OpkgManifest
15from oe.package_manager.deb.manifest import DpkgManifest 15from oe.package_manager.deb.manifest import DpkgManifest
16from oe.package_manager.rpm import RpmPkgsList 16from oe.package_manager.rpm import RpmPkgsList
17from oe.package_manager.ipk import OpkgPkgsList 17from oe.package_manager.ipk import OpkgPkgsList
18from oe.package_manager.deb import DpkgPkgsList
18 19
19class Rootfs(object, metaclass=ABCMeta): 20class Rootfs(object, metaclass=ABCMeta):
20 """ 21 """
diff --git a/meta/lib/oe/sdk.py b/meta/lib/oe/sdk.py
index ce98f80f18..49f519891f 100644
--- a/meta/lib/oe/sdk.py
+++ b/meta/lib/oe/sdk.py
@@ -119,6 +119,7 @@ def sdk_list_installed_packages(d, target, rootfs_dir=None):
119 119
120 from oe.package_manager.rpm import RpmPkgsList 120 from oe.package_manager.rpm import RpmPkgsList
121 from oe.package_manager.ipk import OpkgPkgsList 121 from oe.package_manager.ipk import OpkgPkgsList
122 from oe.package_manager.deb import DpkgPkgsList
122 img_type = d.getVar('IMAGE_PKGTYPE') 123 img_type = d.getVar('IMAGE_PKGTYPE')
123 if img_type == "rpm": 124 if img_type == "rpm":
124 arch_var = ["SDK_PACKAGE_ARCHS", None][target is True] 125 arch_var = ["SDK_PACKAGE_ARCHS", None][target is True]
diff --git a/meta/lib/oeqa/utils/package_manager.py b/meta/lib/oeqa/utils/package_manager.py
index 9998d01ebc..3623299295 100644
--- a/meta/lib/oeqa/utils/package_manager.py
+++ b/meta/lib/oeqa/utils/package_manager.py
@@ -12,10 +12,9 @@ def get_package_manager(d, root_path):
12 """ 12 """
13 Returns an OE package manager that can install packages in root_path. 13 Returns an OE package manager that can install packages in root_path.
14 """ 14 """
15 from oe.package_manager import DpkgPM
16 from oe.package_manager.rpm import RpmPM 15 from oe.package_manager.rpm import RpmPM
17 from oe.package_manager.ipk import OpkgPM 16 from oe.package_manager.ipk import OpkgPM
18 17 from oe.package_manager.deb import DpkgPM
19 18
20 pkg_class = d.getVar("IMAGE_PKGTYPE") 19 pkg_class = d.getVar("IMAGE_PKGTYPE")
21 if pkg_class == "rpm": 20 if pkg_class == "rpm":