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