summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/kickstart/custom_commands/partition.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/mic/kickstart/custom_commands/partition.py')
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/partition.py482
1 files changed, 482 insertions, 0 deletions
diff --git a/scripts/lib/mic/kickstart/custom_commands/partition.py b/scripts/lib/mic/kickstart/custom_commands/partition.py
new file mode 100644
index 0000000000..450d2d492d
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/partition.py
@@ -0,0 +1,482 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module provides the OpenEmbedded partition object definitions.
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27import shutil
28
29from pykickstart.commands.partition import *
30from mic.utils.oe.misc import *
31from mic.kickstart.custom_commands import *
32from mic.plugin import pluginmgr
33
34import os
35from mic.utils.oe.package_manager import *
36
37partition_methods = {
38 "do_install_pkgs":None,
39 "do_stage_partition":None,
40 "do_prepare_partition":None,
41 "do_configure_partition":None,
42}
43
44class Wic_PartData(Mic_PartData):
45 removedKeywords = Mic_PartData.removedKeywords
46 removedAttrs = Mic_PartData.removedAttrs
47
48 def __init__(self, *args, **kwargs):
49 Mic_PartData.__init__(self, *args, **kwargs)
50 self.deleteRemovedAttrs()
51 self.source = kwargs.get("source", None)
52 self.rootfs = kwargs.get("rootfs-dir", None)
53 self.source_file = ""
54 self.size = 0
55
56 def _getArgsAsStr(self):
57 retval = Mic_PartData._getArgsAsStr(self)
58
59 if self.source:
60 retval += " --source=%s" % self.source
61 if self.rootfs:
62 retval += " --rootfs-dir=%s" % self.rootfs
63
64 return retval
65
66 def get_rootfs(self):
67 """
68 Acessor for rootfs dir
69 """
70 return self.rootfs
71
72 def set_rootfs(self, rootfs):
73 """
74 Acessor for actual rootfs dir, which must be set by source
75 plugins.
76 """
77 self.rootfs = rootfs
78
79 def get_size(self):
80 """
81 Accessor for partition size, 0 or --size before set_size().
82 """
83 return self.size
84
85 def set_size(self, size):
86 """
87 Accessor for actual partition size, which must be set by source
88 plugins.
89 """
90 self.size = size
91
92 def set_source_file(self, source_file):
93 """
94 Accessor for source_file, the location of the generated partition
95 image, which must be set by source plugins.
96 """
97 self.source_file = source_file
98
99 def get_extra_block_count(self, current_blocks):
100 """
101 The --size param is reflected in self.size (in MB), and we already
102 have current_blocks (1k) blocks, calculate and return the
103 number of (1k) blocks we need to add to get to --size, 0 if
104 we're already there or beyond.
105 """
106 msger.debug("Requested partition size for %s: %d" % \
107 (self.mountpoint, self.size))
108
109 if not self.size:
110 return 0
111
112 requested_blocks = self.size * 1024
113
114 msger.debug("Requested blocks %d, current_blocks %d" % \
115 (requested_blocks, current_blocks))
116
117 if requested_blocks > current_blocks:
118 return requested_blocks - current_blocks
119 else:
120 return 0
121
122 def install_pkgs(self, creator, cr_workdir, oe_builddir, rootfs_dir,
123 bootimg_dir, kernel_dir, native_sysroot):
124 """
125 Prepare content for individual partitions, installing packages.
126 """
127
128 if not self.source:
129 return
130
131 self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods)
132 self._source_methods["do_install_pkgs"](self, creator,
133 cr_workdir,
134 oe_builddir,
135 rootfs_dir,
136 bootimg_dir,
137 kernel_dir,
138 native_sysroot)
139
140 def install_pkgs_ipk(self, cr_workdir, oe_builddir, rootfs_dir,
141 native_sysroot, packages, repourl):
142 """
143 Install packages specified into wks file using opkg package manager.
144 This method is dependend on bb module.
145 """
146
147 gVar = {}
148 gVar["DEPLOY_DIR_IPK"] = os.path.join(oe_builddir, "tmp/deploy/ipk")
149
150 # Run postinstall scripts even in offline mode
151 # Use the arch priority package rather than higher version one if more than one candidate is found.
152 #d.setVar("OPKG_ARGS", "--force_postinstall --prefer-arch-to-version")
153 gVar["OPKG_ARGS"] = "--force_postinstall"
154
155 # OPKG path relative to /output_path
156 gVar["OPKGLIBDIR"] = "var/lib"
157
158 source_url = repourl.split()
159
160 # Generate feed uri's names, it doesn't seem to matter what name they have
161 feed_uris = ""
162 cnt = 0
163 archs = ""
164 for url in source_url:
165 feed_uris += "cl_def_feed%d##%s\n" % (cnt, url)
166 cnt += 1
167 head, tail = os.path.split(url)
168 archs += " " + tail
169
170 # IPK_FEED_URIS with special formating defines the URI's used as source for packages
171 gVar['IPK_FEED_URIS'] = feed_uris
172
173 gVar['BUILD_IMAGES_FROM_FEEDS'] = "1"
174
175 # We need to provide sysroot for utilities
176 gVar['STAGING_DIR_NATIVE'] = native_sysroot
177
178 # Set WORKDIR for output
179 gVar['WORKDIR'] = cr_workdir
180
181 # Set TMPDIR for output
182 gVar['TMPDIR'] = os.path.join(cr_workdir, "tmp")
183
184 if 'ROOTFS_DIR' in rootfs_dir:
185 target_dir = rootfs_dir['ROOTFS_DIR']
186 elif os.path.isdir(rootfs_dir):
187 target_dir = rootfs_dir
188 else:
189 msg = "Couldn't find --rootfs-dir=%s connection"
190 msg += " or it is not a valid path, exiting"
191 msger.error(msg % rootfs_dir)
192
193 # Need native sysroot /usr/bin/ for opkg-cl
194 # chnage PATH var to avoid issues with host tools
195 defpath = os.environ['PATH']
196 os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"
197
198 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
199 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % target_dir
200 pseudo += "export PSEUDO_PASSWD=%s;" % target_dir
201 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
202 pseudo += "%s/usr/bin/pseudo " % native_sysroot
203
204 pm = WicOpkgPM(gVar,
205 target_dir,
206 'opkg.conf',
207 archs,
208 pseudo,
209 native_sysroot)
210
211 pm.update()
212
213 pm.install(packages)
214
215 os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"
216
217
218 def prepare(self, cr, cr_workdir, oe_builddir, rootfs_dir, bootimg_dir,
219 kernel_dir, native_sysroot):
220 """
221 Prepare content for individual partitions, depending on
222 partition command parameters.
223 """
224 if not self.source:
225 if self.fstype and self.fstype == "swap":
226 self.prepare_swap_partition(cr_workdir, oe_builddir,
227 native_sysroot)
228 elif self.fstype:
229 self.prepare_empty_partition(cr_workdir, oe_builddir,
230 native_sysroot)
231 return
232
233 self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods)
234 self._source_methods["do_configure_partition"](self, cr, cr_workdir,
235 oe_builddir,
236 bootimg_dir,
237 kernel_dir,
238 native_sysroot)
239 self._source_methods["do_stage_partition"](self, cr, cr_workdir,
240 oe_builddir,
241 bootimg_dir, kernel_dir,
242 native_sysroot)
243 self._source_methods["do_prepare_partition"](self, cr, cr_workdir,
244 oe_builddir,
245 bootimg_dir, kernel_dir, rootfs_dir,
246 native_sysroot)
247
248 def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir,
249 rootfs_dir):
250 """
251 Handle an already-created partition e.g. xxx.ext3
252 """
253 rootfs = oe_builddir
254 du_cmd = "du -Lbms %s" % rootfs
255 rc, out = exec_cmd(du_cmd)
256 rootfs_size = out.split()[0]
257
258 self.size = rootfs_size
259 self.source_file = rootfs
260
261 def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
262 native_sysroot):
263 """
264 Prepare content for a rootfs partition i.e. create a partition
265 and fill it from a /rootfs dir.
266
267 Currently handles ext2/3/4 and btrfs.
268 """
269 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
270 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
271 pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
272 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
273 pseudo += "%s/usr/bin/pseudo " % native_sysroot
274
275 if self.fstype.startswith("ext"):
276 return self.prepare_rootfs_ext(cr_workdir, oe_builddir,
277 rootfs_dir, native_sysroot,
278 pseudo)
279 elif self.fstype.startswith("btrfs"):
280 return self.prepare_rootfs_btrfs(cr_workdir, oe_builddir,
281 rootfs_dir, native_sysroot,
282 pseudo)
283
284 def prepare_rootfs_ext(self, cr_workdir, oe_builddir, rootfs_dir,
285 native_sysroot, pseudo):
286 """
287 Prepare content for an ext2/3/4 rootfs partition.
288 """
289
290 image_rootfs = rootfs_dir
291 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label ,self.fstype)
292
293 du_cmd = "du -ks %s" % image_rootfs
294 rc, out = exec_cmd(du_cmd)
295 actual_rootfs_size = int(out.split()[0])
296
297 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
298
299 if extra_blocks < IMAGE_EXTRA_SPACE:
300 extra_blocks = IMAGE_EXTRA_SPACE
301
302 rootfs_size = actual_rootfs_size + extra_blocks
303
304 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
305 (extra_blocks, self.mountpoint, rootfs_size))
306
307 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
308 (rootfs, rootfs_size)
309 rc, out = exec_cmd(dd_cmd)
310
311 extra_imagecmd = "-i 8192"
312
313 mkfs_cmd = "mkfs.%s -F %s %s -d %s" % \
314 (self.fstype, extra_imagecmd, rootfs, image_rootfs)
315 rc, out = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
316
317
318 # get the rootfs size in the right units for kickstart (Mb)
319 du_cmd = "du -Lbms %s" % rootfs
320 rc, out = exec_cmd(du_cmd)
321 rootfs_size = out.split()[0]
322
323 self.size = rootfs_size
324 self.source_file = rootfs
325
326 return 0
327
328 def prepare_for_uboot(self, arch, cr_workdir, oe_builddir, rootfs_dir,
329 native_sysroot):
330 """
331 Generates u-boot image from source_file( ext2/3/4 )
332
333 """
334 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
335 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
336 pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
337 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
338 pseudo += "%s/usr/bin/pseudo " % native_sysroot
339
340 # 1) compress image
341 rootfs = self.source_file
342 rootfs_gzip = "%s.gz" % rootfs
343 gzip_cmd = "gzip -f -9 -c %s > %s" % (rootfs, rootfs_gzip)
344 rc, out = exec_native_cmd(pseudo + gzip_cmd, native_sysroot)
345
346 # 2) image for U-Boot
347 rootfs_uboot = "%s.u-boot" % rootfs_gzip
348 mkimage_cmd = "mkimage -A %s -O linux -T ramdisk -C gzip -n %s -d %s %s" % \
349 (arch, self.label, rootfs_gzip, rootfs_uboot)
350 rc, out = exec_native_cmd(pseudo + mkimage_cmd, native_sysroot)
351
352 msger.info("\n\n\tThe new U-Boot ramdisk image can be found here:\n\t\t%s\n\n" % rootfs_uboot)
353
354 return 0
355
356 def prepare_rootfs_btrfs(self, cr_workdir, oe_builddir, rootfs_dir,
357 native_sysroot, pseudo):
358 """
359 Prepare content for a btrfs rootfs partition.
360
361 Currently handles ext2/3/4 and btrfs.
362 """
363 image_rootfs = rootfs_dir
364 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label, self.fstype)
365
366 du_cmd = "du -ks %s" % image_rootfs
367 rc, out = exec_cmd(du_cmd)
368 actual_rootfs_size = int(out.split()[0])
369
370 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
371
372 if extra_blocks < IMAGE_EXTRA_SPACE:
373 extra_blocks = IMAGE_EXTRA_SPACE
374
375 rootfs_size = actual_rootfs_size + extra_blocks
376
377 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
378 (extra_blocks, self.mountpoint, rootfs_size))
379
380 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
381 (rootfs, rootfs_size)
382 rc, out = exec_cmd(dd_cmd)
383
384 mkfs_cmd = "mkfs.%s -b %d -r %s %s" % \
385 (self.fstype, rootfs_size * 1024, image_rootfs, rootfs)
386 rc, out = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
387
388 # get the rootfs size in the right units for kickstart (Mb)
389 du_cmd = "du -Lbms %s" % rootfs
390 rc, out = exec_cmd(du_cmd)
391 rootfs_size = out.split()[0]
392
393 self.size = rootfs_size
394 self.source_file = rootfs
395
396 def prepare_empty_partition(self, cr_workdir, oe_builddir, native_sysroot):
397 """
398 Prepare an empty partition.
399 """
400 if self.fstype.startswith("ext"):
401 return self.prepare_empty_partition_ext(cr_workdir, oe_builddir,
402 native_sysroot)
403 elif self.fstype.startswith("btrfs"):
404 return self.prepare_empty_partition_btrfs(cr_workdir, oe_builddir,
405 native_sysroot)
406
407 def prepare_empty_partition_ext(self, cr_workdir, oe_builddir,
408 native_sysroot):
409 """
410 Prepare an empty ext2/3/4 partition.
411 """
412 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
413
414 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
415 (fs, self.size)
416 rc, out = exec_cmd(dd_cmd)
417
418 extra_imagecmd = "-i 8192"
419
420 mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs)
421 rc, out = exec_native_cmd(mkfs_cmd, native_sysroot)
422
423 self.source_file = fs
424
425 return 0
426
427 def prepare_empty_partition_btrfs(self, cr_workdir, oe_builddir,
428 native_sysroot):
429 """
430 Prepare an empty btrfs partition.
431 """
432 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
433
434 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
435 (fs, self.size)
436 rc, out = exec_cmd(dd_cmd)
437
438 mkfs_cmd = "mkfs.%s -b %d %s" % (self.fstype, self.size * 1024, rootfs)
439 rc, out = exec_native_cmd(mkfs_cmd, native_sysroot)
440
441 mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs)
442 rc, out = exec_native_cmd(mkfs_cmd, native_sysroot)
443
444 self.source_file = fs
445
446 return 0
447
448 def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot):
449 """
450 Prepare a swap partition.
451 """
452 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
453
454 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
455 (fs, self.size)
456 rc, out = exec_cmd(dd_cmd)
457
458 import uuid
459 label_str = ""
460 if self.label:
461 label_str = "-L %s" % self.label
462 mkswap_cmd = "mkswap %s -U %s %s" % (label_str, str(uuid.uuid1()), fs)
463 rc, out = exec_native_cmd(mkswap_cmd, native_sysroot)
464
465 self.source_file = fs
466
467 return 0
468
469class Wic_Partition(Mic_Partition):
470 removedKeywords = Mic_Partition.removedKeywords
471 removedAttrs = Mic_Partition.removedAttrs
472
473 def _getParser(self):
474 op = Mic_Partition._getParser(self)
475 # use specified source file to fill the partition
476 # and calculate partition size
477 op.add_option("--source", type="string", action="store",
478 dest="source", default=None)
479 # use specified rootfs path to fill the partition
480 op.add_option("--rootfs-dir", type="string", action="store",
481 dest="rootfs", default=None)
482 return op