swupdate.bbclass 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. if (filename != 'sw-description') and (os.path.isfile(local)):
  88. encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", filename, True) or "")
  89. key,iv,salt = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
  90. dst = os.path.join(s, "%s" % filename )
  91. if encrypted == '1':
  92. bb.note("Encryption requested for %s" %(filename))
  93. swupdate_encrypt_file(local, dst, key, iv, salt)
  94. else:
  95. shutil.copyfile(local, dst)
  96. list_for_cpio.append(filename)
  97. def add_image_to_swu(deploydir, imagename, s, encrypt):
  98. src = os.path.join(deploydir, imagename)
  99. if not os.path.isfile(src):
  100. return False
  101. target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
  102. dst = os.path.join(s, target_imagename)
  103. if encrypt == '1':
  104. key,iv,salt = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
  105. bb.note("Encryption requested for %s" %(imagename))
  106. swupdate_encrypt_file(src, dst, key, iv, salt)
  107. else:
  108. shutil.copyfile(src, dst)
  109. list_for_cpio.append(target_imagename)
  110. return True
  111. # Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
  112. deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
  113. imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
  114. for image in images:
  115. fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
  116. encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
  117. if fstypes:
  118. noappend_machine = d.getVarFlag("SWUPDATE_IMAGES_NOAPPEND_MACHINE", image, True)
  119. if noappend_machine == False: # Search for a file explicitely with MACHINE
  120. imagebases = [ image + '-' + d.getVar('MACHINE', True) ]
  121. elif noappend_machine == True: # Search for a file explicitely without MACHINE
  122. imagebases = [ image ]
  123. else: # None, means auto mode. Just try to find an image file with MACHINE or without MACHINE
  124. imagebases = [ image + '-' + d.getVar('MACHINE', True), image ]
  125. for fstype in fstypes:
  126. image_found = False
  127. for imagebase in imagebases:
  128. image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted)
  129. if image_found:
  130. break
  131. if not image_found:
  132. bb.fatal("swupdate cannot find image file: %s" % os.path.join(deploydir, imagebase + fstype))
  133. else: # Allow also complete entries like "image.ext4.gz" in SWUPDATE_IMAGES
  134. if not add_image_to_swu(deploydir, image, s):
  135. bb.fatal("swupdate cannot find %s image file" % image)
  136. prepare_sw_description(d, s, list_for_cpio)
  137. 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')
  138. os.system("cd " + s + ";" + line)
  139. line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
  140. os.system("cd " + imgdeploydir + "; " + line)
  141. }
  142. COMPRESSIONTYPES = ""
  143. PACKAGE_ARCH = "${MACHINE_ARCH}"
  144. INHIBIT_DEFAULT_DEPS = "1"
  145. EXCLUDE_FROM_WORLD = "1"
  146. addtask do_swuimage after do_unpack do_prepare_recipe_sysroot before do_build