1# 2# Copyright OpenEmbedded Contributors 3# 4# SPDX-License-Identifier: GPL-2.0-only 5# 6 7from abc import ABCMeta, abstractmethod 8import os 9import re 10import bb 11 12class Manifest(object, metaclass=ABCMeta): 13 """ 14 This is an abstract class. Do not instantiate this directly. 15 """ 16 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: 67 self.manifest_dir = self.d.getVar('SDK_DIR') 68 else: 69 self.manifest_dir = self.d.getVar('WORKDIR') 70 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): 90 image_rootfs = self.d.getVar('IMAGE_ROOTFS') 91 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: 112 pkg_list[self.PKG_TYPE_MUST_INSTALL] = "packagegroup-core-boot" 113 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 193 194def create_manifest(d, final_manifest=False, manifest_dir=None, 195 manifest_type=Manifest.MANIFEST_TYPE_IMAGE): 196 import importlib 197 manifest = importlib.import_module('oe.package_manager.' + d.getVar('IMAGE_PKGTYPE') + '.manifest').PkgManifest(d, manifest_dir, manifest_type) 198 199 if final_manifest: 200 manifest.create_final() 201 else: 202 manifest.create_initial() 203 204 205if __name__ == "__main__": 206 pass 207