Merge lp:~dooferlad/linaro-image-tools/add-directory-option into lp:linaro-image-tools/11.11

Proposed by James Tunnicliffe
Status: Superseded
Proposed branch: lp:~dooferlad/linaro-image-tools/add-directory-option
Merge into: lp:linaro-image-tools/11.11
Diff against target: 305 lines (+158/-32)
7 files modified
.bzrignore (+1/-0)
linaro-media-create (+37/-25)
linaro_image_tools/media_create/__init__.py (+11/-6)
linaro_image_tools/media_create/boards.py (+28/-0)
linaro_image_tools/media_create/partitions.py (+1/-0)
linaro_image_tools/tests/test_utils.py (+44/-1)
linaro_image_tools/utils.py (+36/-0)
To merge this branch: bzr merge lp:~dooferlad/linaro-image-tools/add-directory-option
Reviewer Review Type Date Requested Status
linaro-image-tools maintainers Pending
Review via email: mp+102331@code.launchpad.net

This proposal supersedes a proposal from 2012-04-16.

This proposal has been superseded by a proposal from 2012-04-18.

Description of the change

Slightly modified patch from https://bugs.launchpad.net/linaro-image-tools/+bug/962147

Updated:
--directory can now be specified at the same time as --image-file. If --directory and --image-file are combined, a file, whose name is specified by --image-file, will be created in --directory. If --image-file is not specified, a sensible default file name will be used and printed for the user to see.

--directory and --mmc are incompatable.

--directory and specifying a full path to a file with --image-file are incompatable.

To post a comment you must log in.
Revision history for this message
Loïc Minier (lool) wrote : Posted in a previous version of this proposal

On Mon, Apr 16, 2012, James Tunnicliffe wrote:
[...]
> + if args.directory is not None:
> + if not board_config.outputs_directory:
> + raise BoardAbilityNotMet("The board '%s' does not support the"
> + "--directory option." % args.board)

 I find the per board attribute kinda ugly and I'm not sure we want to
 suffer from supporting both a single file output or a directory with
 multiple files as output.

 How about we just default to always outputting to a directory, default
 to ./ as the target directory, and allow overriding that, but keep the
 --image-file as the default filename for the main image? We could
 document for each boardconfig what it outputs as to display it at the
 end of the build or in the help output.

 There are alternate approaches such as output a zip/tgz file with all
 the assets and naming that after --image-file, but that's probably a
 bit heavy. We could also abuse --image-file by outputting a warning
 and creating a directory there instead (e.g. --image-file foo.img would
 create ./foo.img/ and output the assets below that).

--
Loïc Minier

Revision history for this message
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal

On 16 April 2012 17:40, Loïc Minier <email address hidden> wrote:
> On Mon, Apr 16, 2012, James Tunnicliffe wrote:
> [...]
>> +    if args.directory is not None:
>> +        if not board_config.outputs_directory:
>> +            raise BoardAbilityNotMet("The board '%s' does not support the"
>> +                                     "--directory option." % args.board)
>
>  I find the per board attribute kinda ugly and I'm not sure we want to
>  suffer from supporting both a single file output or a directory with
>  multiple files as output.
>
>  How about we just default to always outputting to a directory, default
>  to ./ as the target directory, and allow overriding that, but keep the
>  --image-file as the default filename for the main image?  We could
>  document for each boardconfig what it outputs as to display it at the
>  end of the build or in the help output.

I like this approach since it gracefully reverts back to the old
behaviour. Will make some changes.

--
James Tunnicliffe

Revision history for this message
James Tunnicliffe (dooferlad) wrote :

Oops, forgot to delete the outputs_directory flag. Hang on...

Revision history for this message
James Tunnicliffe (dooferlad) wrote :

OK. Done.

511. By James Tunnicliffe

Removed outputs_directory flag

Revision history for this message
Loïc Minier (lool) wrote :

On Tue, Apr 17, 2012, James Tunnicliffe wrote:
> + IncompatableOptions,

 IncompatibleOptions

> + parser.add_argument(
> + '--directory', dest='directory',
> + help='Directory where image and accessories should be written to.')

 --output-directory?

> + outputs_directory = False

 not too nice as property; perhaps outputs_multiple_artifacts = False?
 Or expected_artifacts = 1?

