rawcopy.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #
  2. # Copyright OpenEmbedded Contributors
  3. #
  4. # SPDX-License-Identifier: GPL-2.0-only
  5. #
  6. import logging
  7. import os
  8. import signal
  9. import subprocess
  10. from wic import WicError
  11. from wic.pluginbase import SourcePlugin
  12. from wic.misc import exec_cmd, get_bitbake_var
  13. from wic.filemap import sparse_copy
  14. logger = logging.getLogger('wic')
  15. class RawCopyPlugin(SourcePlugin):
  16. """
  17. Populate partition content from raw image file.
  18. """
  19. name = 'rawcopy'
  20. @staticmethod
  21. def do_image_label(fstype, dst, label):
  22. if fstype.startswith('ext'):
  23. cmd = 'tune2fs -L %s %s' % (label, dst)
  24. elif fstype in ('msdos', 'vfat'):
  25. cmd = 'dosfslabel %s %s' % (dst, label)
  26. elif fstype == 'btrfs':
  27. cmd = 'btrfs filesystem label %s %s' % (dst, label)
  28. elif fstype == 'swap':
  29. cmd = 'mkswap -L %s %s' % (label, dst)
  30. elif fstype in ('squashfs', 'erofs'):
  31. raise WicError("It's not possible to update a %s "
  32. "filesystem label '%s'" % (fstype, label))
  33. else:
  34. raise WicError("Cannot update filesystem label: "
  35. "Unknown fstype: '%s'" % (fstype))
  36. exec_cmd(cmd)
  37. @staticmethod
  38. def do_image_uncompression(src, dst, workdir):
  39. def subprocess_setup():
  40. # Python installs a SIGPIPE handler by default. This is usually not what
  41. # non-Python subprocesses expect.
  42. # SIGPIPE errors are known issues with gzip/bash
  43. signal.signal(signal.SIGPIPE, signal.SIG_DFL)
  44. extension = os.path.splitext(src)[1]
  45. decompressor = {
  46. ".bz2": "bzip2",
  47. ".gz": "gzip",
  48. ".xz": "xz"
  49. }.get(extension)
  50. if not decompressor:
  51. raise WicError("Not supported compressor filename extension: %s" % extension)
  52. cmd = "%s -dc %s > %s" % (decompressor, src, dst)
  53. subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=workdir)
  54. @classmethod
  55. def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
  56. oe_builddir, bootimg_dir, kernel_dir,
  57. rootfs_dir, native_sysroot):
  58. """
  59. Called to do the actual content population for a partition i.e. it
  60. 'prepares' the partition to be incorporated into the image.
  61. """
  62. if not kernel_dir:
  63. kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
  64. if not kernel_dir:
  65. raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
  66. logger.debug('Kernel dir: %s', kernel_dir)
  67. if 'file' not in source_params:
  68. raise WicError("No file specified")
  69. if 'unpack' in source_params:
  70. img = os.path.join(kernel_dir, source_params['file'])
  71. src = os.path.join(cr_workdir, os.path.splitext(source_params['file'])[0])
  72. RawCopyPlugin.do_image_uncompression(img, src, cr_workdir)
  73. else:
  74. src = os.path.join(kernel_dir, source_params['file'])
  75. dst = os.path.join(cr_workdir, "%s.%s" % (os.path.basename(source_params['file']), part.lineno))
  76. if not os.path.exists(os.path.dirname(dst)):
  77. os.makedirs(os.path.dirname(dst))
  78. if 'skip' in source_params:
  79. sparse_copy(src, dst, skip=int(source_params['skip']))
  80. else:
  81. sparse_copy(src, dst)
  82. # get the size in the right units for kickstart (kB)
  83. du_cmd = "du -Lbks %s" % dst
  84. out = exec_cmd(du_cmd)
  85. filesize = int(out.split()[0])
  86. if filesize > part.size:
  87. part.size = filesize
  88. if part.label:
  89. RawCopyPlugin.do_image_label(part.fstype, dst, part.label)
  90. part.source_file = dst