blob: 1a058dcd7341bdcc9c7f003cbff4187f7d0b7188 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: GPL-2.0-only
3#
4
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005from abc import ABCMeta, abstractmethod
6import os
7import re
8import bb
9
Patrick Williamsc0f7c042017-02-23 20:41:17 -060010class Manifest(object, metaclass=ABCMeta):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011 """
12 This is an abstract class. Do not instantiate this directly.
13 """
Patrick Williamsc124f4f2015-09-15 14:41:29 -050014
15 PKG_TYPE_MUST_INSTALL = "mip"
16 PKG_TYPE_MULTILIB = "mlp"
17 PKG_TYPE_LANGUAGE = "lgp"
18 PKG_TYPE_ATTEMPT_ONLY = "aop"
19
20 MANIFEST_TYPE_IMAGE = "image"
21 MANIFEST_TYPE_SDK_HOST = "sdk_host"
22 MANIFEST_TYPE_SDK_TARGET = "sdk_target"
23
24 var_maps = {
25 MANIFEST_TYPE_IMAGE: {
26 "PACKAGE_INSTALL": PKG_TYPE_MUST_INSTALL,
27 "PACKAGE_INSTALL_ATTEMPTONLY": PKG_TYPE_ATTEMPT_ONLY,
28 "LINGUAS_INSTALL": PKG_TYPE_LANGUAGE
29 },
30 MANIFEST_TYPE_SDK_HOST: {
31 "TOOLCHAIN_HOST_TASK": PKG_TYPE_MUST_INSTALL,
32 "TOOLCHAIN_HOST_TASK_ATTEMPTONLY": PKG_TYPE_ATTEMPT_ONLY
33 },
34 MANIFEST_TYPE_SDK_TARGET: {
35 "TOOLCHAIN_TARGET_TASK": PKG_TYPE_MUST_INSTALL,
36 "TOOLCHAIN_TARGET_TASK_ATTEMPTONLY": PKG_TYPE_ATTEMPT_ONLY
37 }
38 }
39
40 INSTALL_ORDER = [
41 PKG_TYPE_LANGUAGE,
42 PKG_TYPE_MUST_INSTALL,
43 PKG_TYPE_ATTEMPT_ONLY,
44 PKG_TYPE_MULTILIB
45 ]
46
47 initial_manifest_file_header = \
48 "# This file was generated automatically and contains the packages\n" \
49 "# passed on to the package manager in order to create the rootfs.\n\n" \
50 "# Format:\n" \
51 "# <package_type>,<package_name>\n" \
52 "# where:\n" \
53 "# <package_type> can be:\n" \
54 "# 'mip' = must install package\n" \
55 "# 'aop' = attempt only package\n" \
56 "# 'mlp' = multilib package\n" \
57 "# 'lgp' = language package\n\n"
58
59 def __init__(self, d, manifest_dir=None, manifest_type=MANIFEST_TYPE_IMAGE):
60 self.d = d
61 self.manifest_type = manifest_type
62
63 if manifest_dir is None:
64 if manifest_type != self.MANIFEST_TYPE_IMAGE:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050065 self.manifest_dir = self.d.getVar('SDK_DIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050067 self.manifest_dir = self.d.getVar('WORKDIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050068 else:
69 self.manifest_dir = manifest_dir
70
71 bb.utils.mkdirhier(self.manifest_dir)
72
73 self.initial_manifest = os.path.join(self.manifest_dir, "%s_initial_manifest" % manifest_type)
74 self.final_manifest = os.path.join(self.manifest_dir, "%s_final_manifest" % manifest_type)
75 self.full_manifest = os.path.join(self.manifest_dir, "%s_full_manifest" % manifest_type)
76
77 # packages in the following vars will be split in 'must install' and
78 # 'multilib'
79 self.vars_to_split = ["PACKAGE_INSTALL",
80 "TOOLCHAIN_HOST_TASK",
81 "TOOLCHAIN_TARGET_TASK"]
82
83 """
84 This creates a standard initial manifest for core-image-(minimal|sato|sato-sdk).
85 This will be used for testing until the class is implemented properly!
86 """
87 def _create_dummy_initial(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050088 image_rootfs = self.d.getVar('IMAGE_ROOTFS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050089 pkg_list = dict()
90 if image_rootfs.find("core-image-sato-sdk") > 0:
91 pkg_list[self.PKG_TYPE_MUST_INSTALL] = \
92 "packagegroup-core-x11-sato-games packagegroup-base-extended " \
93 "packagegroup-core-x11-sato packagegroup-core-x11-base " \
94 "packagegroup-core-sdk packagegroup-core-tools-debug " \
95 "packagegroup-core-boot packagegroup-core-tools-testapps " \
96 "packagegroup-core-eclipse-debug packagegroup-core-qt-demoapps " \
97 "apt packagegroup-core-tools-profile psplash " \
98 "packagegroup-core-standalone-sdk-target " \
99 "packagegroup-core-ssh-openssh dpkg kernel-dev"
100 pkg_list[self.PKG_TYPE_LANGUAGE] = \
101 "locale-base-en-us locale-base-en-gb"
102 elif image_rootfs.find("core-image-sato") > 0:
103 pkg_list[self.PKG_TYPE_MUST_INSTALL] = \
104 "packagegroup-core-ssh-dropbear packagegroup-core-x11-sato-games " \
105 "packagegroup-core-x11-base psplash apt dpkg packagegroup-base-extended " \
106 "packagegroup-core-x11-sato packagegroup-core-boot"
107 pkg_list['lgp'] = \
108 "locale-base-en-us locale-base-en-gb"
109 elif image_rootfs.find("core-image-minimal") > 0:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500110 pkg_list[self.PKG_TYPE_MUST_INSTALL] = "packagegroup-core-boot"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111
112 with open(self.initial_manifest, "w+") as manifest:
113 manifest.write(self.initial_manifest_file_header)
114
115 for pkg_type in pkg_list:
116 for pkg in pkg_list[pkg_type].split():
117 manifest.write("%s,%s\n" % (pkg_type, pkg))
118
119 """
120 This will create the initial manifest which will be used by Rootfs class to
121 generate the rootfs
122 """
123 @abstractmethod
124 def create_initial(self):
125 pass
126
127 """
128 This creates the manifest after everything has been installed.
129 """
130 @abstractmethod
131 def create_final(self):
132 pass
133
134 """
135 This creates the manifest after the package in initial manifest has been
136 dummy installed. It lists all *to be installed* packages. There is no real
137 installation, just a test.
138 """
139 @abstractmethod
140 def create_full(self, pm):
141 pass
142
143 """
144 The following function parses an initial manifest and returns a dictionary
145 object with the must install, attempt only, multilib and language packages.
146 """
147 def parse_initial_manifest(self):
148 pkgs = dict()
149
150 with open(self.initial_manifest) as manifest:
151 for line in manifest.read().split('\n'):
152 comment = re.match("^#.*", line)
153 pattern = "^(%s|%s|%s|%s),(.*)$" % \
154 (self.PKG_TYPE_MUST_INSTALL,
155 self.PKG_TYPE_ATTEMPT_ONLY,
156 self.PKG_TYPE_MULTILIB,
157 self.PKG_TYPE_LANGUAGE)
158 pkg = re.match(pattern, line)
159
160 if comment is not None:
161 continue
162
163 if pkg is not None:
164 pkg_type = pkg.group(1)
165 pkg_name = pkg.group(2)
166
167 if not pkg_type in pkgs:
168 pkgs[pkg_type] = [pkg_name]
169 else:
170 pkgs[pkg_type].append(pkg_name)
171
172 return pkgs
173
174 '''
175 This following function parses a full manifest and return a list
176 object with packages.
177 '''
178 def parse_full_manifest(self):
179 installed_pkgs = list()
180 if not os.path.exists(self.full_manifest):
181 bb.note('full manifest not exist')
182 return installed_pkgs
183
184 with open(self.full_manifest, 'r') as manifest:
185 for pkg in manifest.read().split('\n'):
186 installed_pkgs.append(pkg.strip())
187
188 return installed_pkgs
189
190
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500191
192def create_manifest(d, final_manifest=False, manifest_dir=None,
193 manifest_type=Manifest.MANIFEST_TYPE_IMAGE):
Andrew Geissler6ce62a22020-11-30 19:58:47 -0600194 import importlib
195 manifest = importlib.import_module('oe.package_manager.' + d.getVar('IMAGE_PKGTYPE') + '.manifest').PkgManifest(d, manifest_dir, manifest_type)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500196
197 if final_manifest:
198 manifest.create_final()
199 else:
200 manifest.create_initial()
201
202
203if __name__ == "__main__":
204 pass