summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic/kickstart
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/wic/kickstart')
-rw-r--r--scripts/lib/wic/kickstart/__init__.py125
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/__init__.py10
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/micboot.py49
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/micpartition.py57
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/partition.py652
-rw-r--r--scripts/lib/wic/kickstart/custom_commands/wicboot.py57
6 files changed, 950 insertions, 0 deletions
diff --git a/scripts/lib/wic/kickstart/__init__.py b/scripts/lib/wic/kickstart/__init__.py
new file mode 100644
index 0000000000..600098293a
--- /dev/null
+++ b/scripts/lib/wic/kickstart/__init__.py
@@ -0,0 +1,125 @@
1#!/usr/bin/env python -tt
2#
3# Copyright (c) 2007 Red Hat, Inc.
4# Copyright (c) 2009, 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19import os, sys, re
20import shutil
21import subprocess
22import string
23
24import pykickstart.sections as kssections
25import pykickstart.commands as kscommands
26import pykickstart.constants as ksconstants
27import pykickstart.errors as kserrors
28import pykickstart.parser as ksparser
29import pykickstart.version as ksversion
30from pykickstart.handlers.control import commandMap
31from pykickstart.handlers.control import dataMap
32
33from wic import msger
34from wic.utils import errors, misc, runner, fs_related as fs
35from custom_commands import wicboot, partition
36
37def read_kickstart(path):
38 """Parse a kickstart file and return a KickstartParser instance.
39
40 This is a simple utility function which takes a path to a kickstart file,
41 parses it and returns a pykickstart KickstartParser instance which can
42 be then passed to an ImageCreator constructor.
43
44 If an error occurs, a CreatorError exception is thrown.
45 """
46
47 #version = ksversion.makeVersion()
48 #ks = ksparser.KickstartParser(version)
49
50 using_version = ksversion.DEVEL
51 commandMap[using_version]["bootloader"] = wicboot.Wic_Bootloader
52 commandMap[using_version]["part"] = partition.Wic_Partition
53 commandMap[using_version]["partition"] = partition.Wic_Partition
54 dataMap[using_version]["PartData"] = partition.Wic_PartData
55 superclass = ksversion.returnClassForVersion(version=using_version)
56
57 class KSHandlers(superclass):
58 def __init__(self):
59 superclass.__init__(self, mapping=commandMap[using_version])
60
61 ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False)
62
63 try:
64 ks.readKickstart(path)
65 except (kserrors.KickstartParseError, kserrors.KickstartError), err:
66 if msger.ask("Errors occured on kickstart file, skip and continue?"):
67 msger.warning("%s" % err)
68 pass
69 else:
70 raise errors.KsError("%s" % err)
71
72 return ks
73
74def get_image_size(ks, default = None):
75 __size = 0
76 for p in ks.handler.partition.partitions:
77 if p.mountpoint == "/" and p.size:
78 __size = p.size
79 if __size > 0:
80 return int(__size) * 1024L * 1024L
81 else:
82 return default
83
84def get_image_fstype(ks, default = None):
85 for p in ks.handler.partition.partitions:
86 if p.mountpoint == "/" and p.fstype:
87 return p.fstype
88 return default
89
90def get_image_fsopts(ks, default = None):
91 for p in ks.handler.partition.partitions:
92 if p.mountpoint == "/" and p.fsopts:
93 return p.fsopts
94 return default
95
96def get_timeout(ks, default = None):
97 if not hasattr(ks.handler.bootloader, "timeout"):
98 return default
99 if ks.handler.bootloader.timeout is None:
100 return default
101 return int(ks.handler.bootloader.timeout)
102
103def get_kernel_args(ks, default = "ro rd.live.image"):
104 if not hasattr(ks.handler.bootloader, "appendLine"):
105 return default
106 if ks.handler.bootloader.appendLine is None:
107 return default
108 return "%s %s" %(default, ks.handler.bootloader.appendLine)
109
110def get_menu_args(ks, default = ""):
111 if not hasattr(ks.handler.bootloader, "menus"):
112 return default
113 if ks.handler.bootloader.menus in (None, ""):
114 return default
115 return "%s" % ks.handler.bootloader.menus
116
117def get_default_kernel(ks, default = None):
118 if not hasattr(ks.handler.bootloader, "default"):
119 return default
120 if not ks.handler.bootloader.default:
121 return default
122 return ks.handler.bootloader.default
123
124def get_partitions(ks):
125 return ks.handler.partition.partitions
diff --git a/scripts/lib/wic/kickstart/custom_commands/__init__.py b/scripts/lib/wic/kickstart/custom_commands/__init__.py
new file mode 100644
index 0000000000..f84c6d9e00
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/__init__.py
@@ -0,0 +1,10 @@
1from micpartition import Mic_Partition
2from micpartition import Mic_PartData
3from partition import Wic_Partition
4
5__all__ = (
6 "Mic_Partition",
7 "Mic_PartData",
8 "Wic_Partition",
9 "Wic_PartData",
10)
diff --git a/scripts/lib/wic/kickstart/custom_commands/micboot.py b/scripts/lib/wic/kickstart/custom_commands/micboot.py
new file mode 100644
index 0000000000..d162142506
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/micboot.py
@@ -0,0 +1,49 @@
1#!/usr/bin/env python -tt
2#
3# Copyright (c) 2008, 2009, 2010 Intel, Inc.
4#
5# Anas Nashif
6#
7# This program is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the Free
9# Software Foundation; version 2 of the License
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# 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., 59
18# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23from pykickstart.commands.bootloader import *
24
25class Mic_Bootloader(F8_Bootloader):
26 def __init__(self, writePriority=10, appendLine="", driveorder=None,
27 forceLBA=False, location="", md5pass="", password="",
28 upgrade=False, menus=""):
29 F8_Bootloader.__init__(self, writePriority, appendLine, driveorder,
30 forceLBA, location, md5pass, password, upgrade)
31
32 self.menus = ""
33 self.ptable = "msdos"
34
35 def _getArgsAsStr(self):
36 ret = F8_Bootloader._getArgsAsStr(self)
37
38 if self.menus == "":
39 ret += " --menus=%s" %(self.menus,)
40 if self.ptable:
41 ret += " --ptable=\"%s\"" %(self.ptable,)
42 return ret
43
44 def _getParser(self):
45 op = F8_Bootloader._getParser(self)
46 op.add_option("--menus", dest="menus")
47 op.add_option("--ptable", dest="ptable", type="string")
48 return op
49
diff --git a/scripts/lib/wic/kickstart/custom_commands/micpartition.py b/scripts/lib/wic/kickstart/custom_commands/micpartition.py
new file mode 100644
index 0000000000..43d04f1294
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/micpartition.py
@@ -0,0 +1,57 @@
1#!/usr/bin/env python -tt
2#
3# Marko Saukko <marko.saukko@cybercom.com>
4#
5# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
6#
7# This copyrighted material is made available to anyone wishing to use, modify,
8# copy, or redistribute it subject to the terms and conditions of the GNU
9# General Public License v.2. This program is distributed in the hope that it
10# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
11# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18from pykickstart.commands.partition import *
19
20class Mic_PartData(FC4_PartData):
21 removedKeywords = FC4_PartData.removedKeywords
22 removedAttrs = FC4_PartData.removedAttrs
23
24 def __init__(self, *args, **kwargs):
25 FC4_PartData.__init__(self, *args, **kwargs)
26 self.deleteRemovedAttrs()
27 self.align = kwargs.get("align", None)
28 self.extopts = kwargs.get("extopts", None)
29 self.part_type = kwargs.get("part_type", None)
30
31 def _getArgsAsStr(self):
32 retval = FC4_PartData._getArgsAsStr(self)
33
34 if self.align:
35 retval += " --align"
36 if self.extopts:
37 retval += " --extoptions=%s" % self.extopts
38 if self.part_type:
39 retval += " --part-type=%s" % self.part_type
40
41 return retval
42
43class Mic_Partition(FC4_Partition):
44 removedKeywords = FC4_Partition.removedKeywords
45 removedAttrs = FC4_Partition.removedAttrs
46
47 def _getParser(self):
48 op = FC4_Partition._getParser(self)
49 # The alignment value is given in kBytes. e.g., value 8 means that
50 # the partition is aligned to start from 8096 byte boundary.
51 op.add_option("--align", type="int", action="store", dest="align",
52 default=None)
53 op.add_option("--extoptions", type="string", action="store", dest="extopts",
54 default=None)
55 op.add_option("--part-type", type="string", action="store", dest="part_type",
56 default=None)
57 return op
diff --git a/scripts/lib/wic/kickstart/custom_commands/partition.py b/scripts/lib/wic/kickstart/custom_commands/partition.py
new file mode 100644
index 0000000000..03332194df
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/partition.py
@@ -0,0 +1,652 @@
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
28import os
29import tempfile
30
31from pykickstart.commands.partition import *
32from wic.utils.oe.misc import *
33from wic.kickstart.custom_commands import *
34from wic.plugin import pluginmgr
35
36import os
37from mic.utils.oe.package_manager import *
38
39partition_methods = {
40 "do_install_pkgs":None,
41 "do_stage_partition":None,
42 "do_prepare_partition":None,
43 "do_configure_partition":None,
44}
45
46class Wic_PartData(Mic_PartData):
47 removedKeywords = Mic_PartData.removedKeywords
48 removedAttrs = Mic_PartData.removedAttrs
49
50 def __init__(self, *args, **kwargs):
51 Mic_PartData.__init__(self, *args, **kwargs)
52 self.deleteRemovedAttrs()
53 self.source = kwargs.get("source", None)
54 self.sourceparams = kwargs.get("sourceparams", None)
55 self.rootfs = kwargs.get("rootfs-dir", None)
56 self.source_file = ""
57 self.size = 0
58
59 def _getArgsAsStr(self):
60 retval = Mic_PartData._getArgsAsStr(self)
61
62 if self.source:
63 retval += " --source=%s" % self.source
64 if self.sourceparams:
65 retval += " --sourceparams=%s" % self.sourceparams
66 if self.rootfs:
67 retval += " --rootfs-dir=%s" % self.rootfs
68
69 return retval
70
71 def get_rootfs(self):
72 """
73 Acessor for rootfs dir
74 """
75 return self.rootfs
76
77 def set_rootfs(self, rootfs):
78 """
79 Acessor for actual rootfs dir, which must be set by source
80 plugins.
81 """
82 self.rootfs = rootfs
83
84 def get_size(self):
85 """
86 Accessor for partition size, 0 or --size before set_size().
87 """
88 return self.size
89
90 def set_size(self, size):
91 """
92 Accessor for actual partition size, which must be set by source
93 plugins.
94 """
95 self.size = size
96
97 def set_source_file(self, source_file):
98 """
99 Accessor for source_file, the location of the generated partition
100 image, which must be set by source plugins.
101 """
102 self.source_file = source_file
103
104 def get_extra_block_count(self, current_blocks):
105 """
106 The --size param is reflected in self.size (in MB), and we already
107 have current_blocks (1k) blocks, calculate and return the
108 number of (1k) blocks we need to add to get to --size, 0 if
109 we're already there or beyond.
110 """
111 msger.debug("Requested partition size for %s: %d" % \
112 (self.mountpoint, self.size))
113
114 if not self.size:
115 return 0
116
117 requested_blocks = self.size * 1024
118
119 msger.debug("Requested blocks %d, current_blocks %d" % \
120 (requested_blocks, current_blocks))
121
122 if requested_blocks > current_blocks:
123 return requested_blocks - current_blocks
124 else:
125 return 0
126
127 def install_pkgs(self, creator, cr_workdir, oe_builddir, rootfs_dir,
128 bootimg_dir, kernel_dir, native_sysroot):
129 """
130 Prepare content for individual partitions, installing packages.
131 """
132
133 if not self.source:
134 return
135
136 self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods)
137 self._source_methods["do_install_pkgs"](self, creator,
138 cr_workdir,
139 oe_builddir,
140 rootfs_dir,
141 bootimg_dir,
142 kernel_dir,
143 native_sysroot)
144
145 def install_pkgs_ipk(self, cr_workdir, oe_builddir, rootfs_dir,
146 native_sysroot, packages, repourl):
147 """
148 Install packages specified into wks file using opkg package manager.
149 This method is dependend on bb module.
150 """
151
152 gVar = {}
153 gVar["DEPLOY_DIR_IPK"] = os.path.join(oe_builddir, "tmp/deploy/ipk")
154
155 # Run postinstall scripts even in offline mode
156 # Use the arch priority package rather than higher version one if more than one candidate is found.
157 #d.setVar("OPKG_ARGS", "--force_postinstall --prefer-arch-to-version")
158 gVar["OPKG_ARGS"] = "--force_postinstall"
159
160 # OPKG path relative to /output_path
161 gVar["OPKGLIBDIR"] = "var/lib"
162
163 source_url = repourl.split()
164
165 # Generate feed uri's names, it doesn't seem to matter what name they have
166 feed_uris = ""
167 cnt = 0
168 archs = ""
169 for url in source_url:
170 feed_uris += "cl_def_feed%d##%s\n" % (cnt, url)
171 cnt += 1
172 head, tail = os.path.split(url)
173 archs += " " + tail
174
175 # IPK_FEED_URIS with special formating defines the URI's used as source for packages
176 gVar['IPK_FEED_URIS'] = feed_uris
177
178 gVar['BUILD_IMAGES_FROM_FEEDS'] = "1"
179
180 # We need to provide sysroot for utilities
181 gVar['STAGING_DIR_NATIVE'] = native_sysroot
182
183 # Set WORKDIR for output
184 gVar['WORKDIR'] = cr_workdir
185
186 # Set TMPDIR for output
187 gVar['TMPDIR'] = os.path.join(cr_workdir, "tmp")
188
189 if 'ROOTFS_DIR' in rootfs_dir:
190 target_dir = rootfs_dir['ROOTFS_DIR']
191 elif os.path.isdir(rootfs_dir):
192 target_dir = rootfs_dir
193 else:
194 msg = "Couldn't find --rootfs-dir=%s connection"
195 msg += " or it is not a valid path, exiting"
196 msger.error(msg % rootfs_dir)
197
198 # Need native sysroot /usr/bin/ for opkg-cl
199 # chnage PATH var to avoid issues with host tools
200 defpath = os.environ['PATH']
201 os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"
202
203 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
204 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % target_dir
205 pseudo += "export PSEUDO_PASSWD=%s;" % target_dir
206 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
207 pseudo += "%s/usr/bin/pseudo " % native_sysroot
208
209 pm = WicOpkgPM(gVar,
210 target_dir,
211 'opkg.conf',
212 archs,
213 pseudo,
214 native_sysroot)
215
216 pm.update()
217
218 pm.install(packages)
219
220 os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"
221
222
223 def prepare(self, cr, cr_workdir, oe_builddir, rootfs_dir, bootimg_dir,
224 kernel_dir, native_sysroot):
225 """
226 Prepare content for individual partitions, depending on
227 partition command parameters.
228 """
229 self.sourceparams_dict = {}
230
231 if self.sourceparams:
232 self.sourceparams_dict = parse_sourceparams(self.sourceparams)
233
234 if not self.source:
235 if not self.size:
236 msger.error("The %s partition has a size of zero. Please specify a non-zero --size for that partition." % self.mountpoint)
237 if self.fstype and self.fstype == "swap":
238 self.prepare_swap_partition(cr_workdir, oe_builddir,
239 native_sysroot)
240 elif self.fstype:
241 self.prepare_empty_partition(cr_workdir, oe_builddir,
242 native_sysroot)
243 return
244
245 plugins = pluginmgr.get_source_plugins()
246
247 if self.source not in plugins:
248 msger.error("The '%s' --source specified for %s doesn't exist.\n\tSee 'wic list source-plugins' for a list of available --sources.\n\tSee 'wic help source-plugins' for details on adding a new source plugin." % (self.source, self.mountpoint))
249
250 self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods)
251 self._source_methods["do_configure_partition"](self, self.sourceparams_dict,
252 cr, cr_workdir,
253 oe_builddir,
254 bootimg_dir,
255 kernel_dir,
256 native_sysroot)
257 self._source_methods["do_stage_partition"](self, self.sourceparams_dict,
258 cr, cr_workdir,
259 oe_builddir,
260 bootimg_dir, kernel_dir,
261 native_sysroot)
262 self._source_methods["do_prepare_partition"](self, self.sourceparams_dict,
263 cr, cr_workdir,
264 oe_builddir,
265 bootimg_dir, kernel_dir, rootfs_dir,
266 native_sysroot)
267
268 def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir,
269 rootfs_dir):
270 """
271 Handle an already-created partition e.g. xxx.ext3
272 """
273 rootfs = oe_builddir
274 du_cmd = "du -Lbms %s" % rootfs
275 out = exec_cmd(du_cmd)
276 rootfs_size = out.split()[0]
277
278 self.size = rootfs_size
279 self.source_file = rootfs
280
281 def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
282 native_sysroot):
283 """
284 Prepare content for a rootfs partition i.e. create a partition
285 and fill it from a /rootfs dir.
286
287 Currently handles ext2/3/4, btrfs and vfat.
288 """
289 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
290 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
291 pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
292 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
293 pseudo += "%s/usr/bin/pseudo " % native_sysroot
294
295 if self.fstype.startswith("ext"):
296 return self.prepare_rootfs_ext(cr_workdir, oe_builddir,
297 rootfs_dir, native_sysroot,
298 pseudo)
299 elif self.fstype.startswith("btrfs"):
300 return self.prepare_rootfs_btrfs(cr_workdir, oe_builddir,
301 rootfs_dir, native_sysroot,
302 pseudo)
303
304 elif self.fstype.startswith("vfat"):
305 return self.prepare_rootfs_vfat(cr_workdir, oe_builddir,
306 rootfs_dir, native_sysroot,
307 pseudo)
308 elif self.fstype.startswith("squashfs"):
309 return self.prepare_rootfs_squashfs(cr_workdir, oe_builddir,
310 rootfs_dir, native_sysroot,
311 pseudo)
312
313 def prepare_rootfs_ext(self, cr_workdir, oe_builddir, rootfs_dir,
314 native_sysroot, pseudo):
315 """
316 Prepare content for an ext2/3/4 rootfs partition.
317 """
318
319 image_rootfs = rootfs_dir
320 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label ,self.fstype)
321
322 du_cmd = "du -ks %s" % image_rootfs
323 out = exec_cmd(du_cmd)
324 actual_rootfs_size = int(out.split()[0])
325
326 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
327
328 if extra_blocks < IMAGE_EXTRA_SPACE:
329 extra_blocks = IMAGE_EXTRA_SPACE
330
331 rootfs_size = actual_rootfs_size + extra_blocks
332 rootfs_size *= IMAGE_OVERHEAD_FACTOR
333
334 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
335 (extra_blocks, self.mountpoint, rootfs_size))
336
337 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
338 (rootfs, rootfs_size)
339 exec_cmd(dd_cmd)
340
341 extra_imagecmd = "-i 8192"
342
343 mkfs_cmd = "mkfs.%s -F %s %s -d %s" % \
344 (self.fstype, extra_imagecmd, rootfs, image_rootfs)
345 (rc, out) = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
346 if rc:
347 print "rootfs_dir: %s" % rootfs_dir
348 msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details) when creating filesystem from rootfs directory: %s" % (self.fstype, rc, rootfs_dir))
349
350 # get the rootfs size in the right units for kickstart (Mb)
351 du_cmd = "du -Lbms %s" % rootfs
352 out = exec_cmd(du_cmd)
353 rootfs_size = out.split()[0]
354
355 self.size = rootfs_size
356 self.source_file = rootfs
357
358 return 0
359
360 def prepare_for_uboot(self, arch, cr_workdir, oe_builddir, rootfs_dir,
361 native_sysroot):
362 """
363 Generates u-boot image from source_file( ext2/3/4 )
364
365 """
366 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
367 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
368 pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
369 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
370 pseudo += "%s/usr/bin/pseudo " % native_sysroot
371
372 # 1) compress image
373 rootfs = self.source_file
374 rootfs_gzip = "%s.gz" % rootfs
375 gzip_cmd = "gzip -f -9 -c %s > %s" % (rootfs, rootfs_gzip)
376 rc, out = exec_native_cmd(pseudo + gzip_cmd, native_sysroot)
377
378 # 2) image for U-Boot
379 rootfs_uboot = "%s.u-boot" % rootfs_gzip
380 mkimage_cmd = "mkimage -A %s -O linux -T ramdisk -C gzip -n %s -d %s %s" % \
381 (arch, self.label, rootfs_gzip, rootfs_uboot)
382 rc, out = exec_native_cmd(pseudo + mkimage_cmd, native_sysroot)
383
384 msger.info("\n\n\tThe new U-Boot ramdisk image can be found here:\n\t\t%s\n\n" % rootfs_uboot)
385
386 return 0
387
388 def prepare_rootfs_btrfs(self, cr_workdir, oe_builddir, rootfs_dir,
389 native_sysroot, pseudo):
390 """
391 Prepare content for a btrfs rootfs partition.
392
393 Currently handles ext2/3/4 and btrfs.
394 """
395 image_rootfs = rootfs_dir
396 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label, self.fstype)
397
398 du_cmd = "du -ks %s" % image_rootfs
399 out = exec_cmd(du_cmd)
400 actual_rootfs_size = int(out.split()[0])
401
402 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
403
404 if extra_blocks < IMAGE_EXTRA_SPACE:
405 extra_blocks = IMAGE_EXTRA_SPACE
406
407 rootfs_size = actual_rootfs_size + extra_blocks
408 rootfs_size *= IMAGE_OVERHEAD_FACTOR
409
410 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
411 (extra_blocks, self.mountpoint, rootfs_size))
412
413 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
414 (rootfs, rootfs_size)
415 exec_cmd(dd_cmd)
416
417 mkfs_cmd = "mkfs.%s -b %d -r %s %s" % \
418 (self.fstype, rootfs_size * 1024, image_rootfs, rootfs)
419 (rc, out) = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
420 if rc:
421 msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details) when creating filesystem from rootfs directory: %s" % (self.fstype, rc, rootfs_dir))
422
423 # get the rootfs size in the right units for kickstart (Mb)
424 du_cmd = "du -Lbms %s" % rootfs
425 out = exec_cmd(du_cmd)
426 rootfs_size = out.split()[0]
427
428 self.size = rootfs_size
429 self.source_file = rootfs
430
431 def prepare_rootfs_vfat(self, cr_workdir, oe_builddir, rootfs_dir,
432 native_sysroot, pseudo):
433 """
434 Prepare content for a vfat rootfs partition.
435 """
436 image_rootfs = rootfs_dir
437 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label, self.fstype)
438
439 du_cmd = "du -bks %s" % image_rootfs
440 out = exec_cmd(du_cmd)
441 blocks = int(out.split()[0])
442
443 extra_blocks = self.get_extra_block_count(blocks)
444
445 if extra_blocks < IMAGE_EXTRA_SPACE:
446 extra_blocks = IMAGE_EXTRA_SPACE
447
448 blocks += extra_blocks
449
450 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
451 (extra_blocks, self.mountpoint, blocks))
452
453 # Ensure total sectors is an integral number of sectors per
454 # track or mcopy will complain. Sectors are 512 bytes, and we
455 # generate images with 32 sectors per track. This calculation
456 # is done in blocks, thus the mod by 16 instead of 32. Apply
457 # sector count fix only when needed.
458 if blocks % 16 != 0:
459 blocks += (16 - (blocks % 16))
460
461 dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (rootfs, blocks)
462 exec_native_cmd(dosfs_cmd, native_sysroot)
463
464 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, image_rootfs)
465 rc, out = exec_native_cmd(mcopy_cmd, native_sysroot)
466 if rc:
467 msger.error("ERROR: mcopy returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % rc)
468
469 chmod_cmd = "chmod 644 %s" % rootfs
470 exec_cmd(chmod_cmd)
471
472 # get the rootfs size in the right units for kickstart (Mb)
473 du_cmd = "du -Lbms %s" % rootfs
474 out = exec_cmd(du_cmd)
475 rootfs_size = out.split()[0]
476
477 self.set_size(rootfs_size)
478 self.set_source_file(rootfs)
479
480 def prepare_rootfs_squashfs(self, cr_workdir, oe_builddir, rootfs_dir,
481 native_sysroot, pseudo):
482 """
483 Prepare content for a squashfs rootfs partition.
484 """
485 image_rootfs = rootfs_dir
486 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label ,self.fstype)
487
488 squashfs_cmd = "mksquashfs %s %s -noappend" % \
489 (image_rootfs, rootfs)
490 exec_native_cmd(pseudo + squashfs_cmd, native_sysroot)
491
492 # get the rootfs size in the right units for kickstart (Mb)
493 du_cmd = "du -Lbms %s" % rootfs
494 out = exec_cmd(du_cmd)
495 rootfs_size = out.split()[0]
496
497 self.size = rootfs_size
498 self.source_file = rootfs
499
500 return 0
501
502 def prepare_empty_partition(self, cr_workdir, oe_builddir, native_sysroot):
503 """
504 Prepare an empty partition.
505 """
506 if self.fstype.startswith("ext"):
507 return self.prepare_empty_partition_ext(cr_workdir, oe_builddir,
508 native_sysroot)
509 elif self.fstype.startswith("btrfs"):
510 return self.prepare_empty_partition_btrfs(cr_workdir, oe_builddir,
511 native_sysroot)
512 elif self.fstype.startswith("vfat"):
513 return self.prepare_empty_partition_vfat(cr_workdir, oe_builddir,
514 native_sysroot)
515 elif self.fstype.startswith("squashfs"):
516 return self.prepare_empty_partition_squashfs(cr_workdir, oe_builddir,
517 native_sysroot)
518
519 def prepare_empty_partition_ext(self, cr_workdir, oe_builddir,
520 native_sysroot):
521 """
522 Prepare an empty ext2/3/4 partition.
523 """
524 fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype)
525
526 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
527 (fs, self.size)
528 exec_cmd(dd_cmd)
529
530 extra_imagecmd = "-i 8192"
531
532 mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs)
533 (rc, out) = exec_native_cmd(mkfs_cmd, native_sysroot)
534 if rc:
535 msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % (self.fstype, rc))
536
537 self.source_file = fs
538
539 return 0
540
541 def prepare_empty_partition_btrfs(self, cr_workdir, oe_builddir,
542 native_sysroot):
543 """
544 Prepare an empty btrfs partition.
545 """
546 fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype)
547
548 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
549 (fs, self.size)
550 exec_cmd(dd_cmd)
551
552 mkfs_cmd = "mkfs.%s -b %d %s" % (self.fstype, self.size * 1024, rootfs)
553 (rc, out) = exec_native_cmd(mkfs_cmd, native_sysroot)
554 if rc:
555 msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % (self.fstype, rc))
556
557 mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs)
558 (rc, out) = exec_native_cmd(mkfs_cmd, native_sysroot)
559 if rc:
560 msger.error("ERROR: mkfs.%s returned '%s' instead of 0 (which you probably don't want to ignore, use --debug for details)" % (self.fstype, rc))
561
562 self.source_file = fs
563
564 return 0
565
566 def prepare_empty_partition_vfat(self, cr_workdir, oe_builddir,
567 native_sysroot):
568 """
569 Prepare an empty vfat partition.
570 """
571 fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype)
572
573 blocks = self.size * 1024
574
575 dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (fs, blocks)
576 exec_native_cmd(dosfs_cmd, native_sysroot)
577
578 chmod_cmd = "chmod 644 %s" % fs
579 exec_cmd(chmod_cmd)
580
581 self.source_file = fs
582
583 return 0
584
585 def prepare_empty_partition_squashfs(self, cr_workdir, oe_builddir,
586 native_sysroot):
587 """
588 Prepare an empty squashfs partition.
589 """
590 msger.warning("Creating of an empty squashfs %s partition was attempted. " \
591 "Proceeding as requested." % self.mountpoint)
592
593 fs = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype)
594
595 # it is not possible to create a squashfs without source data,
596 # thus prepare an empty temp dir that is used as source
597 tmpdir = tempfile.mkdtemp()
598
599 squashfs_cmd = "mksquashfs %s %s -noappend" % \
600 (tmpdir, fs)
601 exec_native_cmd(squashfs_cmd, native_sysroot)
602
603 os.rmdir(tmpdir)
604
605 # get the rootfs size in the right units for kickstart (Mb)
606 du_cmd = "du -Lbms %s" % fs
607 out = exec_cmd(du_cmd)
608 fs_size = out.split()[0]
609
610 self.size = fs_size
611 self.source_file = fs
612
613 return 0
614
615 def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot):
616 """
617 Prepare a swap partition.
618 """
619 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
620
621 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
622 (fs, self.size)
623 exec_cmd(dd_cmd)
624
625 import uuid
626 label_str = ""
627 if self.label:
628 label_str = "-L %s" % self.label
629 mkswap_cmd = "mkswap %s -U %s %s" % (label_str, str(uuid.uuid1()), fs)
630 exec_native_cmd(mkswap_cmd, native_sysroot)
631
632 self.source_file = fs
633
634 return 0
635
636class Wic_Partition(Mic_Partition):
637 removedKeywords = Mic_Partition.removedKeywords
638 removedAttrs = Mic_Partition.removedAttrs
639
640 def _getParser(self):
641 op = Mic_Partition._getParser(self)
642 # use specified source file to fill the partition
643 # and calculate partition size
644 op.add_option("--source", type="string", action="store",
645 dest="source", default=None)
646 # comma-separated list of param=value pairs
647 op.add_option("--sourceparams", type="string", action="store",
648 dest="sourceparams", default=None)
649 # use specified rootfs path to fill the partition
650 op.add_option("--rootfs-dir", type="string", action="store",
651 dest="rootfs", default=None)
652 return op
diff --git a/scripts/lib/wic/kickstart/custom_commands/wicboot.py b/scripts/lib/wic/kickstart/custom_commands/wicboot.py
new file mode 100644
index 0000000000..f1914169d8
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/wicboot.py
@@ -0,0 +1,57 @@
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) 2014, 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 bootloader object definitions.
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27from pykickstart.base import *
28from pykickstart.errors import *
29from pykickstart.options import *
30from pykickstart.commands.bootloader import *
31
32from wic.kickstart.custom_commands.micboot import *
33
34class Wic_Bootloader(Mic_Bootloader):
35 def __init__(self, writePriority=10, appendLine="", driveorder=None,
36 forceLBA=False, location="", md5pass="", password="",
37 upgrade=False, menus=""):
38 Mic_Bootloader.__init__(self, writePriority, appendLine, driveorder,
39 forceLBA, location, md5pass, password, upgrade)
40
41 self.source = ""
42
43 def _getArgsAsStr(self):
44 retval = Mic_Bootloader._getArgsAsStr(self)
45
46 if self.source:
47 retval += " --source=%s" % self.source
48
49 return retval
50
51 def _getParser(self):
52 op = Mic_Bootloader._getParser(self)
53 # use specified source plugin to implement bootloader-specific methods
54 op.add_option("--source", type="string", action="store",
55 dest="source", default=None)
56 return op
57