> +def prep_media_path(args, board_config):
> +
> + # If args.device isn't set, generate a sensible default file name and
> + # tell the user
> + if not args.device:
> + args.device = board_config.board + ".img"
> + print "Setting destination file name to", args.device

 I think it would be more stable to just call it mmc.img or sd.img.

> + if args.directory is not None:
> + # If args.device is a path to a device (/dev/) then this is an error
> + if "--mmc" in sys.argv:
> + raise IncompatableOptions("--directory option incompatable with "
> + "option --mmc")
> +
> + # If directory is used as well as having a full path (rather than just
> + # a file name or relative path) in args.device, this is an error.
> + if re.search(r"^/", args.device):
> + raise IncompatableOptions("--directory option incompatable with "

 IncompatibleOptions + "incompatible"

 We could actually support absolute --image-file with --directory and
 just output the image where the user wants it, but I don't really care
 strongly about the behavior in that particular use case.

 Generally ok with the design apart of the minor comments here, but
 I have one objection: I think the argument validation / mangling should
 happen when parsing the cmdline rather than in boards code.

 Could you just include prep_media_path logic as part of the cmdline
 args validation? This would also remove the need for a special
 exception down the road.

 Otherwise good, thanks!

--
Loïc Minier

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

On Tue, Apr 17, 2012 at 3:37 PM, Loïc Minier <email address hidden> wrote:
>> +def prep_media_path(args, board_config):
>> +
>> +    # If args.device isn't set, generate a sensible default file name and
>> +    # tell the user
>> +    if not args.device:
>> +        args.device = board_config.board + ".img"
>> +        print "Setting destination file name to", args.device
>
>  I think it would be more stable to just call it mmc.img or sd.img.

+1, that would help scripting the output later on.

>> +    if args.directory is not None:
>> +        # If args.device is a path to a device (/dev/) then this is an error
>> +        if "--mmc" in sys.argv:
>> +            raise IncompatableOptions("--directory option incompatable with "
>> +                                      "option --mmc")
>> +
>> +        # If directory is used as well as having a full path (rather than just
>> +        # a file name or relative path) in args.device, this is an error.
>> +        if re.search(r"^/", args.device):
>> +            raise IncompatableOptions("--directory option incompatable with "
>
>  IncompatibleOptions + "incompatible"
>
>  We could actually support absolute --image-file with --directory and
>  just output the image where the user wants it, but I don't really care
>  strongly about the behavior in that particular use case.
>
>  Generally ok with the design apart of the minor comments here, but
>  I have one objection: I think the argument validation / mangling should
>  happen when parsing the cmdline rather than in boards code.

+1

>  Otherwise good, thanks!

+1

512. By James Tunnicliffe

Fixed spelling of IncompatibleOptions

513. By James Tunnicliffe

Renamed --directory option to --output-directory. Set default file name for an image to sd.img

514. By James Tunnicliffe

Moved defaulting of args.device into ArgumentParser set up.

515. By James Tunnicliffe

Moved additional option checks into their own function (additional_option_checks).

516. By James Tunnicliffe

remove .idea ignore

517. By James Tunnicliffe

Removed unused directory variable.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2010-12-06 23:58:41 +0000
+++ .bzrignore 2012-04-18 13:29:18 +0000
@@ -1,2 +1,3 @@
1.testrepository1.testrepository
2_trial_temp2_trial_temp
3.idea
34
=== modified file 'linaro-media-create'
--- linaro-media-create 2012-01-17 14:50:47 +0000
+++ linaro-media-create 2012-04-18 13:29:18 +0000
@@ -48,6 +48,9 @@
48 is_arm_host,48 is_arm_host,
49 check_file_integrity_and_log_errors,49 check_file_integrity_and_log_errors,
50 path_in_tarfile_exists,50 path_in_tarfile_exists,
51 IncompatibleOptions,
52 prep_media_path,
53 additional_option_checks,
51 )54 )
5255
53# Just define the global variables56# Just define the global variables
@@ -97,6 +100,37 @@
97 parser = get_args_parser()100 parser = get_args_parser()
98 args = parser.parse_args()101 args = parser.parse_args()
99102
103 try:
104 additional_option_checks(args)
105 except IncompatibleOptions as e:
106 parser.print_help()
107 print >> sys.stderr, "\nError:", e.value
108 sys.exit(1)
109
110 board_config = board_configs[args.board]
111 board_config.set_metadata(args.hwpacks)
112 board_config.set_board(args.board)
113 board_config.add_boot_args(args.extra_boot_args)
114 board_config.add_boot_args_from_file(args.extra_boot_args_file)
115
116 media = Media(prep_media_path(args))
117
118 if media.is_block_device:
119 if not board_config.supports_writing_to_mmc:
120 print "The board '%s' does not support the --mmc option. Please use "\
121 "--image_file to create an image file for this board." % args.board
122 sys.exit(1)
123 if not confirm_device_selection_and_ensure_it_is_ready(args.device,
124 args.nocheck_mmc):
125 sys.exit(1)
126 elif not args.should_format_rootfs or not args.should_format_bootfs:
127 print ("Do not use --no-boot or --no-part in conjunction with "
128 "--image_file.")
129 sys.exit(1)
130 else:
131 # All good, move on.
132 pass
133
100 ch = logging.StreamHandler()134 ch = logging.StreamHandler()
101 ch.setLevel(logging.INFO)135 ch.setLevel(logging.INFO)
102 formatter = logging.Formatter("%(message)s")136 formatter = logging.Formatter("%(message)s")
@@ -116,12 +150,6 @@
116 BOOT_DISK = os.path.join(TMP_DIR, 'boot-disc')150 BOOT_DISK = os.path.join(TMP_DIR, 'boot-disc')
117 ROOT_DISK = os.path.join(TMP_DIR, 'root-disc')151 ROOT_DISK = os.path.join(TMP_DIR, 'root-disc')
118152
119 board_config = board_configs[args.board]
120 board_config.set_metadata(args.hwpacks)
121 board_config.set_board(args.board)
122 board_config.add_boot_args(args.extra_boot_args)
123 board_config.add_boot_args_from_file(args.extra_boot_args_file)
124
125 ensure_required_commands(args)153 ensure_required_commands(args)
126154
127 sig_file_list = args.hwpacksigs[:]155 sig_file_list = args.hwpacksigs[:]
@@ -134,24 +162,8 @@
134 sig_file_list, args.binary, args.hwpacks)162 sig_file_list, args.binary, args.hwpacks)
135 if not files_ok:163 if not files_ok:
136 sys.exit(1)164 sys.exit(1)
137 165
138 atexit.register(cleanup_tempdir)166 atexit.register(cleanup_tempdir)
139 media = Media(args.device)
140 if media.is_block_device:
141 if not board_config.supports_writing_to_mmc:
142 print "The board '%s' does not support the --mmc option. Please use " \
143 "--image_file to create an image file for this board." % args.board
144 sys.exit(1)
145 if not confirm_device_selection_and_ensure_it_is_ready(args.device,
146 args.nocheck_mmc):
147 sys.exit(1)
148 elif not args.should_format_rootfs or not args.should_format_bootfs:
149 print ("Do not use --no-boot or --no-part in conjunction with "
150 "--image_file.")
151 sys.exit(1)
152 else:
153 # All good, move on.
154 pass
155167
156 unpack_binary_tarball(args.binary, TMP_DIR)168 unpack_binary_tarball(args.binary, TMP_DIR)
157169
@@ -174,7 +186,7 @@
174186
175 if args.should_format_bootfs:187 if args.should_format_bootfs:
176 board_config.populate_boot(188 board_config.populate_boot(
177 ROOTFS_DIR, rootfs_uuid, boot_partition, BOOT_DISK, args.device,189 ROOTFS_DIR, rootfs_uuid, boot_partition, BOOT_DISK, media.path,
178 args.is_live, args.is_lowmem, args.consoles)190 args.is_live, args.is_lowmem, args.consoles)
179191
180 if args.should_format_rootfs:192 if args.should_format_rootfs:
@@ -185,4 +197,4 @@
185 rootfs_uuid, create_swap, str(args.swap_file),197 rootfs_uuid, create_swap, str(args.swap_file),
186 board_config.mmc_part_offset, board_config)198 board_config.mmc_part_offset, board_config)
187199
188 print "Done creating Linaro image on %s" % args.device200 print "Done creating Linaro image on %s" % media.path
189201
=== modified file 'linaro_image_tools/media_create/__init__.py'
--- linaro_image_tools/media_create/__init__.py 2012-01-19 06:31:50 +0000
+++ linaro_image_tools/media_create/__init__.py 2012-04-18 13:29:18 +0000
@@ -77,12 +77,17 @@
77def get_args_parser():77def get_args_parser():
78 """Get the ArgumentParser for the arguments given on the command line."""78 """Get the ArgumentParser for the arguments given on the command line."""
79 parser = argparse.ArgumentParser(version='%(prog)s ' + get_version())79 parser = argparse.ArgumentParser(version='%(prog)s ' + get_version())
80 group = parser.add_mutually_exclusive_group(required=True)80 group = parser.add_mutually_exclusive_group()
81 group.add_argument(81 group.add_argument(
82 '--mmc', dest='device', help='The storage device to use.')82 '--mmc', dest='device', default="sd.img",
83 group.add_argument(83 help='The storage device to use.')
84 '--image-file', '--image_file', dest='device',84 group.add_argument(
85 help='File where we should write the QEMU image.')85 '--image-file', '--image_file', dest='device', default="sd.img",
86 help='File where we should write an image file (defaults to sd.img '
87 'if neither --image-file or --mmc are specified.)')
88 parser.add_argument(
89 '--output-directory', dest='directory',
90 help='Directory where image and accessories should be written to.')
86 parser.add_argument(91 parser.add_argument(
87 '--dev', required=True, dest='board', choices=KNOWN_BOARDS,92 '--dev', required=True, dest='board', choices=KNOWN_BOARDS,
88 help='Generate an SD card or image for the given board.')93 help='Generate an SD card or image for the given board.')
8994
=== modified file 'linaro_image_tools/media_create/boards.py'
--- linaro_image_tools/media_create/boards.py 2012-04-17 16:22:09 +0000
+++ linaro_image_tools/media_create/boards.py 2012-04-18 13:29:18 +0000
@@ -1337,6 +1337,33 @@
1337 pass1337 pass
13381338
13391339
1340class FastModelConfig(BoardConfig):
1341 supports_writing_to_mmc = False
1342
1343 @classmethod
1344 def _get_bootcmd(cls, d_img_data):
1345 """Get the bootcmd for FastModel.
1346
1347 We override this as we don't do uboot.
1348 """
1349 return ""
1350
1351 @classmethod
1352 def _make_boot_files_v2(cls, boot_env, chroot_dir, boot_dir,
1353 boot_device_or_file, k_img_data, i_img_data,
1354 d_img_data):
1355 logger = logging.getLogger("linaro_image_tools")
1356 logger.info("WTF=%s." % boot_device_or_file )
1357 output_dir=os.path.dirname(boot_device_or_file)
1358 cmd = [ "cp", "-v", _get_file_matching("%s/boot/img.axf" % chroot_dir), output_dir ]
1359 proc = cmd_runner.run(cmd, as_root=True)
1360 proc.wait()
1361 cmd = [ "cp", "-v", k_img_data, i_img_data, d_img_data, output_dir ]
1362 proc = cmd_runner.run(cmd, as_root=True)
1363 proc.wait()
1364 return
1365
1366
1340class SamsungConfig(BoardConfig):1367class SamsungConfig(BoardConfig):
1341 @classproperty1368 @classproperty
1342 def extra_serial_opts(cls):1369 def extra_serial_opts(cls):
@@ -1542,6 +1569,7 @@
1542 'panda': PandaConfig,1569 'panda': PandaConfig,
1543 'vexpress': VexpressConfig,1570 'vexpress': VexpressConfig,
1544 'vexpress-a9': VexpressA9Config,1571 'vexpress-a9': VexpressA9Config,
1572 'fastmodel': FastModelConfig,
1545 'ux500': Ux500Config,1573 'ux500': Ux500Config,
1546 'snowball_sd': SnowballSdConfig,1574 'snowball_sd': SnowballSdConfig,
1547 'snowball_emmc': SnowballEmmcConfig,1575 'snowball_emmc': SnowballEmmcConfig,
15481576
=== modified file 'linaro_image_tools/media_create/partitions.py'
--- linaro_image_tools/media_create/partitions.py 2012-01-17 14:19:19 +0000
+++ linaro_image_tools/media_create/partitions.py 2012-04-18 13:29:18 +0000
@@ -590,4 +590,5 @@
590590
591 def __init__(self, path):591 def __init__(self, path):
592 self.path = path592 self.path = path
593 self.directory = None
593 self.is_block_device = path.startswith('/dev/')594 self.is_block_device = path.startswith('/dev/')
594595
=== modified file 'linaro_image_tools/tests/test_utils.py'
--- linaro_image_tools/tests/test_utils.py 2011-10-12 09:54:29 +0000
+++ linaro_image_tools/tests/test_utils.py 2012-04-18 13:29:18 +0000
@@ -41,9 +41,11 @@
41 verify_file_integrity,41 verify_file_integrity,
42 check_file_integrity_and_log_errors,42 check_file_integrity_and_log_errors,
43 path_in_tarfile_exists,43 path_in_tarfile_exists,
44 IncompatibleOptions,
45 prep_media_path,
46 additional_option_checks,
44 )47 )
4548
46
47sudo_args = " ".join(cmd_runner.SUDO_ARGS)49sudo_args = " ".join(cmd_runner.SUDO_ARGS)
4850
4951
@@ -260,3 +262,44 @@
260 UnableToFindPackageProvidingCommand,262 UnableToFindPackageProvidingCommand,
261 install_package_providing, 'mkfs.lean')263 install_package_providing, 'mkfs.lean')
262264
265
266class Args():
267 def __init__(self, directory, device, board):
268 self.directory = directory
269 self.device = device
270 self.board = board
271
272
273class TestPrepMediaPath(TestCaseWithFixtures):
274
275 def test_prep_media_path(self):
276 self.useFixture(MockSomethingFixture(os.path, 'abspath', lambda x: x))
277 self.useFixture(MockSomethingFixture(os, "makedirs", lambda x: x))
278
279 self.assertEqual("testdevice",
280 prep_media_path(Args(directory=None,
281 device="testdevice",
282 board="testboard")))
283
284 self.assertEqual("/foo/bar/testdevice",
285 prep_media_path(Args(directory="/foo/bar",
286 device="testdevice",
287 board="testboard")))
288
289class TestPrepMediaPath(TestCaseWithFixtures):
290
291 def test_additional_option_checks(self):
292 self.useFixture(MockSomethingFixture(os.path, 'abspath', lambda x: x))
293 self.useFixture(MockSomethingFixture(os, "makedirs", lambda x: x))
294
295 self.assertRaises(IncompatibleOptions, additional_option_checks,
296 Args(directory="/foo/bar",
297 device="/testdevice",
298 board="testboard"))
299
300 sys.argv.append("--mmc")
301 self.assertRaises(IncompatibleOptions, additional_option_checks,
302 Args(directory="/foo/bar",
303 device="testdevice",
304 board="testboard"))
305 sys.argv.remove("--mmc")
263306
=== modified file 'linaro_image_tools/utils.py'
--- linaro_image_tools/utils.py 2011-11-28 12:49:14 +0000
+++ linaro_image_tools/utils.py 2012-04-18 13:29:18 +0000
@@ -247,5 +247,41 @@
247 return prefer_dir247 return prefer_dir
248248
249249
250def prep_media_path(args):
251 if args.directory is not None:
252 loc = os.path.abspath(args.directory)
253 try:
254 os.makedirs(loc)
255 except OSError:
256 pass # Directory exists.
257
258 path = os.path.join(loc, args.device)
259 else:
260 path = args.device
261
262 return path
263
264
250class UnableToFindPackageProvidingCommand(Exception):265class UnableToFindPackageProvidingCommand(Exception):
251 """We can't find a package which provides the given command."""266 """We can't find a package which provides the given command."""
267
268
269class IncompatibleOptions(Exception):
270 def __init__(self, value):
271 self.value = value
272
273 def __str__(self):
274 return repr(self.value)
275
276def additional_option_checks(args):
277 if args.directory is not None:
278 # If args.device is a path to a device (/dev/) then this is an error
279 if "--mmc" in sys.argv:
280 raise IncompatibleOptions("--directory option incompatable with "
281 "option --mmc")
282
283 # If directory is used as well as having a full path (rather than just
284 # a file name or relative path) in args.device, this is an error.
285 if re.search(r"^/", args.device):
286 raise IncompatibleOptions("--directory option incompatable with "
287 "a full path in --image-file")

Subscribers

People subscribed via source and target branches