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