swupdate.bbclass 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # Copyright (C) 2015 Stefano Babic <sbabic@denx.de>
  2. #
  3. # Some parts from the patch class
  4. #
  5. # swupdate allows to generate a compound image for the
  6. # in the "swupdate" format, used for updating the targets
  7. # in field.
  8. # See also http://sbabic.github.io/swupdate/
  9. #
  10. # To use this class, add swupdate to the inherit clause of the update image bb file.
  11. # The generated output file is an swu archive ready to be uploaded to a device running
  12. # swupdate.
  13. #
  14. # Files listed in the SRC_URI variable are added the the swu archive.
  15. #
  16. # For each entry in the SWUPDATE_IMAGES variable an image file is searched for in the
  17. # ${DEPLOY_DIR_IMAGE} folder and added to the swu archive. Different types of entries
  18. # are supported:
  19. # * image name(s) and fstype(s):
  20. # Example:
  21. # SWUPDATE_IMAGES = "core-image-full-cmdline"
  22. # SWUPDATE_IMAGES_FSTYPES[core-image-full-cmdline] = ".ext4.gz"
  23. # For this example either a file core-image-full-cmdline-${MACHINE}.ext4.gz or a file
  24. # core-image-full-cmdline.ext4.gz gets added the swu archive. Optionally the variable
  25. # SWUPDATE_IMAGES_NOAPPEND_MACHINE allows to explicitley define if the MACHINE name
  26. # must be part of the image file name or not.
  27. # * image file name(s)
  28. # Example:
  29. # SWUPDATE_IMAGES = "core-image-full-cmdline.ext4.gz"
  30. # If SWUPDATE_IMAGES_FSTYPES is not defined for an entry in SWUPDATE_IMAGES or the
  31. # corresponding image files cannot be found in the ${DEPLOY_DIR_IMAGE} folder, an
  32. # image file with exactly the name as specified in SWUPDATE_IMAGES is searched for.
  33. inherit swupdate-common.bbclass
  34. inherit image-artifact-names
  35. S = "${WORKDIR}/${PN}"
  36. DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
  37. IMAGE_DEPENDS ?= ""
  38. def swupdate_getdepends(d):
  39. def adddep(depstr, deps):
  40. for i in (depstr or "").split():
  41. if i not in deps:
  42. deps.append(i)
  43. deps = []
  44. images = (d.getVar('IMAGE_DEPENDS', True) or "").split()
  45. for image in images:
  46. adddep(image , deps)
  47. depstr = ""
  48. for dep in deps:
  49. depstr += " " + dep + ":do_build"
  50. return depstr
  51. IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
  52. do_swuimage[dirs] = "${TOPDIR}"
  53. do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
  54. do_swuimage[umask] = "022"
  55. SSTATETASKS += "do_swuimage"
  56. SSTATE_SKIP_CREATION_task-swuimage = '1'
  57. do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
  58. do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
  59. do_swuimage[stamp-extra-info] = "${MACHINE}"
  60. do_configure[noexec] = "1"
  61. do_compile[noexec] = "1"
  62. do_install[noexec] = "1"
  63. deltask do_populate_sysroot
  64. do_package[noexec] = "1"
  65. deltask do_package_qa
  66. do_packagedata[noexec] = "1"
  67. do_package_write_ipk[noexec] = "1"
  68. do_package_write_deb[noexec] = "1"
  69. do_package_write_rpm[noexec] = "1"
  70. python () {
  71. deps = " " + swupdate_getdepends(d)
  72. d.appendVarFlag('do_swuimage', 'depends', deps)
  73. }
  74. python do_swuimage () {
  75. import shutil
  76. workdir = d.getVar('WORKDIR', True)
  77. images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
  78. s = d.getVar('S', True)
  79. shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
  80. fetch = bb.fetch2.Fetch([], d)
  81. list_for_cpio = ["sw-description"]
  82. if d.getVar('SWUPDATE_SIGNING', True):
  83. list_for_cpio.append('sw-description.sig')
  84. # Add files listed in SRC_URI to the swu file
  85. for url in fetch.urls:
  86. local = fetch.localpath(url)
  87. filename = os.path.basename(local)
  88. aes_file = d.getVar('SWUPDATE_AES_FILE', True)
  89. if aes_file:
  90. key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
  91. if (filename != 'sw-description') and (os.path.isfile(local)):
  92. encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", filename, True) or "")
  93. dst = os.path.join(s, "%s" % filename )
  94. if encrypted == '1':
  95. bb.note("Encryption requested for %s" %(filename))
  96. if not key or not iv:
  97. bb.fatal("Encryption required, but no key found")
  98. swupdate_encrypt_file(local, dst, key, iv)
  99. else:
  100. shutil.copyfile(local, dst)
  101. list_for_cpio.append(filename)
  102. def add_image_to_swu(deploydir, imagename, s, encrypt):
  103. src = os.path.join(deploydir, imagename)
  104. if not os.path.isfile(src):
  105. return False
  106. target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
  107. dst = os.path.join(s, target_imagename)
  108. if encrypt == '1':
  109. key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
  110. bb.note("Encryption requested for %s" %(imagename))
  111. swupdate_encrypt_file(src, dst, key, iv)
  112. else:
  113. shutil.copyfile(src, dst)
  114. list_for_cpio.append(target_imagename)
  115. return True
  116. # Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
  117. deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
  118. imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
  119. for image in images:
  120. fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
  121. encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
  122. if fstypes:
  123. noappend_machine = d.getVarFlag("SWUPDATE_IMAGES_NOAPPEND_MACHINE", image, True)
  124. if noappend_machine == False: # Search for a file explicitely with MACHINE
  125. imagebases = [ image + '-' + d.getVar('MACHINE', True) ]
  126. elif noappend_machine == True: # Search for a file explicitely without MACHINE
  127. imagebases = [ image ]
  128. else: # None, means auto mode. Just try to find an image file with MACHINE or without MACHINE
  129. imagebases = [ image + '-' + d.getVar('MACHINE', True), image ]
  130. for fstype in fstypes:
  131. image_found = False
  132. for imagebase in imagebases:
  133. image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted)
  134. if image_found:
  135. break
  136. if not image_found:
  137. bb.fatal("swupdate cannot find image file: %s" % os.path.join(deploydir, imagebase + fstype))
  138. else: # Allow also complete entries like "image.ext4.gz" in SWUPDATE_IMAGES
  139. if not add_image_to_swu(deploydir, image, s, encrypted):
  140. bb.fatal("swupdate cannot find %s image file" % image)
  141. prepare_sw_description(d, s, list_for_cpio)
  142. line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
  143. os.system("cd " + s + ";" + line)
  144. line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
  145. os.system("cd " + imgdeploydir + "; " + line)
  146. }
  147. COMPRESSIONTYPES = ""
  148. PACKAGE_ARCH = "${MACHINE_ARCH}"
  149. INHIBIT_DEFAULT_DEPS = "1"
  150. EXCLUDE_FROM_WORLD = "1"
  151. addtask do_swuimage after do_unpack do_prepare_recipe_sysroot before do_build