wic 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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 = ""
  117. if options.image_name:
  118. (rootfs_dir, kernel_dir, bootimg_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(kernel_dir):
  153. (not_found, not_found_dir) = ("kernel-dir", kernel_dir)
  154. elif not os.path.isdir(native_sysroot):
  155. (not_found, not_found_dir) = ("native-sysroot", native_sysroot)
  156. if not_found:
  157. if not not_found_dir:
  158. not_found_dir = "Completely missing artifact - wrong image (.wks) used?"
  159. print "Build artifacts not found, exiting."
  160. print " (Please check that the build artifacts for the machine"
  161. print " selected in local.conf actually exist and that they"
  162. print " are the correct artifacts for the image (.wks file)).\n"
  163. print "The artifact that couldn't be found was %s:\n %s" % \
  164. (not_found, not_found_dir)
  165. sys.exit(1)
  166. krootfs_dir = options.rootfs_dir
  167. if krootfs_dir is None:
  168. krootfs_dir = {}
  169. krootfs_dir['ROOTFS_DIR'] = rootfs_dir
  170. rootfs_dir = rootfs_dir_to_args(krootfs_dir)
  171. wic_create(args, wks_file, rootfs_dir, bootimg_dir, kernel_dir,
  172. native_sysroot, scripts_path, image_output_dir,
  173. options.debug, options.properties_file)
  174. def wic_list_subcommand(args, usage_str):
  175. """
  176. Command-line handling for listing available image properties and
  177. values. The real work is done by image.engine.wic_list()
  178. """
  179. parser = optparse.OptionParser(usage = usage_str)
  180. parser.add_option("-o", "--outfile", action = "store",
  181. dest = "properties_file",
  182. help = "dump the possible values for image properties to a JSON file")
  183. (options, args) = parser.parse_args(args)
  184. bitbake_env_lines = find_bitbake_env_lines(None)
  185. if not bitbake_env_lines:
  186. print "Couldn't get bitbake environment, exiting."
  187. sys.exit(1)
  188. set_bitbake_env_lines(bitbake_env_lines)
  189. if not wic_list(args, scripts_path, options.properties_file):
  190. logging.error("Bad list arguments, exiting\n")
  191. parser.print_help()
  192. sys.exit(1)
  193. def wic_help_topic_subcommand(args, usage_str):
  194. """
  195. Command-line handling for help-only 'subcommands'. This is
  196. essentially a dummy command that doesn nothing but allow users to
  197. use the existing subcommand infrastructure to display help on a
  198. particular topic not attached to any particular subcommand.
  199. """
  200. pass
  201. wic_help_topic_usage = """
  202. """
  203. subcommands = {
  204. "create": [wic_create_subcommand,
  205. wic_create_usage,
  206. wic_create_help],
  207. "list": [wic_list_subcommand,
  208. wic_list_usage,
  209. wic_list_help],
  210. "plugins": [wic_help_topic_subcommand,
  211. wic_help_topic_usage,
  212. wic_plugins_help],
  213. "overview": [wic_help_topic_subcommand,
  214. wic_help_topic_usage,
  215. wic_overview_help],
  216. "kickstart": [wic_help_topic_subcommand,
  217. wic_help_topic_usage,
  218. wic_kickstart_help],
  219. }
  220. def start_logging(loglevel):
  221. logging.basicConfig(filname = 'wic.log', filemode = 'w', level=loglevel)
  222. def main():
  223. parser = optparse.OptionParser(version = "wic version %s" % __version__,
  224. usage = wic_usage)
  225. parser.disable_interspersed_args()
  226. (options, args) = parser.parse_args()
  227. if len(args):
  228. if args[0] == "help":
  229. if len(args) == 1:
  230. parser.print_help()
  231. sys.exit(1)
  232. invoke_subcommand(args, parser, wic_help_usage, subcommands)
  233. if __name__ == "__main__":
  234. try:
  235. ret = main()
  236. except Exception:
  237. ret = 1
  238. import traceback
  239. traceback.print_exc(5)
  240. sys.exit(ret)