wic 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #!/usr/bin/env python
  2. # ex:ts=4:sw=4:sts=4:et
  3. # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
  4. #
  5. # Copyright (c) 2013, Intel Corporation.
  6. # All rights reserved.
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License version 2 as
  10. # published by the Free Software Foundation.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. # DESCRIPTION 'wic' is the OpenEmbedded Image Creator that users can
  22. # use to generate bootable images. Invoking it without any arguments
  23. # will display help screens for the 'wic' command and list the
  24. # available 'wic' subcommands. Invoking a subcommand without any
  25. # arguments will likewise display help screens for the specified
  26. # subcommand. Please use that interface for detailed help.
  27. #
  28. # AUTHORS
  29. # Tom Zanussi <tom.zanussi (at] linux.intel.com>
  30. #
  31. __version__ = "0.1.0"
  32. # Python Standard Library modules
  33. import os
  34. import sys
  35. import optparse
  36. import logging
  37. # External modules
  38. scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
  39. lib_path = scripts_path + '/lib'
  40. sys.path = sys.path + [lib_path]
  41. from image.help import *
  42. from image.engine import *
  43. def rootfs_dir_to_args(krootfs_dir):
  44. """
  45. Get a rootfs_dir dict and serialize to string
  46. """
  47. rootfs_dir = ''
  48. for k, v in krootfs_dir.items():
  49. rootfs_dir += ' '
  50. rootfs_dir += '='.join([k, v])
  51. return rootfs_dir.strip()
  52. def callback_rootfs_dir(option, opt, value, parser):
  53. """
  54. Build a dict using --rootfs_dir connection=dir
  55. """
  56. if not type(parser.values.rootfs_dir) is dict:
  57. parser.values.rootfs_dir = dict()
  58. if '=' in value:
  59. (key, rootfs_dir) = value.split('=')
  60. else:
  61. key = 'ROOTFS_DIR'
  62. rootfs_dir = value
  63. parser.values.rootfs_dir[key] = rootfs_dir
  64. def wic_create_subcommand(args, usage_str):
  65. """
  66. Command-line handling for image creation. The real work is done
  67. by image.engine.wic_create()
  68. """
  69. parser = optparse.OptionParser(usage = usage_str)
  70. parser.add_option("-o", "--outdir", dest = "outdir",
  71. action = "store", help = "name of directory to create image in")
  72. parser.add_option("-i", "--infile", dest = "properties_file",
  73. action = "store", help = "name of file containing the values for image properties as a JSON file")
  74. parser.add_option("-e", "--image-name", dest = "image_name",
  75. action = "store", help = "name of the image to use the artifacts from e.g. core-image-sato")
  76. parser.add_option("-r", "--rootfs-dir", dest = "rootfs_dir",
  77. action = "callback", callback = callback_rootfs_dir, type = "string",
  78. help = "path to the /rootfs dir to use as the .wks rootfs source")
  79. parser.add_option("-b", "--bootimg-dir", dest = "bootimg_dir",
  80. action = "store", help = "path to the dir containing the boot artifacts (e.g. /EFI or /syslinux dirs) to use as the .wks bootimg source")
  81. parser.add_option("-k", "--kernel-dir", dest = "kernel_dir",
  82. action = "store", help = "path to the dir containing the kernel to use in the .wks bootimg")
  83. parser.add_option("-n", "--native-sysroot", dest = "native_sysroot",
  84. action = "store", help = "path to the native sysroot containing the tools to use to build the image")
  85. parser.add_option("-p", "--skip-build-check", dest = "build_check",
  86. action = "store_false", default = True, help = "skip the build check")
  87. parser.add_option("-D", "--debug", dest = "debug", action = "store_true",
  88. default = False, help = "output debug information")
  89. (options, args) = parser.parse_args(args)
  90. if len(args) != 1:
  91. logging.error("Wrong number of arguments, exiting\n")
  92. parser.print_help()
  93. sys.exit(1)
  94. if not options.image_name and not (options.rootfs_dir and
  95. options.bootimg_dir and
  96. options.kernel_dir and
  97. options.native_sysroot):
  98. print "Build artifacts not completely specified, exiting."
  99. print " (Use 'wic -e' or 'wic -r -b -k -n' to specify artifacts)"
  100. sys.exit(1)
  101. if not options.image_name:
  102. options.build_check = False
  103. if options.build_check and not options.properties_file:
  104. print "Checking basic build environment..."
  105. if not verify_build_env():
  106. print "Couldn't verify build environment, exiting\n"
  107. sys.exit(1)
  108. else:
  109. print "Done.\n"
  110. print "Creating image(s)...\n"
  111. bitbake_env_lines = find_bitbake_env_lines(options.image_name)
  112. if not bitbake_env_lines:
  113. print "Couldn't get bitbake environment, exiting."
  114. sys.exit(1)
  115. set_bitbake_env_lines(bitbake_env_lines)
  116. bootimg_dir = staging_data_dir = hdddir = ""
  117. if options.image_name:
  118. (rootfs_dir, kernel_dir, hdddir, staging_data_dir, native_sysroot) = \
  119. find_artifacts(options.image_name)
  120. wks_file = args[0]
  121. if not wks_file.endswith(".wks"):
  122. wks_file = find_canned_image(scripts_path, wks_file)
  123. if not wks_file:
  124. print "No image named %s found, exiting. (Use 'wic list images' to list available images, or specify a fully-qualified OE kickstart (.wks) filename)\n" % wks_file
  125. sys.exit(1)
  126. image_output_dir = ""
  127. if options.outdir:
  128. image_output_dir = options.outdir
  129. if not options.image_name:
  130. rootfs_dir = ''
  131. if 'ROOTFS_DIR' in options.rootfs_dir:
  132. rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
  133. bootimg_dir = options.bootimg_dir
  134. kernel_dir = options.kernel_dir
  135. native_sysroot = options.native_sysroot
  136. if rootfs_dir and not os.path.isdir(rootfs_dir):
  137. print "--roofs-dir (-r) not found, exiting\n"
  138. sys.exit(1)
  139. if not os.path.isdir(bootimg_dir):
  140. print "--bootimg-dir (-b) not found, exiting\n"
  141. sys.exit(1)
  142. if not os.path.isdir(kernel_dir):
  143. print "--kernel-dir (-k) not found, exiting\n"
  144. sys.exit(1)
  145. if not os.path.isdir(native_sysroot):
  146. print "--native-sysroot (-n) not found, exiting\n"
  147. sys.exit(1)
  148. else:
  149. not_found = not_found_dir = ""
  150. if not os.path.isdir(rootfs_dir):
  151. (not_found, not_found_dir) = ("rootfs-dir", rootfs_dir)
  152. elif not os.path.isdir(hdddir) and not os.path.isdir(staging_data_dir):
  153. (not_found, not_found_dir) = ("bootimg-dir", bootimg_dir)
  154. elif not os.path.isdir(kernel_dir):
  155. (not_found, not_found_dir) = ("kernel-dir", kernel_dir)
  156. elif not os.path.isdir(native_sysroot):
  157. (not_found, not_found_dir) = ("native-sysroot", native_sysroot)
  158. if not_found:
  159. if not not_found_dir:
  160. not_found_dir = "Completely missing artifact - wrong image (.wks) used?"
  161. print "Build artifacts not found, exiting."
  162. print " (Please check that the build artifacts for the machine"
  163. print " selected in local.conf actually exist and that they"
  164. print " are the correct artifacts for the image (.wks file)).\n"
  165. print "The artifact that couldn't be found was %s:\n %s" % \
  166. (not_found, not_found_dir)
  167. sys.exit(1)
  168. krootfs_dir = options.rootfs_dir
  169. if krootfs_dir is None:
  170. krootfs_dir = {}
  171. krootfs_dir['ROOTFS_DIR'] = rootfs_dir
  172. rootfs_dir = rootfs_dir_to_args(krootfs_dir)
  173. wic_create(args, wks_file, rootfs_dir, bootimg_dir, kernel_dir,
  174. native_sysroot, hdddir, staging_data_dir, scripts_path,
  175. image_output_dir, options.debug, options.properties_file)
  176. def wic_list_subcommand(args, usage_str):
  177. """
  178. Command-line handling for listing available image properties and
  179. values. The real work is done by image.engine.wic_list()
  180. """
  181. parser = optparse.OptionParser(usage = usage_str)
  182. parser.add_option("-o", "--outfile", action = "store",
  183. dest = "properties_file",
  184. help = "dump the possible values for image properties to a JSON file")
  185. (options, args) = parser.parse_args(args)
  186. if not wic_list(args, scripts_path, options.properties_file):
  187. logging.error("Bad list arguments, exiting\n")
  188. parser.print_help()
  189. sys.exit(1)
  190. subcommands = {
  191. "create": [wic_create_subcommand,
  192. wic_create_usage,
  193. wic_create_help],
  194. "list": [wic_list_subcommand,
  195. wic_list_usage,
  196. wic_list_help],
  197. }
  198. def start_logging(loglevel):
  199. logging.basicConfig(filname = 'wic.log', filemode = 'w', level=loglevel)
  200. def main():
  201. parser = optparse.OptionParser(version = "wic version %s" % __version__,
  202. usage = wic_usage)
  203. parser.disable_interspersed_args()
  204. (options, args) = parser.parse_args()
  205. if len(args):
  206. if args[0] == "help":
  207. if len(args) == 1:
  208. parser.print_help()
  209. sys.exit(1)
  210. invoke_subcommand(args, parser, wic_help_usage, subcommands)
  211. if __name__ == "__main__":
  212. try:
  213. ret = main()
  214. except Exception:
  215. ret = 1
  216. import traceback
  217. traceback.print_exc(5)
  218. sys.exit(ret)