Merge lp:~dooferlad/linaro-image-tools/add-directory-option into lp:linaro-image-tools/11.11
- add-directory-option
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 508 |
Proposed branch: | lp:~dooferlad/linaro-image-tools/add-directory-option |
Merge into: | lp:linaro-image-tools/11.11 |
Diff against target: |
287 lines (+156/-32) 5 files modified
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/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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Loïc Minier (community) | Approve | ||
Review via email: mp+102518@code.launchpad.net |
This proposal supersedes a proposal from 2012-04-17.
Commit message
Description of the change
Slightly modified patch from https:/
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.
Updated(2):
Fixed spelling of IncompatibleOpt
Renamed --directory option to --output-directory. Set default file name for an image to sd.img.
Moved defaulting of args.device into ArgumentParser set up.
Moved additional option checks into their own function (additional_
I am unable to move more argument processing into media_create/
Loïc Minier (lool) wrote : Posted in a previous version of this proposal | # |
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.
>> + raise BoardAbilityNot
>> + "--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
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal | # |
Oops, forgot to delete the outputs_directory flag. Hang on...
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal | # |
OK. Done.
Loïc Minier (lool) wrote : Posted in a previous version of this proposal | # |
On Tue, Apr 17, 2012, James Tunnicliffe wrote:
> + IncompatableOpt
IncompatibleOp
> + parser.
> + '--directory', dest='directory',
> + help='Directory where image and accessories should be written to.')
--output-
> + outputs_directory = False
not too nice as property; perhaps outputs_
Or expected_artifacts = 1?
> +def prep_media_
> +
> + # 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 IncompatableOpt
> + "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 IncompatableOpt
IncompatibleOp
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
Ricardo Salveti (rsalveti) wrote : Posted in a previous version of this proposal | # |
On Tue, Apr 17, 2012 at 3:37 PM, Loïc Minier <email address hidden> wrote:
>> +def prep_media_
>> +
>> + # 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 IncompatableOpt
>> + "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 IncompatableOpt
>
> 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
- 516. By James Tunnicliffe
-
remove .idea ignore
Loïc Minier (lool) wrote : | # |
review approve
Seems almost good to go except minor points below:
On Wed, Apr 18, 2012, James Tunnicliffe wrote:
> + try:
> + additional_
I would just include the logic here rather than adding a separate
function + Exception, but up to you
> === modified file 'linaro_
> --- linaro_
> +++ linaro_
> @@ -590,4 +590,5 @@
>
> def __init__(self, path):
> self.path = path
> + self.directory = None
> self.is_
Hmm shouldn't you take directory in __init__?
> +class Args():
> + def __init__(self, directory, device, board):
> + self.directory = directory
> + self.device = device
> + self.board = board
Don't think board is needed anymore, but you shouldn't you just use a
Media() instance?
--
Loïc Minier
- 517. By James Tunnicliffe
-
Removed unused directory variable.
James Tunnicliffe (dooferlad) wrote : | # |
On 18 April 2012 14:55, Loïc Minier <email address hidden> wrote:
> Review: Approve
>
> review approve
>
> Seems almost good to go except minor points below:
>
> On Wed, Apr 18, 2012, James Tunnicliffe wrote:
>> + try:
>> + additional_
>
> I would just include the logic here rather than adding a separate
> function + Exception, but up to you
I just got to write tests for it this way.
>> === modified file 'linaro_
>> --- linaro_
>> +++ linaro_
>> @@ -590,4 +590,5 @@
>>
>> def __init__(self, path):
>> self.path = path
>> + self.directory = None
>> self.is_
>
> Hmm shouldn't you take directory in __init__?
Actually, I can't find anywhere it is used. Deleted.
>> +class Args():
>> + def __init__(self, directory, device, board):
>> + self.directory = directory
>> + self.device = device
>> + self.board = board
>
> Don't think board is needed anymore, but you shouldn't you just use a
> Media() instance?
It is needed as a fake version of what comes out of the arguments
parser. It isn't the same as Media.
--
James Tunnicliffe
Preview Diff
1 | === modified file 'linaro-media-create' |
2 | --- linaro-media-create 2012-01-17 14:50:47 +0000 |
3 | +++ linaro-media-create 2012-04-18 14:21:19 +0000 |
4 | @@ -48,6 +48,9 @@ |
5 | is_arm_host, |
6 | check_file_integrity_and_log_errors, |
7 | path_in_tarfile_exists, |
8 | + IncompatibleOptions, |
9 | + prep_media_path, |
10 | + additional_option_checks, |
11 | ) |
12 | |
13 | # Just define the global variables |
14 | @@ -97,6 +100,37 @@ |
15 | parser = get_args_parser() |
16 | args = parser.parse_args() |
17 | |
18 | + try: |
19 | + additional_option_checks(args) |
20 | + except IncompatibleOptions as e: |
21 | + parser.print_help() |
22 | + print >> sys.stderr, "\nError:", e.value |
23 | + sys.exit(1) |
24 | + |
25 | + board_config = board_configs[args.board] |
26 | + board_config.set_metadata(args.hwpacks) |
27 | + board_config.set_board(args.board) |
28 | + board_config.add_boot_args(args.extra_boot_args) |
29 | + board_config.add_boot_args_from_file(args.extra_boot_args_file) |
30 | + |
31 | + media = Media(prep_media_path(args)) |
32 | + |
33 | + if media.is_block_device: |
34 | + if not board_config.supports_writing_to_mmc: |
35 | + print "The board '%s' does not support the --mmc option. Please use "\ |
36 | + "--image_file to create an image file for this board." % args.board |
37 | + sys.exit(1) |
38 | + if not confirm_device_selection_and_ensure_it_is_ready(args.device, |
39 | + args.nocheck_mmc): |
40 | + sys.exit(1) |
41 | + elif not args.should_format_rootfs or not args.should_format_bootfs: |
42 | + print ("Do not use --no-boot or --no-part in conjunction with " |
43 | + "--image_file.") |
44 | + sys.exit(1) |
45 | + else: |
46 | + # All good, move on. |
47 | + pass |
48 | + |
49 | ch = logging.StreamHandler() |
50 | ch.setLevel(logging.INFO) |
51 | formatter = logging.Formatter("%(message)s") |
52 | @@ -116,12 +150,6 @@ |
53 | BOOT_DISK = os.path.join(TMP_DIR, 'boot-disc') |
54 | ROOT_DISK = os.path.join(TMP_DIR, 'root-disc') |
55 | |
56 | - board_config = board_configs[args.board] |
57 | - board_config.set_metadata(args.hwpacks) |
58 | - board_config.set_board(args.board) |
59 | - board_config.add_boot_args(args.extra_boot_args) |
60 | - board_config.add_boot_args_from_file(args.extra_boot_args_file) |
61 | - |
62 | ensure_required_commands(args) |
63 | |
64 | sig_file_list = args.hwpacksigs[:] |
65 | @@ -134,24 +162,8 @@ |
66 | sig_file_list, args.binary, args.hwpacks) |
67 | if not files_ok: |
68 | sys.exit(1) |
69 | - |
70 | + |
71 | atexit.register(cleanup_tempdir) |
72 | - media = Media(args.device) |
73 | - if media.is_block_device: |
74 | - if not board_config.supports_writing_to_mmc: |
75 | - print "The board '%s' does not support the --mmc option. Please use " \ |
76 | - "--image_file to create an image file for this board." % args.board |
77 | - sys.exit(1) |
78 | - if not confirm_device_selection_and_ensure_it_is_ready(args.device, |
79 | - args.nocheck_mmc): |
80 | - sys.exit(1) |
81 | - elif not args.should_format_rootfs or not args.should_format_bootfs: |
82 | - print ("Do not use --no-boot or --no-part in conjunction with " |
83 | - "--image_file.") |
84 | - sys.exit(1) |
85 | - else: |
86 | - # All good, move on. |
87 | - pass |
88 | |
89 | unpack_binary_tarball(args.binary, TMP_DIR) |
90 | |
91 | @@ -174,7 +186,7 @@ |
92 | |
93 | if args.should_format_bootfs: |
94 | board_config.populate_boot( |
95 | - ROOTFS_DIR, rootfs_uuid, boot_partition, BOOT_DISK, args.device, |
96 | + ROOTFS_DIR, rootfs_uuid, boot_partition, BOOT_DISK, media.path, |
97 | args.is_live, args.is_lowmem, args.consoles) |
98 | |
99 | if args.should_format_rootfs: |
100 | @@ -185,4 +197,4 @@ |
101 | rootfs_uuid, create_swap, str(args.swap_file), |
102 | board_config.mmc_part_offset, board_config) |
103 | |
104 | - print "Done creating Linaro image on %s" % args.device |
105 | + print "Done creating Linaro image on %s" % media.path |
106 | |
107 | === modified file 'linaro_image_tools/media_create/__init__.py' |
108 | --- linaro_image_tools/media_create/__init__.py 2012-01-19 06:31:50 +0000 |
109 | +++ linaro_image_tools/media_create/__init__.py 2012-04-18 14:21:19 +0000 |
110 | @@ -77,12 +77,17 @@ |
111 | def get_args_parser(): |
112 | """Get the ArgumentParser for the arguments given on the command line.""" |
113 | parser = argparse.ArgumentParser(version='%(prog)s ' + get_version()) |
114 | - group = parser.add_mutually_exclusive_group(required=True) |
115 | - group.add_argument( |
116 | - '--mmc', dest='device', help='The storage device to use.') |
117 | - group.add_argument( |
118 | - '--image-file', '--image_file', dest='device', |
119 | - help='File where we should write the QEMU image.') |
120 | + group = parser.add_mutually_exclusive_group() |
121 | + group.add_argument( |
122 | + '--mmc', dest='device', default="sd.img", |
123 | + help='The storage device to use.') |
124 | + group.add_argument( |
125 | + '--image-file', '--image_file', dest='device', default="sd.img", |
126 | + help='File where we should write an image file (defaults to sd.img ' |
127 | + 'if neither --image-file or --mmc are specified.)') |
128 | + parser.add_argument( |
129 | + '--output-directory', dest='directory', |
130 | + help='Directory where image and accessories should be written to.') |
131 | parser.add_argument( |
132 | '--dev', required=True, dest='board', choices=KNOWN_BOARDS, |
133 | help='Generate an SD card or image for the given board.') |
134 | |
135 | === modified file 'linaro_image_tools/media_create/boards.py' |
136 | --- linaro_image_tools/media_create/boards.py 2012-04-17 16:22:09 +0000 |
137 | +++ linaro_image_tools/media_create/boards.py 2012-04-18 14:21:19 +0000 |
138 | @@ -1337,6 +1337,33 @@ |
139 | pass |
140 | |
141 | |
142 | +class FastModelConfig(BoardConfig): |
143 | + supports_writing_to_mmc = False |
144 | + |
145 | + @classmethod |
146 | + def _get_bootcmd(cls, d_img_data): |
147 | + """Get the bootcmd for FastModel. |
148 | + |
149 | + We override this as we don't do uboot. |
150 | + """ |
151 | + return "" |
152 | + |
153 | + @classmethod |
154 | + def _make_boot_files_v2(cls, boot_env, chroot_dir, boot_dir, |
155 | + boot_device_or_file, k_img_data, i_img_data, |
156 | + d_img_data): |
157 | + logger = logging.getLogger("linaro_image_tools") |
158 | + logger.info("WTF=%s." % boot_device_or_file ) |
159 | + output_dir=os.path.dirname(boot_device_or_file) |
160 | + cmd = [ "cp", "-v", _get_file_matching("%s/boot/img.axf" % chroot_dir), output_dir ] |
161 | + proc = cmd_runner.run(cmd, as_root=True) |
162 | + proc.wait() |
163 | + cmd = [ "cp", "-v", k_img_data, i_img_data, d_img_data, output_dir ] |
164 | + proc = cmd_runner.run(cmd, as_root=True) |
165 | + proc.wait() |
166 | + return |
167 | + |
168 | + |
169 | class SamsungConfig(BoardConfig): |
170 | @classproperty |
171 | def extra_serial_opts(cls): |
172 | @@ -1542,6 +1569,7 @@ |
173 | 'panda': PandaConfig, |
174 | 'vexpress': VexpressConfig, |
175 | 'vexpress-a9': VexpressA9Config, |
176 | + 'fastmodel': FastModelConfig, |
177 | 'ux500': Ux500Config, |
178 | 'snowball_sd': SnowballSdConfig, |
179 | 'snowball_emmc': SnowballEmmcConfig, |
180 | |
181 | === modified file 'linaro_image_tools/tests/test_utils.py' |
182 | --- linaro_image_tools/tests/test_utils.py 2011-10-12 09:54:29 +0000 |
183 | +++ linaro_image_tools/tests/test_utils.py 2012-04-18 14:21:19 +0000 |
184 | @@ -41,9 +41,11 @@ |
185 | verify_file_integrity, |
186 | check_file_integrity_and_log_errors, |
187 | path_in_tarfile_exists, |
188 | + IncompatibleOptions, |
189 | + prep_media_path, |
190 | + additional_option_checks, |
191 | ) |
192 | |
193 | - |
194 | sudo_args = " ".join(cmd_runner.SUDO_ARGS) |
195 | |
196 | |
197 | @@ -260,3 +262,44 @@ |
198 | UnableToFindPackageProvidingCommand, |
199 | install_package_providing, 'mkfs.lean') |
200 | |
201 | + |
202 | +class Args(): |
203 | + def __init__(self, directory, device, board): |
204 | + self.directory = directory |
205 | + self.device = device |
206 | + self.board = board |
207 | + |
208 | + |
209 | +class TestPrepMediaPath(TestCaseWithFixtures): |
210 | + |
211 | + def test_prep_media_path(self): |
212 | + self.useFixture(MockSomethingFixture(os.path, 'abspath', lambda x: x)) |
213 | + self.useFixture(MockSomethingFixture(os, "makedirs", lambda x: x)) |
214 | + |
215 | + self.assertEqual("testdevice", |
216 | + prep_media_path(Args(directory=None, |
217 | + device="testdevice", |
218 | + board="testboard"))) |
219 | + |
220 | + self.assertEqual("/foo/bar/testdevice", |
221 | + prep_media_path(Args(directory="/foo/bar", |
222 | + device="testdevice", |
223 | + board="testboard"))) |
224 | + |
225 | +class TestPrepMediaPath(TestCaseWithFixtures): |
226 | + |
227 | + def test_additional_option_checks(self): |
228 | + self.useFixture(MockSomethingFixture(os.path, 'abspath', lambda x: x)) |
229 | + self.useFixture(MockSomethingFixture(os, "makedirs", lambda x: x)) |
230 | + |
231 | + self.assertRaises(IncompatibleOptions, additional_option_checks, |
232 | + Args(directory="/foo/bar", |
233 | + device="/testdevice", |
234 | + board="testboard")) |
235 | + |
236 | + sys.argv.append("--mmc") |
237 | + self.assertRaises(IncompatibleOptions, additional_option_checks, |
238 | + Args(directory="/foo/bar", |
239 | + device="testdevice", |
240 | + board="testboard")) |
241 | + sys.argv.remove("--mmc") |
242 | |
243 | === modified file 'linaro_image_tools/utils.py' |
244 | --- linaro_image_tools/utils.py 2011-11-28 12:49:14 +0000 |
245 | +++ linaro_image_tools/utils.py 2012-04-18 14:21:19 +0000 |
246 | @@ -247,5 +247,41 @@ |
247 | return prefer_dir |
248 | |
249 | |
250 | +def 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 | + |
265 | class UnableToFindPackageProvidingCommand(Exception): |
266 | """We can't find a package which provides the given command.""" |
267 | + |
268 | + |
269 | +class IncompatibleOptions(Exception): |
270 | + def __init__(self, value): |
271 | + self.value = value |
272 | + |
273 | + def __str__(self): |
274 | + return repr(self.value) |
275 | + |
276 | +def 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") |
On Mon, Apr 16, 2012, James Tunnicliffe wrote: outputs_ directory: Met("The board '%s' does not support the"
[...]
> + if args.directory is not None:
> + if not board_config.
> + raise BoardAbilityNot
> + "--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