from abc import ABCMeta, abstractmethod
import os
import glob
import subprocess
import shutil
import multiprocessing
import re
import bb
# this can be used by all PM backends to create the index files in parallel
def create_index(arg):
index_cmd = arg
try:
bb.note("Executing '%s' ..." % index_cmd)
subprocess.check_output(index_cmd, shell=True)
except subprocess.CalledProcessError as e:
return("Index creation command '%s' failed with return code %d:\n%s" %
(e.cmd, e.returncode, e.output))
return None
class PackageManager(object):
"""
This is an abstract class. Do not instantiate this directly.
"""
__metaclass__ = ABCMeta
def __init__(self, d):
self.d = d
self.deploy_dir = None
self.deploy_lock = None
"""
Update the package manager package database.
"""
@abstractmethod
def update(self):
pass
"""
Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is
True, installation failures are ignored.
"""
@abstractmethod
def install(self, pkgs, attempt_only=False):
pass
"""
Remove a list of packages. 'pkgs' is a list object. If 'with_dependencies'
is False, the any dependencies are left in place.
"""
@abstractmethod
def remove(self, pkgs, with_dependencies=True):
pass
"""
This function creates the index files
"""
@abstractmethod
def write_index(self):
pass
@abstractmethod
def remove_packaging_data(self):
pass
@abstractmethod
def list_installed(self, format=None):
pass
"""
Install complementary packages based upon the list of currently installed
packages e.g. locales, *-dev, *-dbg, etc. This will only attempt to install
these packages, if they don't exist then no error will occur. Note: every
backend needs to call this function explicitly after the normal package
installation
"""
def install_complementary(self, globs=None):
# we need to write the list of installed packages to a file because the
# oe-pkgdata-util reads it from a file
installed_pkgs_file = os.path.join(self.d.getVar('WORKDIR', True),
"installed_pkgs.txt")
with open(installed_pkgs_file, "w+") as installed_pkgs:
installed_pkgs.write(self.list_installed("arch"))
if globs is None:
globs = self.d.getVar('IMAGE_INSTALL_COMPLEMENTARY', True)
split_linguas = set()
for translation in self.d.getVar('IMAGE_LINGUAS', True).split():
split_linguas.add(translation)
split_linguas.add(translation.split('-')[0])
split_linguas = sorted(split_linguas)
for lang in split_linguas:
globs += " *-locale-%s" % lang
if globs is None:
return
cmd = [bb.utils.which(os.getenv('PATH'), "oe-pkgdata-util"),
"glob", self.d.getVar('PKGDATA_DIR', True), installed_pkgs_file,
globs]
try:
bb.note("Installing complementary packages ...")
complementary_pkgs = subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
bb.fatal("Could not compute complementary packages list. Command "
"'%s' returned %d:\n%s" %
(' '.join(cmd), e.returncode, e.output))
self.install(complementary_pkgs.split(), attempt_only=True)
def deploy_dir_lock(self):
if self.deploy_dir is None:
raise RuntimeError("deploy_dir is not set!")
lock_file_name = os.path.join(self.deploy_dir, "deploy.lock")
self
|