swupdate.bbclass 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. S = "${WORKDIR}/${PN}"
  35. DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
  36. IMAGE_DEPENDS ?= ""
  37. def swupdate_getdepends(d):
  38. def adddep(depstr, deps):
  39. for i in (depstr or "").split():
  40. if i not in deps:
  41. deps.append(i)
  42. deps = []
  43. images = (d.getVar('IMAGE_DEPENDS', True) or "").split()
  44. for image in images:
  45. adddep(image , deps)
  46. depstr = ""
  47. for dep in deps:
  48. depstr += " " + dep + ":do_build"
  49. return depstr
  50. IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
  51. do_swuimage[dirs] = "${TOPDIR}"
  52. do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
  53. do_swuimage[umask] = "022"
  54. SSTATETASKS += "do_swuimage"
  55. SSTATE_SKIP_CREATION_task-swuimage = '1'
  56. do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
  57. do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
  58. do_swuimage[stamp-extra-info] = "${MACHINE}"
  59. do_configure[noexec] = "1"
  60. do_compile[noexec] = "1"
  61. do_install[noexec] = "1"
  62. deltask do_populate_sysroot
  63. do_package[noexec] = "1"
  64. deltask do_package_qa
  65. do_packagedata[noexec] = "1"
  66. do_package_write_ipk[noexec] = "1"
  67. do_package_write_deb[noexec] = "1"
  68. do_package_write_rpm[noexec] = "1"
  69. python () {
  70. deps = " " + swupdate_getdepends(d)
  71. d.appendVarFlag('do_swuimage', 'depends', deps)
  72. }
  73. python do_swuimage () {
  74. import shutil
  75. workdir = d.getVar('WORKDIR', True)
  76. images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
  77. s = d.getVar('S', True)
  78. shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
  79. fetch = bb.fetch2.Fetch([], d)
  80. list_for_cpio = ["sw-description"]
  81. if d.getVar('SWUPDATE_SIGNING', True):
  82. list_for_cpio.append('sw-description.sig')
  83. # Add files listed in SRC_URI to the swu file
  84. for url in fetch.urls:
  85. local = fetch.localpath(url)
  86. filename = os.path.basename(local)
  87. aes_file = d.getVar('SWUPDATE_AES_FILE', True)
  88. if aes_file:
  89. key,iv,salt = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
  90. if (filename != 'sw-description') and (os.path.isfile(local)):
  91. encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", filename, True) or "")
  92. dst = os.path.join(s, "%s" % filename )
  93. if encrypted == '1':
  94. bb.note("Encryption requested for %s" %(filename))
  95. if not key or not iv or not salt:
  96. bb.fatal("Encryption required, but no key found")
  97. swupdate_encrypt_file(local, dst, key, iv, salt)
  98. else:
  99. shutil.copyfile(local, dst)
  100. list_for_cpio.append(filename)
  101. def add_image_to_swu(deploydir, imagename, s, encrypt):
  102. src = os.path.join(deploydir, imagename)
  103. if not os.path.isfile(src):
  104. return False
  105. target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
  106. dst = os.path.join(s, target_imagename)
  107. if encrypt == '1':
  108. key,iv,salt = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
  109. bb.note("Encryption requested for %s" %(imagename))
  110. swupdate_encrypt_file(src, dst, key, iv, salt)
  111. else:
  112. shutil.copyfile(src, dst)
  113. list_for_cpio.append(target_imagename)
  114. return True
  115. # Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
  116. deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
  117. imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
  118. for image in images:
  119. fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
  120. encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
  121. if fstypes:
  122. noappend_machine = d.getVarFlag("SWUPDATE_IMAGES_NOAPPEND_MACHINE", image, True)
  123. if noappend_machine == False: # Search for a file explicitely with MACHINE
  124. imagebases = [ image + '-' + d.getVar('MACHINE', True) ]
  125. elif noappend_machine == True: # Search for a file explicitely without MACHINE
  126. imagebases = [ image ]
  127. else: # None, means auto mode. Just try to find an image file with MACHINE or without MACHINE
  128. imagebases = [ image + '-' + d.getVar('MACHINE', True), image ]
  129. for fstype in fstypes:
  130. image_found = False
  131. for imagebase in imagebases:
  132. image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted)
  133. if image_found:
  134. break
  135. if not image_found:
  136. bb.fatal("swupdate cannot find image file: %s" % os.path.join(deploydir, imagebase + fstype))
  137. else: # Allow also complete entries like "image.ext4.gz" in SWUPDATE_IMAGES
  138. if not add_image_to_swu(deploydir, image, s, encrypted):
  139. bb.fatal("swupdate cannot find %s image file" % image)
  140. prepare_sw_description(d, s, list_for_cpio)
  141. 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')
  142. os.system("cd " + s + ";" + line)
  143. line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
  144. os.system("cd " + imgdeploydir + "; " + line)
  145. }
  146. COMPRESSIONTYPES = ""
  147. PACKAGE_ARCH = "${MACHINE_ARCH}"
  148. INHIBIT_DEFAULT_DEPS = "1"
  149. EXCLUDE_FROM_WORLD = "1"
  150. addtask do_swuimage after do_unpack do_prepare_recipe_sysroot before do_build