diff options
| -rw-r--r-- | scripts/lib/wic/engine.py | 11 | ||||
| -rw-r--r-- | scripts/lib/wic/help.py | 23 | ||||
| -rwxr-xr-x | scripts/wic | 213 |
3 files changed, 154 insertions, 93 deletions
diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py index f59821fea6..647358287f 100644 --- a/scripts/lib/wic/engine.py +++ b/scripts/lib/wic/engine.py | |||
| @@ -201,17 +201,18 @@ def wic_list(args, scripts_path): | |||
| 201 | """ | 201 | """ |
| 202 | Print the list of images or source plugins. | 202 | Print the list of images or source plugins. |
| 203 | """ | 203 | """ |
| 204 | if len(args) < 1: | 204 | if args.list_type is None: |
| 205 | return False | 205 | return False |
| 206 | 206 | ||
| 207 | if args == ["images"]: | 207 | if args.list_type == "images": |
| 208 | |||
| 208 | list_canned_images(scripts_path) | 209 | list_canned_images(scripts_path) |
| 209 | return True | 210 | return True |
| 210 | elif args == ["source-plugins"]: | 211 | elif args.list_type == "source-plugins": |
| 211 | list_source_plugins() | 212 | list_source_plugins() |
| 212 | return True | 213 | return True |
| 213 | elif len(args) == 2 and args[1] == "help": | 214 | elif len(args.help_for) == 1 and args.help_for[0] == 'help': |
| 214 | wks_file = args[0] | 215 | wks_file = args.list_type |
| 215 | fullpath = find_canned_image(scripts_path, wks_file) | 216 | fullpath = find_canned_image(scripts_path, wks_file) |
| 216 | if not fullpath: | 217 | if not fullpath: |
| 217 | raise WicError("No image named %s found, exiting. " | 218 | raise WicError("No image named %s found, exiting. " |
diff --git a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py index d6e027d253..74db05cb94 100644 --- a/scripts/lib/wic/help.py +++ b/scripts/lib/wic/help.py | |||
| @@ -56,7 +56,7 @@ def wic_help(args, usage_str, subcommands): | |||
| 56 | """ | 56 | """ |
| 57 | Subcommand help dispatcher. | 57 | Subcommand help dispatcher. |
| 58 | """ | 58 | """ |
| 59 | if len(args) == 1 or not display_help(args[1], subcommands): | 59 | if args.help_topic == None or not display_help(args.help_topic, subcommands): |
| 60 | print(usage_str) | 60 | print(usage_str) |
| 61 | 61 | ||
| 62 | 62 | ||
| @@ -82,19 +82,20 @@ def invoke_subcommand(args, parser, main_command_usage, subcommands): | |||
| 82 | Dispatch to subcommand handler borrowed from combo-layer. | 82 | Dispatch to subcommand handler borrowed from combo-layer. |
| 83 | Should use argparse, but has to work in 2.6. | 83 | Should use argparse, but has to work in 2.6. |
| 84 | """ | 84 | """ |
| 85 | if not args: | 85 | if not args.command: |
| 86 | logger.error("No subcommand specified, exiting") | 86 | logger.error("No subcommand specified, exiting") |
| 87 | parser.print_help() | 87 | parser.print_help() |
| 88 | return 1 | 88 | return 1 |
| 89 | elif args[0] == "help": | 89 | elif args.command == "help": |
| 90 | wic_help(args, main_command_usage, subcommands) | 90 | wic_help(args, main_command_usage, subcommands) |
| 91 | elif args[0] not in subcommands: | 91 | elif args.command not in subcommands: |
| 92 | logger.error("Unsupported subcommand %s, exiting\n", args[0]) | 92 | logger.error("Unsupported subcommand %s, exiting\n", args.command) |
| 93 | parser.print_help() | 93 | parser.print_help() |
| 94 | return 1 | 94 | return 1 |
| 95 | else: | 95 | else: |
| 96 | usage = subcommands.get(args[0], subcommand_error)[1] | 96 | subcmd = subcommands.get(args.command, subcommand_error) |
| 97 | subcommands.get(args[0], subcommand_error)[0](args[1:], usage) | 97 | usage = subcmd[1] |
| 98 | subcmd[0](args, usage) | ||
| 98 | 99 | ||
| 99 | 100 | ||
| 100 | ## | 101 | ## |
| @@ -795,3 +796,11 @@ DESCRIPTION | |||
| 795 | .wks files. | 796 | .wks files. |
| 796 | 797 | ||
| 797 | """ | 798 | """ |
| 799 | |||
| 800 | wic_help_help = """ | ||
| 801 | NAME | ||
| 802 | wic help - display a help topic | ||
| 803 | |||
| 804 | DESCRIPTION | ||
| 805 | Specify a help topic to display it. Topics are shown above. | ||
| 806 | """ | ||
diff --git a/scripts/wic b/scripts/wic index a5f2dbfc6f..49cad869e2 100755 --- a/scripts/wic +++ b/scripts/wic | |||
| @@ -33,7 +33,7 @@ __version__ = "0.2.0" | |||
| 33 | # Python Standard Library modules | 33 | # Python Standard Library modules |
| 34 | import os | 34 | import os |
| 35 | import sys | 35 | import sys |
| 36 | import optparse | 36 | import argparse |
| 37 | import logging | 37 | import logging |
| 38 | from distutils import spawn | 38 | from distutils import spawn |
| 39 | 39 | ||
| @@ -85,66 +85,30 @@ def rootfs_dir_to_args(krootfs_dir): | |||
| 85 | rootfs_dir += '='.join([key, val]) | 85 | rootfs_dir += '='.join([key, val]) |
| 86 | return rootfs_dir.strip() | 86 | return rootfs_dir.strip() |
| 87 | 87 | ||
| 88 | def callback_rootfs_dir(option, opt, value, parser): | ||
| 89 | """ | ||
| 90 | Build a dict using --rootfs_dir connection=dir | ||
| 91 | """ | ||
| 92 | if not type(parser.values.rootfs_dir) is dict: | ||
| 93 | parser.values.rootfs_dir = dict() | ||
| 94 | 88 | ||
| 95 | if '=' in value: | 89 | class RootfsArgAction(argparse.Action): |
| 96 | (key, rootfs_dir) = value.split('=') | 90 | def __init__(self, **kwargs): |
| 97 | else: | 91 | super().__init__(**kwargs) |
| 98 | key = 'ROOTFS_DIR' | 92 | |
| 99 | rootfs_dir = value | 93 | def __call__(self, parser, namespace, value, option_string=None): |
| 94 | if not "rootfs_dir" in vars(namespace) or \ | ||
| 95 | not type(namespace.__dict__['rootfs_dir']) is dict: | ||
| 96 | namespace.__dict__['rootfs_dir'] = {} | ||
| 97 | |||
| 98 | if '=' in value: | ||
| 99 | (key, rootfs_dir) = value.split('=') | ||
| 100 | else: | ||
| 101 | key = 'ROOTFS_DIR' | ||
| 102 | rootfs_dir = value | ||
| 100 | 103 | ||
| 101 | parser.values.rootfs_dir[key] = rootfs_dir | 104 | namespace.__dict__['rootfs_dir'][key] = rootfs_dir |
| 102 | 105 | ||
| 103 | def wic_create_subcommand(args, usage_str): | 106 | |
| 107 | def wic_create_subcommand(options, usage_str): | ||
| 104 | """ | 108 | """ |
| 105 | Command-line handling for image creation. The real work is done | 109 | Command-line handling for image creation. The real work is done |
| 106 | by image.engine.wic_create() | 110 | by image.engine.wic_create() |
| 107 | """ | 111 | """ |
| 108 | parser = optparse.OptionParser(usage=usage_str) | ||
| 109 | |||
| 110 | parser.add_option("-o", "--outdir", dest="outdir", default='.', | ||
| 111 | help="name of directory to create image in") | ||
| 112 | parser.add_option("-e", "--image-name", dest="image_name", | ||
| 113 | help="name of the image to use the artifacts from " | ||
| 114 | "e.g. core-image-sato") | ||
| 115 | parser.add_option("-r", "--rootfs-dir", dest="rootfs_dir", type="string", | ||
| 116 | action="callback", callback=callback_rootfs_dir, | ||
| 117 | help="path to the /rootfs dir to use as the " | ||
| 118 | ".wks rootfs source") | ||
| 119 | parser.add_option("-b", "--bootimg-dir", dest="bootimg_dir", | ||
| 120 | help="path to the dir containing the boot artifacts " | ||
| 121 | "(e.g. /EFI or /syslinux dirs) to use as the " | ||
| 122 | ".wks bootimg source") | ||
| 123 | parser.add_option("-k", "--kernel-dir", dest="kernel_dir", | ||
| 124 | help="path to the dir containing the kernel to use " | ||
| 125 | "in the .wks bootimg") | ||
| 126 | parser.add_option("-n", "--native-sysroot", dest="native_sysroot", | ||
| 127 | help="path to the native sysroot containing the tools " | ||
| 128 | "to use to build the image") | ||
| 129 | parser.add_option("-s", "--skip-build-check", dest="build_check", | ||
| 130 | action="store_false", default=True, help="skip the build check") | ||
| 131 | parser.add_option("-f", "--build-rootfs", action="store_true", help="build rootfs") | ||
| 132 | parser.add_option("-c", "--compress-with", choices=("gzip", "bzip2", "xz"), | ||
| 133 | dest='compressor', | ||
| 134 | help="compress image with specified compressor") | ||
| 135 | parser.add_option("-m", "--bmap", action="store_true", help="generate .bmap") | ||
| 136 | parser.add_option("-v", "--vars", dest='vars_dir', | ||
| 137 | help="directory with <image>.env files that store " | ||
| 138 | "bitbake variables") | ||
| 139 | parser.add_option("-D", "--debug", dest="debug", action="store_true", | ||
| 140 | default=False, help="output debug information") | ||
| 141 | |||
| 142 | (options, args) = parser.parse_args(args) | ||
| 143 | |||
| 144 | if len(args) != 1: | ||
| 145 | parser.print_help() | ||
| 146 | raise WicError("Wrong number of arguments, exiting") | ||
| 147 | |||
| 148 | if options.build_rootfs and not bitbake_main: | 112 | if options.build_rootfs and not bitbake_main: |
| 149 | raise WicError("Can't build rootfs as bitbake is not in the $PATH") | 113 | raise WicError("Can't build rootfs as bitbake is not in the $PATH") |
| 150 | 114 | ||
| @@ -206,14 +170,14 @@ def wic_create_subcommand(args, usage_str): | |||
| 206 | raise WicError("Unable to find the location of the native " | 170 | raise WicError("Unable to find the location of the native " |
| 207 | "tools sysroot to use") | 171 | "tools sysroot to use") |
| 208 | 172 | ||
| 209 | wks_file = args[0] | 173 | wks_file = options.wks_file |
| 210 | 174 | ||
| 211 | if not wks_file.endswith(".wks"): | 175 | if not wks_file.endswith(".wks"): |
| 212 | wks_file = engine.find_canned_image(scripts_path, wks_file) | 176 | wks_file = engine.find_canned_image(scripts_path, wks_file) |
| 213 | if not wks_file: | 177 | if not wks_file: |
| 214 | raise WicError("No image named %s found, exiting. (Use 'wic list images' " | 178 | raise WicError("No image named %s found, exiting. (Use 'wic list images' " |
| 215 | "to list available images, or specify a fully-qualified OE " | 179 | "to list available images, or specify a fully-qualified OE " |
| 216 | "kickstart (.wks) filename)" % args[0]) | 180 | "kickstart (.wks) filename)" % options.wks_file) |
| 217 | 181 | ||
| 218 | if not options.image_name: | 182 | if not options.image_name: |
| 219 | rootfs_dir = '' | 183 | rootfs_dir = '' |
| @@ -264,59 +228,146 @@ def wic_list_subcommand(args, usage_str): | |||
| 264 | Command-line handling for listing available images. | 228 | Command-line handling for listing available images. |
| 265 | The real work is done by image.engine.wic_list() | 229 | The real work is done by image.engine.wic_list() |
| 266 | """ | 230 | """ |
| 267 | parser = optparse.OptionParser(usage=usage_str) | ||
| 268 | args = parser.parse_args(args)[1] | ||
| 269 | |||
| 270 | if not engine.wic_list(args, scripts_path): | 231 | if not engine.wic_list(args, scripts_path): |
| 271 | parser.print_help() | ||
| 272 | raise WicError("Bad list arguments, exiting") | 232 | raise WicError("Bad list arguments, exiting") |
| 273 | 233 | ||
| 274 | 234 | ||
| 275 | def wic_help_topic_subcommand(args, usage_str): | 235 | def wic_help_subcommand(args, usage_str): |
| 276 | """ | 236 | """ |
| 277 | Command-line handling for help-only 'subcommands'. This is | 237 | Command-line handling for help subcommand to keep the current |
| 278 | essentially a dummy command that doesn nothing but allow users to | 238 | structure of the function definitions. |
| 279 | use the existing subcommand infrastructure to display help on a | ||
| 280 | particular topic not attached to any particular subcommand. | ||
| 281 | """ | 239 | """ |
| 282 | pass | 240 | pass |
| 283 | 241 | ||
| 284 | 242 | ||
| 243 | def wic_help_topic_subcommand(usage_str, help_str): | ||
| 244 | """ | ||
| 245 | Display function for help 'sub-subcommands'. | ||
| 246 | """ | ||
| 247 | print(help_str) | ||
| 248 | return | ||
| 249 | |||
| 250 | |||
| 285 | wic_help_topic_usage = """ | 251 | wic_help_topic_usage = """ |
| 286 | """ | 252 | """ |
| 287 | 253 | ||
| 288 | subcommands = { | 254 | helptopics = { |
| 289 | "create": [wic_create_subcommand, | ||
| 290 | hlp.wic_create_usage, | ||
| 291 | hlp.wic_create_help], | ||
| 292 | "list": [wic_list_subcommand, | ||
| 293 | hlp.wic_list_usage, | ||
| 294 | hlp.wic_list_help], | ||
| 295 | "plugins": [wic_help_topic_subcommand, | 255 | "plugins": [wic_help_topic_subcommand, |
| 296 | wic_help_topic_usage, | 256 | wic_help_topic_usage, |
| 297 | hlp.get_wic_plugins_help], | 257 | hlp.wic_plugins_help], |
| 298 | "overview": [wic_help_topic_subcommand, | 258 | "overview": [wic_help_topic_subcommand, |
| 299 | wic_help_topic_usage, | 259 | wic_help_topic_usage, |
| 300 | hlp.wic_overview_help], | 260 | hlp.wic_overview_help], |
| 301 | "kickstart": [wic_help_topic_subcommand, | 261 | "kickstart": [wic_help_topic_subcommand, |
| 302 | wic_help_topic_usage, | 262 | wic_help_topic_usage, |
| 303 | hlp.wic_kickstart_help], | 263 | hlp.wic_kickstart_help], |
| 264 | "create": [wic_help_topic_subcommand, | ||
| 265 | wic_help_topic_usage, | ||
| 266 | hlp.wic_create_help], | ||
| 267 | "list": [wic_help_topic_subcommand, | ||
| 268 | wic_help_topic_usage, | ||
| 269 | hlp.wic_list_help] | ||
| 304 | } | 270 | } |
| 305 | 271 | ||
| 306 | 272 | ||
| 273 | def wic_init_parser_create(subparser): | ||
| 274 | subparser.add_argument("wks_file") | ||
| 275 | |||
| 276 | subparser.add_argument("-o", "--outdir", dest="outdir", default='.', | ||
| 277 | help="name of directory to create image in") | ||
| 278 | subparser.add_argument("-e", "--image-name", dest="image_name", | ||
| 279 | help="name of the image to use the artifacts from " | ||
| 280 | "e.g. core-image-sato") | ||
| 281 | subparser.add_argument("-r", "--rootfs-dir", action=RootfsArgAction, | ||
| 282 | help="path to the /rootfs dir to use as the " | ||
| 283 | ".wks rootfs source") | ||
| 284 | subparser.add_argument("-b", "--bootimg-dir", dest="bootimg_dir", | ||
| 285 | help="path to the dir containing the boot artifacts " | ||
| 286 | "(e.g. /EFI or /syslinux dirs) to use as the " | ||
| 287 | ".wks bootimg source") | ||
| 288 | subparser.add_argument("-k", "--kernel-dir", dest="kernel_dir", | ||
| 289 | help="path to the dir containing the kernel to use " | ||
| 290 | "in the .wks bootimg") | ||
| 291 | subparser.add_argument("-n", "--native-sysroot", dest="native_sysroot", | ||
| 292 | help="path to the native sysroot containing the tools " | ||
| 293 | "to use to build the image") | ||
| 294 | subparser.add_argument("-s", "--skip-build-check", dest="build_check", | ||
| 295 | action="store_false", default=True, help="skip the build check") | ||
| 296 | subparser.add_argument("-f", "--build-rootfs", action="store_true", help="build rootfs") | ||
| 297 | subparser.add_argument("-c", "--compress-with", choices=("gzip", "bzip2", "xz"), | ||
| 298 | dest='compressor', | ||
| 299 | help="compress image with specified compressor") | ||
| 300 | subparser.add_argument("-m", "--bmap", action="store_true", help="generate .bmap") | ||
| 301 | subparser.add_argument("-v", "--vars", dest='vars_dir', | ||
| 302 | help="directory with <image>.env files that store " | ||
| 303 | "bitbake variables") | ||
| 304 | subparser.add_argument("-D", "--debug", dest="debug", action="store_true", | ||
| 305 | default=False, help="output debug information") | ||
| 306 | return | ||
| 307 | |||
| 308 | |||
| 309 | def wic_init_parser_list(subparser): | ||
| 310 | subparser.add_argument("list_type", | ||
| 311 | help="can be 'images' or 'source-plugins' " | ||
| 312 | "to obtain a list. " | ||
| 313 | "If value is a valid .wks image file") | ||
| 314 | subparser.add_argument("help_for", default=[], nargs='*', | ||
| 315 | help="If 'list_type' is a valid .wks image file " | ||
| 316 | "this value can be 'help' to show the help information " | ||
| 317 | "defined inside the .wks file") | ||
| 318 | return | ||
| 319 | |||
| 320 | |||
| 321 | def wic_init_parser_help(subparser): | ||
| 322 | helpparsers = subparser.add_subparsers(dest='help_topic', help=hlp.wic_usage) | ||
| 323 | for helptopic in helptopics: | ||
| 324 | helpparsers.add_parser(helptopic, help=helptopics[helptopic][2]) | ||
| 325 | return | ||
| 326 | |||
| 327 | |||
| 328 | subcommands = { | ||
| 329 | "create": [wic_create_subcommand, | ||
| 330 | hlp.wic_create_usage, | ||
| 331 | hlp.wic_create_help, | ||
| 332 | wic_init_parser_create], | ||
| 333 | "list": [wic_list_subcommand, | ||
| 334 | hlp.wic_list_usage, | ||
| 335 | hlp.wic_list_help, | ||
| 336 | wic_init_parser_list], | ||
| 337 | "help": [wic_help_subcommand, | ||
| 338 | wic_help_topic_usage, | ||
| 339 | hlp.wic_help_help, | ||
| 340 | wic_init_parser_help] | ||
| 341 | } | ||
| 342 | |||
| 343 | |||
| 344 | def init_parser(parser): | ||
| 345 | parser.add_argument("--version", action="version", | ||
| 346 | version="%(prog)s {version}".format(version=__version__)) | ||
| 347 | subparsers = parser.add_subparsers(dest='command', help=hlp.wic_usage) | ||
| 348 | for subcmd in subcommands: | ||
| 349 | subparser = subparsers.add_parser(subcmd, help=subcommands[subcmd][2]) | ||
| 350 | subcommands[subcmd][3](subparser) | ||
| 351 | |||
| 352 | |||
| 307 | def main(argv): | 353 | def main(argv): |
| 308 | parser = optparse.OptionParser(version="wic version %s" % __version__, | 354 | parser = argparse.ArgumentParser( |
| 309 | usage=hlp.wic_usage) | 355 | description="wic version %s" % __version__) |
| 310 | 356 | ||
| 311 | parser.disable_interspersed_args() | 357 | init_parser(parser) |
| 312 | 358 | ||
| 313 | args = parser.parse_args(argv)[1] | 359 | args = parser.parse_args(argv) |
| 314 | 360 | ||
| 315 | if len(args): | 361 | if "command" in vars(args): |
| 316 | if args[0] == "help": | 362 | if args.command == "help": |
| 317 | if len(args) == 1: | 363 | if args.help_topic is None: |
| 318 | parser.print_help() | 364 | parser.print_help() |
| 319 | raise WicError("help command requires parameter") | 365 | print() |
| 366 | print("Please specify a help topic") | ||
| 367 | elif args.help_topic in helptopics: | ||
| 368 | hlpt = helptopics[args.help_topic] | ||
| 369 | hlpt[0](hlpt[1], hlpt[2]) | ||
| 370 | return 0 | ||
| 320 | 371 | ||
| 321 | return hlp.invoke_subcommand(args, parser, hlp.wic_help_usage, subcommands) | 372 | return hlp.invoke_subcommand(args, parser, hlp.wic_help_usage, subcommands) |
| 322 | 373 | ||
