aboutsummaryrefslogtreecommitdiffstats
path: root/lib/swupd/bundles.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/swupd/bundles.py')
-rw-r--r--lib/swupd/bundles.py194
1 files changed, 47 insertions, 147 deletions
diff --git a/lib/swupd/bundles.py b/lib/swupd/bundles.py
index 3b8be32..c75347b 100644
--- a/lib/swupd/bundles.py
+++ b/lib/swupd/bundles.py
@@ -42,145 +42,62 @@ def get_bundle_packages(d, bundle):
return pkgs
+def create_content_manifest(dir, outfile, blacklist):
+ """
+ Iterate over the content of the directory, remove entries listed in the blacklist
+ (for example, /etc/machine-id), and write the full paths of the remaining
+ entries (without leading ./ or /) to the file named in outfile. All directories
+ are explicitly listed.
+ """
+ bb.debug(3, 'Creating %s from directory %s, excluding %s' % (outfile, dir, blacklist))
+ cwd = os.getcwd()
+ try:
+ os.chdir(dir)
+ with open(outfile, 'w') as f:
+ for root, dirs, files in os.walk('.'):
+ for entry in dirs + files:
+ # strip the leading ./
+ fullpath = os.path.join(root, entry)[2:]
+ if not ('/' + fullpath) in blacklist:
+ f.write(fullpath + '\n')
+ finally:
+ os.chdir(cwd)
+
+
def copy_core_contents(d):
"""
- Copy the os-core contents from the mega image to swupd's image directory
+ Determine the os-core contents and copy the mega image to swupd's image directory.
d -- the bitbake datastore
"""
- outfile = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/${SWUPD_ROOTFS_MANIFEST}')
- bundledir = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/${BUNDLE_NAME}/')
+ corefile = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/os-core${SWUPD_ROOTFS_MANIFEST_SUFFIX}')
+ fullfile = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/full${SWUPD_ROOTFS_MANIFEST_SUFFIX}')
+ bundledir = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/full/')
rootfs = d.getVar('IMAGE_ROOTFS', True)
- # Generate a manifest of the bundle contents for pruning
+ # Generate a manifest of the bundle content.
bb.utils.mkdirhier(bundledir)
- manifest_cmd = 'cd %s && find . ! -path . > %s' % (rootfs, outfile)
- subprocess.call(manifest_cmd, shell=True, stderr=subprocess.STDOUT)
-
- manifest_files = swupd.utils.manifest_to_file_list(outfile)
- bundle_file_contents = []
- # Don't copy files which should not be included in the swupd manifests
unwanted_files = (d.getVar('SWUPD_FILE_BLACKLIST', True) or '').split()
- # The manifest files have a leading . before the /
- for f in manifest_files:
- if f[1:] not in unwanted_files:
- bundle_file_contents.append(f[2:])
- bb.debug(1, 'os-core contains %s items' % len(bundle_file_contents))
+ create_content_manifest(rootfs, corefile, unwanted_files)
+
havebundles = (d.getVar('SWUPD_BUNDLES', True) or '') != ''
imgrootfs = d.getVar('MEGA_IMAGE_ROOTFS', True)
if not havebundles:
imgrootfs = rootfs
- bb.debug(1, "Copying from image (%s) to os-core bundle dir (%s)" % (imgrootfs, bundledir))
- swupd.path.copyxattrfiles(d, bundle_file_contents, imgrootfs, bundledir)
-
-
-def stage_package_bundle_contents(d, bundle):
- """
- stage the contents of a bundle using the package manager
-
- For each bundle we have already included their contents in the mega-image,
- thus we should be able to determine which packages were generated for that
- bundles features and contents through the generated dependency data. Thus:
- 1) determine the package manager and instantiate a PM object
- 2) collect a list of package names for each bundle
- 3) install the packages for the bundle into:
- ${SWUPDIMAGEDIR}/${OS_VERSION}/$bndl
-
- d -- the bitbake datastore
- bundle -- the name of the bundle to be staged
- """
- bb.debug(1, 'Staging bundle contents for %s' % bundle)
- dest = d.expand("${SWUPDIMAGEDIR}/${OS_VERSION}/%s/" % bundle)
- pm = swupd.utils.get_package_manager(d, dest)
-
- pkgs = get_bundle_packages(d, bundle)
- pm.install(pkgs)
- # We don't want package manager artefacts left in the bundle 'chroot'
- pm.remove_packaging_data()
- # Remove any empty directories installed by the package manager, so as not
- # to pollute the 'chroot'
- swupd.path.remove_empty_directories(dest)
-
- # Create the swupd bundle manifest
- create_bundle_manifest(d, bundle, dest)
-
- # Generate a manifest of files in the bundle
- imagename = d.getVar('PN_BASE', True)
- if not imagename:
- imagename = d.getVar('IMAGE_BASENAME', True)
- manfile = d.expand("${SWUPDIMAGEDIR}/${OS_VERSION}/bundle-%s-%s${SWUPD_ROOTFS_MANIFEST_SUFFIX}") % (imagename, bundle)
- bb.debug(3, 'Writing bundle file manifest %s' % manfile)
- cmd = 'cd %s && find . ! -path . > %s' % (dest, manfile)
- subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
-
- # Generate a manifest of packages in the bundle, we need this so that we
- # can compose a complete list of packages installed in any bundle images
- mandir = d.getVar('SWUPDMANIFESTDIR', True)
- manf = d.expand('${IMAGE_NAME}.rootfs.manifest')
- manf = manf.replace(imagename, 'bundle-%s-%s' % (imagename, bundle))
- manfile = mandir + '/' + manf
- bb.debug(3, 'Writing bundle package manifest %s' % manfile)
- installed = image_list_installed_packages(d, dest)
- with open(manfile, 'w+') as manifest:
- manifest.write(format_pkg_list(installed, "ver"))
- manifest.write('\n')
-
- # Also write the manifest symlink
- if os.path.exists(manfile):
- deploy_dir = d.getVar('DEPLOY_DIR_IMAGE', True)
- link_name = d.getVar('IMAGE_LINK_NAME', True)
- manifest_link = deploy_dir + '/' + link_name + '.manifest'
- if os.path.lexists(manifest_link):
- if d.getVar('RM_OLD_IMAGE', True) == "1" and \
- os.path.exists(os.path.realpath(manifest_link)):
- os.remove(os.path.realpath(manifest_link))
- os.remove(manifest_link)
- bb.debug(3, 'Linking bundle package manifest from %s to %s' % (manfile, manifest_link))
- os.symlink(os.path.basename(manfile), manifest_link)
-
-
-def recopy_package_bundle_contents(d, bundle):
- """
- recopy the contents of a bundle from the mega image rootfs
-
- d -- the bitbake datastore
- bundle -- the name of the bundle to be staged
- """
- bb.debug(2, 'Re-copying files for package based bundle %s' % bundle)
- bundlecontents = []
- bundlebase = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/')
- bundledir = bundlebase + bundle
- bb.debug(3, 'Scanning %s for bundle files' % bundledir)
+ manifest_files = swupd.utils.manifest_to_file_list(corefile)
+ with open(fullfile, 'w') as f:
+ f.write('\n'.join(manifest_files))
+ else:
+ create_content_manifest(imgrootfs, fullfile, unwanted_files)
+ manifest_files = swupd.utils.manifest_to_file_list(fullfile)
- # Don't copy files which should not be included in the swupd manifests
- unwanted_files = (d.getVar('SWUPD_FILE_BLACKLIST', True) or '').split()
- def add_target_to_contents(root, file):
- # Compose a full path to the file
- tgt = os.path.join(root, file)
- # then strip out the prefix so it's just the target path
- tgt = tgt.replace(bundledir, '')
- if tgt not in unwanted_files:
- bundlecontents.append(tgt)
-
- for root, directories, files in os.walk(bundledir):
- for file in files:
- add_target_to_contents(root, file)
- for dir in directories:
- add_target_to_contents(root, dir)
-
- bundle_files = swupd.utils.sanitise_file_list(bundlecontents)
-
- # remove the current file contents of the bundle directory
- bb.debug(2, 'About to rm %s' % bundledir)
- oe.path.remove(bundledir)
- # copy over the required files from the megarootfs
- megarootfs = d.getVar('MEGA_IMAGE_ROOTFS', True)
- swupd.path.copyxattrfiles(d, bundle_files, megarootfs, bundledir)
+ bb.debug(1, "Copying from image (%s) to full bundle dir (%s)" % (imgrootfs, bundledir))
+ swupd.path.copyxattrfiles(d, manifest_files, imgrootfs, bundledir)
-def copy_image_bundle_contents(d, bundle):
+def stage_image_bundle_contents(d, bundle):
"""
- Copy bundle contents which aren't part of os-core from the mega-image rootfs
+ Determine bundle contents which aren't part of os-core from the mega-image rootfs
For an image-based bundle, generate a list of files which exist in the
bundle but not os-core and stage those files from the mega image rootfs to
@@ -189,35 +106,23 @@ def copy_image_bundle_contents(d, bundle):
d -- the bitbake datastore
bundle -- the name of the bundle to be staged
"""
- bb.debug(2, 'Re-copying files for image based bundle %s' % bundle)
# Construct paths to manifest files and directories
pn = d.getVar('PN', True)
manifest_path = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/')
- base_manifest_name = d.getVar('SWUPD_ROOTFS_MANIFEST', True)
- image_manifest_name = base_manifest_name.replace(pn, 'bundle-%s-%s' % (pn, bundle))
+ base_manifest_name = d.expand('os-core${SWUPD_ROOTFS_MANIFEST_SUFFIX}')
+ image_manifest_name = base_manifest_name.replace('os-core', bundle, 1)
base_manifest = manifest_path + base_manifest_name
image_manifest = manifest_path + image_manifest_name
megarootfs = d.getVar('MEGA_IMAGE_ROOTFS', True)
imagesrc = megarootfs.replace('mega', bundle)
- # Generate the manifest of the bundle image's file contents
+ # Generate the manifest of the bundle image's file contents,
+ # excluding blacklisted files and the content of the os-core.
bb.debug(3, 'Writing bundle image file manifest %s' % image_manifest)
- cmd = 'cd %s && find . ! -path . > %s' % (imagesrc, image_manifest)
- subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
-
- # Get a list of files in the bundle image which aren't in the base (os-core)
- bb.debug(3, 'Comparing manifest %s to %s' %(base_manifest, image_manifest))
- bundle_file_contents = swupd.utils.unique_contents(base_manifest, image_manifest)
- bb.debug(3, '%s has %s unique contents' % (bundle, len(bundle_file_contents)))
-
- bundle_files = swupd.utils.sanitise_file_list(bundle_file_contents)
- bb.debug(3, 'Sanitised file list for %s has %s contents' % (bundle, len(bundle_files)))
-
- # Finally, copy over the unique bundle contents
- bundledir = d.expand('${SWUPDIMAGEDIR}/${OS_VERSION}/%s/' % bundle)
- swupd.path.copyxattrfiles(d, bundle_files, megarootfs, bundledir)
-
+ unwanted_files = set((d.getVar('SWUPD_FILE_BLACKLIST', True) or '').split())
+ unwanted_files.update(['/' + x for x in swupd.utils.manifest_to_file_list(base_manifest)])
+ create_content_manifest(imagesrc, image_manifest, unwanted_files)
def stage_empty_bundle(d, bundle):
"""
@@ -244,12 +149,7 @@ def copy_bundle_contents(d):
bb.debug(1, 'Copying contents of bundles for %s from mega image rootfs' % d.getVar('PN', True))
bundles = (d.getVar('SWUPD_BUNDLES', True) or '').split()
for bndl in bundles:
- features = d.getVarFlag('BUNDLE_FEATURES', bndl, True)
- if features:
- copy_image_bundle_contents(d, bndl)
- else:
- stage_package_bundle_contents(d, bndl)
- recopy_package_bundle_contents(d, bndl)
+ stage_image_bundle_contents(d, bndl)
bundles = (d.getVar('SWUPD_EMPTY_BUNDLES', True) or '').split()
for bndl in bundles:
stage_empty_bundle(d, bndl)