summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2014-08-03 12:14:16 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-08-11 10:53:08 +0100
commitc0aa6cb8fe4aa98b455af044d4ede4b034644875 (patch)
tree8acc6a2ad85c29b84da72863a82e957cdd76fad5 /scripts
parentd2120000df4f3b5589ca5a0ac4686caac198cb93 (diff)
downloadpoky-c0aa6cb8fe4aa98b455af044d4ede4b034644875.tar.gz
wic: Remove mic chroot
mic chroot allows users to chroot into an existing mic image and isn't used by wic, so remove it. Removing chroot.py leads in turn to various plugin-loading failures for a number of plugins that wic doesn't use either, so remove those as well. The existing source plugins refer to chroot but don't use it, so fix those up. (From OE-Core rev: d73230306b827972cdc99f21d247c54d5d7c0b6d) Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lib/mic/chroot.py343
-rw-r--r--scripts/lib/mic/imager/fs.py99
-rw-r--r--scripts/lib/mic/imager/livecd.py750
-rw-r--r--scripts/lib/mic/imager/liveusb.py308
-rw-r--r--scripts/lib/mic/imager/loop.py418
-rw-r--r--scripts/lib/mic/imager/raw.py501
-rw-r--r--scripts/lib/mic/plugins/imager/direct_plugin.py2
-rw-r--r--scripts/lib/mic/plugins/imager/fs_plugin.py143
-rw-r--r--scripts/lib/mic/plugins/imager/livecd_plugin.py255
-rw-r--r--scripts/lib/mic/plugins/imager/liveusb_plugin.py260
-rw-r--r--scripts/lib/mic/plugins/imager/loop_plugin.py255
-rw-r--r--scripts/lib/mic/plugins/imager/raw_plugin.py275
-rw-r--r--scripts/lib/mic/plugins/source/bootimg-efi.py2
-rw-r--r--scripts/lib/mic/plugins/source/bootimg-pcbios.py2
-rw-r--r--scripts/lib/mic/plugins/source/rootfs.py2
15 files changed, 4 insertions, 3611 deletions
diff --git a/scripts/lib/mic/chroot.py b/scripts/lib/mic/chroot.py
deleted file mode 100644
index 99fb9a2c17..0000000000
--- a/scripts/lib/mic/chroot.py
+++ /dev/null
@@ -1,343 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18from __future__ import with_statement
19import os
20import shutil
21import subprocess
22
23from mic import msger
24from mic.conf import configmgr
25from mic.utils import misc, errors, runner, fs_related
26
27chroot_lockfd = -1
28chroot_lock = ""
29BIND_MOUNTS = (
30 "/proc",
31 "/proc/sys/fs/binfmt_misc",
32 "/sys",
33 "/dev",
34 "/dev/pts",
35 "/dev/shm",
36 "/var/lib/dbus",
37 "/var/run/dbus",
38 "/var/lock",
39 )
40
41def cleanup_after_chroot(targettype,imgmount,tmpdir,tmpmnt):
42 if imgmount and targettype == "img":
43 imgmount.cleanup()
44
45 if tmpdir:
46 shutil.rmtree(tmpdir, ignore_errors = True)
47
48 if tmpmnt:
49 shutil.rmtree(tmpmnt, ignore_errors = True)
50
51def check_bind_mounts(chrootdir, bindmounts):
52 chrootmounts = []
53 for mount in bindmounts.split(";"):
54 if not mount:
55 continue
56
57 srcdst = mount.split(":")
58 if len(srcdst) == 1:
59 srcdst.append("none")
60
61 if not os.path.isdir(srcdst[0]):
62 return False
63
64 if srcdst[1] == "" or srcdst[1] == "none":
65 srcdst[1] = None
66
67 if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/':
68 continue
69
70 if chrootdir:
71 if not srcdst[1]:
72 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[0]))
73 else:
74 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
75
76 tmpdir = chrootdir + "/" + srcdst[1]
77 if os.path.isdir(tmpdir):
78 msger.warning("Warning: dir %s has existed." % tmpdir)
79
80 return True
81
82def cleanup_mounts(chrootdir):
83 umountcmd = misc.find_binary_path("umount")
84 abs_chrootdir = os.path.abspath(chrootdir)
85 mounts = open('/proc/mounts').readlines()
86 for line in reversed(mounts):
87 if abs_chrootdir not in line:
88 continue
89
90 point = line.split()[1]
91
92 # '/' to avoid common name prefix
93 if abs_chrootdir == point or point.startswith(abs_chrootdir + '/'):
94 args = [ umountcmd, "-l", point ]
95 ret = runner.quiet(args)
96 if ret != 0:
97 msger.warning("failed to unmount %s" % point)
98
99 return 0
100
101def setup_chrootenv(chrootdir, bindmounts = None, mountparent = True):
102 global chroot_lockfd, chroot_lock
103
104 def get_bind_mounts(chrootdir, bindmounts, mountparent = True):
105 chrootmounts = []
106 if bindmounts in ("", None):
107 bindmounts = ""
108
109 for mount in bindmounts.split(";"):
110 if not mount:
111 continue
112
113 srcdst = mount.split(":")
114 srcdst[0] = os.path.abspath(os.path.expanduser(srcdst[0]))
115 if len(srcdst) == 1:
116 srcdst.append("none")
117
118 # if some bindmount is not existed, but it's created inside
119 # chroot, this is not expected
120 if not os.path.exists(srcdst[0]):
121 os.makedirs(srcdst[0])
122
123 if not os.path.isdir(srcdst[0]):
124 continue
125
126 if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/':
127 msger.verbose("%s will be mounted by default." % srcdst[0])
128 continue
129
130 if srcdst[1] == "" or srcdst[1] == "none":
131 srcdst[1] = None
132 else:
133 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
134 if os.path.isdir(chrootdir + "/" + srcdst[1]):
135 msger.warning("%s has existed in %s , skip it."\
136 % (srcdst[1], chrootdir))
137 continue
138
139 chrootmounts.append(fs_related.BindChrootMount(srcdst[0],
140 chrootdir,
141 srcdst[1]))
142
143 """Default bind mounts"""
144 for pt in BIND_MOUNTS:
145 if not os.path.exists(pt):
146 continue
147 chrootmounts.append(fs_related.BindChrootMount(pt,
148 chrootdir,
149 None))
150
151 if mountparent:
152 chrootmounts.append(fs_related.BindChrootMount("/",
153 chrootdir,
154 "/parentroot",
155 "ro"))
156
157 for kernel in os.listdir("/lib/modules"):
158 chrootmounts.append(fs_related.BindChrootMount(
159 "/lib/modules/"+kernel,
160 chrootdir,
161 None,
162 "ro"))
163
164 return chrootmounts
165
166 def bind_mount(chrootmounts):
167 for b in chrootmounts:
168 msger.verbose("bind_mount: %s -> %s" % (b.src, b.dest))
169 b.mount()
170
171 def setup_resolv(chrootdir):
172 try:
173 shutil.copyfile("/etc/resolv.conf", chrootdir + "/etc/resolv.conf")
174 except:
175 pass
176
177 globalmounts = get_bind_mounts(chrootdir, bindmounts, mountparent)
178 bind_mount(globalmounts)
179
180 setup_resolv(chrootdir)
181
182 mtab = "/etc/mtab"
183 dstmtab = chrootdir + mtab
184 if not os.path.islink(dstmtab):
185 shutil.copyfile(mtab, dstmtab)
186
187 chroot_lock = os.path.join(chrootdir, ".chroot.lock")
188 chroot_lockfd = open(chroot_lock, "w")
189
190 return globalmounts
191
192def cleanup_chrootenv(chrootdir, bindmounts=None, globalmounts=()):
193 global chroot_lockfd, chroot_lock
194
195 def bind_unmount(chrootmounts):
196 for b in reversed(chrootmounts):
197 msger.verbose("bind_unmount: %s -> %s" % (b.src, b.dest))
198 b.unmount()
199
200 def cleanup_resolv(chrootdir):
201 try:
202 fd = open(chrootdir + "/etc/resolv.conf", "w")
203 fd.truncate(0)
204 fd.close()
205 except:
206 pass
207
208 def kill_processes(chrootdir):
209 import glob
210 for fp in glob.glob("/proc/*/root"):
211 try:
212 if os.readlink(fp) == chrootdir:
213 pid = int(fp.split("/")[2])
214 os.kill(pid, 9)
215 except:
216 pass
217
218 def cleanup_mountdir(chrootdir, bindmounts):
219 if bindmounts == "" or bindmounts == None:
220 return
221 chrootmounts = []
222 for mount in bindmounts.split(";"):
223 if not mount:
224 continue
225
226 srcdst = mount.split(":")
227
228 if len(srcdst) == 1:
229 srcdst.append("none")
230
231 if srcdst[0] == "/":
232 continue
233
234 if srcdst[1] == "" or srcdst[1] == "none":
235 srcdst[1] = srcdst[0]
236
237 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
238 tmpdir = chrootdir + "/" + srcdst[1]
239 if os.path.isdir(tmpdir):
240 if len(os.listdir(tmpdir)) == 0:
241 shutil.rmtree(tmpdir, ignore_errors = True)
242 else:
243 msger.warning("Warning: dir %s isn't empty." % tmpdir)
244
245 chroot_lockfd.close()
246 bind_unmount(globalmounts)
247
248 if not fs_related.my_fuser(chroot_lock):
249 tmpdir = chrootdir + "/parentroot"
250 if os.path.exists(tmpdir) and len(os.listdir(tmpdir)) == 0:
251 shutil.rmtree(tmpdir, ignore_errors = True)
252
253 cleanup_resolv(chrootdir)
254
255 if os.path.exists(chrootdir + "/etc/mtab"):
256 os.unlink(chrootdir + "/etc/mtab")
257
258 kill_processes(chrootdir)
259
260 cleanup_mountdir(chrootdir, bindmounts)
261
262def chroot(chrootdir, bindmounts = None, execute = "/bin/bash"):
263 def mychroot():
264 os.chroot(chrootdir)
265 os.chdir("/")
266
267 if configmgr.chroot['saveto']:
268 savefs = True
269 saveto = configmgr.chroot['saveto']
270 wrnmsg = "Can't save chroot fs for dir %s exists" % saveto
271 if saveto == chrootdir:
272 savefs = False
273 wrnmsg = "Dir %s is being used to chroot" % saveto
274 elif os.path.exists(saveto):
275 if msger.ask("Dir %s already exists, cleanup and continue?" %
276 saveto):
277 shutil.rmtree(saveto, ignore_errors = True)
278 savefs = True
279 else:
280 savefs = False
281
282 if savefs:
283 msger.info("Saving image to directory %s" % saveto)
284 fs_related.makedirs(os.path.dirname(os.path.abspath(saveto)))
285 runner.quiet("cp -af %s %s" % (chrootdir, saveto))
286 devs = ['dev/fd',
287 'dev/stdin',
288 'dev/stdout',
289 'dev/stderr',
290 'etc/mtab']
291 ignlst = [os.path.join(saveto, x) for x in devs]
292 map(os.unlink, filter(os.path.exists, ignlst))
293 else:
294 msger.warning(wrnmsg)
295
296 dev_null = os.open("/dev/null", os.O_WRONLY)
297 files_to_check = ["/bin/bash", "/sbin/init"]
298
299 architecture_found = False
300
301 """ Register statically-linked qemu-arm if it is an ARM fs """
302 qemu_emulator = None
303
304 for ftc in files_to_check:
305 ftc = "%s/%s" % (chrootdir,ftc)
306
307 # Return code of 'file' is "almost always" 0 based on some man pages
308 # so we need to check the file existance first.
309 if not os.path.exists(ftc):
310 continue
311
312 for line in runner.outs(['file', ftc]).splitlines():
313 if 'ARM' in line:
314 qemu_emulator = misc.setup_qemu_emulator(chrootdir, "arm")
315 architecture_found = True
316 break
317
318 if 'Intel' in line:
319 architecture_found = True
320 break
321
322 if architecture_found:
323 break
324
325 os.close(dev_null)
326 if not architecture_found:
327 raise errors.CreatorError("Failed to get architecture from any of the "
328 "following files %s from chroot." \
329 % files_to_check)
330
331 try:
332 msger.info("Launching shell. Exit to continue.\n"
333 "----------------------------------")
334 globalmounts = setup_chrootenv(chrootdir, bindmounts)
335 subprocess.call(execute, preexec_fn = mychroot, shell=True)
336
337 except OSError, err:
338 raise errors.CreatorError("chroot err: %s" % str(err))
339
340 finally:
341 cleanup_chrootenv(chrootdir, bindmounts, globalmounts)
342 if qemu_emulator:
343 os.unlink(chrootdir + qemu_emulator)
diff --git a/scripts/lib/mic/imager/fs.py b/scripts/lib/mic/imager/fs.py
deleted file mode 100644
index d53b29cb47..0000000000
--- a/scripts/lib/mic/imager/fs.py
+++ /dev/null
@@ -1,99 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19
20from mic import msger
21from mic.utils import runner, misc
22from mic.utils.errors import CreatorError
23from mic.utils.fs_related import find_binary_path
24from mic.imager.baseimager import BaseImageCreator
25
26class FsImageCreator(BaseImageCreator):
27 def __init__(self, cfgmgr = None, pkgmgr = None):
28 self.zips = {
29 "tar.bz2" : ""
30 }
31 BaseImageCreator.__init__(self, cfgmgr, pkgmgr)
32 self._fstype = None
33 self._fsopts = None
34 self._include_src = False
35
36 def package(self, destdir = "."):
37
38 ignores = ["/dev/fd",
39 "/dev/stdin",
40 "/dev/stdout",
41 "/dev/stderr",
42 "/etc/mtab"]
43
44 if not os.path.exists(destdir):
45 os.makedirs(destdir)
46
47 if self._recording_pkgs:
48 self._save_recording_pkgs(destdir)
49
50 if not self.pack_to:
51 fsdir = os.path.join(destdir, self.name)
52
53 misc.check_space_pre_cp(self._instroot, destdir)
54 msger.info("Copying %s to %s ..." % (self._instroot, fsdir))
55 runner.show(['cp', "-af", self._instroot, fsdir])
56
57 for exclude in ignores:
58 if os.path.exists(fsdir + exclude):
59 os.unlink(fsdir + exclude)
60
61 self.outimage.append(fsdir)
62
63 else:
64 (tar, comp) = os.path.splitext(self.pack_to)
65 try:
66 tarcreat = {'.tar': '-cf',
67 '.gz': '-czf',
68 '.bz2': '-cjf',
69 '.tgz': '-czf',
70 '.tbz': '-cjf'}[comp]
71 except KeyError:
72 raise CreatorError("Unsupported comression for this image type:"
73 " '%s', try '.tar', '.tar.gz', etc" % comp)
74
75 dst = os.path.join(destdir, self.pack_to)
76 msger.info("Pack rootfs to %s. Please wait..." % dst)
77
78 tar = find_binary_path('tar')
79 tar_cmdline = [tar, "--numeric-owner",
80 "--preserve-permissions",
81 "--preserve-order",
82 "--one-file-system",
83 "--directory",
84 self._instroot]
85 for ignore_entry in ignores:
86 if ignore_entry.startswith('/'):
87 ignore_entry = ignore_entry[1:]
88
89 tar_cmdline.append("--exclude=%s" % (ignore_entry))
90
91 tar_cmdline.extend([tarcreat, dst, "."])
92
93 rc = runner.show(tar_cmdline)
94 if rc:
95 raise CreatorError("Failed compress image with tar.bz2. "
96 "Cmdline: %s" % (" ".join(tar_cmdline)))
97
98 self.outimage.append(dst)
99
diff --git a/scripts/lib/mic/imager/livecd.py b/scripts/lib/mic/imager/livecd.py
deleted file mode 100644
index e36f4a76c6..0000000000
--- a/scripts/lib/mic/imager/livecd.py
+++ /dev/null
@@ -1,750 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os, sys
19import glob
20import shutil
21
22from mic import kickstart, msger
23from mic.utils import fs_related, runner, misc
24from mic.utils.errors import CreatorError
25from mic.imager.loop import LoopImageCreator
26
27
28class LiveImageCreatorBase(LoopImageCreator):
29 """A base class for LiveCD image creators.
30
31 This class serves as a base class for the architecture-specific LiveCD
32 image creator subclass, LiveImageCreator.
33
34 LiveImageCreator creates a bootable ISO containing the system image,
35 bootloader, bootloader configuration, kernel and initramfs.
36 """
37
38 def __init__(self, creatoropts = None, pkgmgr = None):
39 """Initialise a LiveImageCreator instance.
40
41 This method takes the same arguments as ImageCreator.__init__().
42 """
43 LoopImageCreator.__init__(self, creatoropts, pkgmgr)
44
45 #Controls whether to use squashfs to compress the image.
46 self.skip_compression = False
47
48 #Controls whether an image minimizing snapshot should be created.
49 #
50 #This snapshot can be used when copying the system image from the ISO in
51 #order to minimize the amount of data that needs to be copied; simply,
52 #it makes it possible to create a version of the image's filesystem with
53 #no spare space.
54 self.skip_minimize = False
55
56 #A flag which indicates i act as a convertor default false
57 self.actasconvertor = False
58
59 #The bootloader timeout from kickstart.
60 if self.ks:
61 self._timeout = kickstart.get_timeout(self.ks, 10)
62 else:
63 self._timeout = 10
64
65 #The default kernel type from kickstart.
66 if self.ks:
67 self._default_kernel = kickstart.get_default_kernel(self.ks,
68 "kernel")
69 else:
70 self._default_kernel = None
71
72 if self.ks:
73 parts = kickstart.get_partitions(self.ks)
74 if len(parts) > 1:
75 raise CreatorError("Can't support multi partitions in ks file "
76 "for this image type")
77 # FIXME: rename rootfs img to self.name,
78 # else can't find files when create iso
79 self._instloops[0]['name'] = self.name + ".img"
80
81 self.__isodir = None
82
83 self.__modules = ["=ata",
84 "sym53c8xx",
85 "aic7xxx",
86 "=usb",
87 "=firewire",
88 "=mmc",
89 "=pcmcia",
90 "mptsas"]
91 if self.ks:
92 self.__modules.extend(kickstart.get_modules(self.ks))
93
94 self._dep_checks.extend(["isohybrid",
95 "unsquashfs",
96 "mksquashfs",
97 "dd",
98 "genisoimage"])
99
100 #
101 # Hooks for subclasses
102 #
103 def _configure_bootloader(self, isodir):
104 """Create the architecture specific booloader configuration.
105
106 This is the hook where subclasses must create the booloader
107 configuration in order to allow a bootable ISO to be built.
108
109 isodir -- the directory where the contents of the ISO are to
110 be staged
111 """
112 raise CreatorError("Bootloader configuration is arch-specific, "
113 "but not implemented for this arch!")
114 def _get_menu_options(self):
115 """Return a menu options string for syslinux configuration.
116 """
117 if self.ks is None:
118 return "liveinst autoinst"
119 r = kickstart.get_menu_args(self.ks)
120 return r
121
122 def _get_kernel_options(self):
123 """Return a kernel options string for bootloader configuration.
124
125 This is the hook where subclasses may specify a set of kernel
126 options which should be included in the images bootloader
127 configuration.
128
129 A sensible default implementation is provided.
130 """
131
132 if self.ks is None:
133 r = "ro rd.live.image"
134 else:
135 r = kickstart.get_kernel_args(self.ks)
136
137 return r
138
139 def _get_mkisofs_options(self, isodir):
140 """Return the architecture specific mkisosfs options.
141
142 This is the hook where subclasses may specify additional arguments
143 to mkisofs, e.g. to enable a bootable ISO to be built.
144
145 By default, an empty list is returned.
146 """
147 return []
148
149 #
150 # Helpers for subclasses
151 #
152 def _has_checkisomd5(self):
153 """Check whether checkisomd5 is available in the install root."""
154 def _exists(path):
155 return os.path.exists(self._instroot + path)
156
157 if _exists("/usr/bin/checkisomd5") and os.path.exists("/usr/bin/implantisomd5"):
158 return True
159
160 return False
161
162 def __restore_file(self,path):
163 try:
164 os.unlink(path)
165 except:
166 pass
167 if os.path.exists(path + '.rpmnew'):
168 os.rename(path + '.rpmnew', path)
169
170 def _mount_instroot(self, base_on = None):
171 LoopImageCreator._mount_instroot(self, base_on)
172 self.__write_initrd_conf(self._instroot + "/etc/sysconfig/mkinitrd")
173 self.__write_dracut_conf(self._instroot + "/etc/dracut.conf.d/02livecd.conf")
174
175 def _unmount_instroot(self):
176 self.__restore_file(self._instroot + "/etc/sysconfig/mkinitrd")
177 self.__restore_file(self._instroot + "/etc/dracut.conf.d/02livecd.conf")
178 LoopImageCreator._unmount_instroot(self)
179
180 def __ensure_isodir(self):
181 if self.__isodir is None:
182 self.__isodir = self._mkdtemp("iso-")
183 return self.__isodir
184
185 def _get_isodir(self):
186 return self.__ensure_isodir()
187
188 def _set_isodir(self, isodir = None):
189 self.__isodir = isodir
190
191 def _create_bootconfig(self):
192 """Configure the image so that it's bootable."""
193 self._configure_bootloader(self.__ensure_isodir())
194
195 def _get_post_scripts_env(self, in_chroot):
196 env = LoopImageCreator._get_post_scripts_env(self, in_chroot)
197
198 if not in_chroot:
199 env["LIVE_ROOT"] = self.__ensure_isodir()
200
201 return env
202 def __write_dracut_conf(self, path):
203 if not os.path.exists(os.path.dirname(path)):
204 fs_related.makedirs(os.path.dirname(path))
205 f = open(path, "a")
206 f.write('add_dracutmodules+=" dmsquash-live pollcdrom "')
207 f.close()
208
209 def __write_initrd_conf(self, path):
210 content = ""
211 if not os.path.exists(os.path.dirname(path)):
212 fs_related.makedirs(os.path.dirname(path))
213 f = open(path, "w")
214
215 content += 'LIVEOS="yes"\n'
216 content += 'PROBE="no"\n'
217 content += 'MODULES+="squashfs ext3 ext2 vfat msdos "\n'
218 content += 'MODULES+="sr_mod sd_mod ide-cd cdrom "\n'
219
220 for module in self.__modules:
221 if module == "=usb":
222 content += 'MODULES+="ehci_hcd uhci_hcd ohci_hcd "\n'
223 content += 'MODULES+="usb_storage usbhid "\n'
224 elif module == "=firewire":
225 content += 'MODULES+="firewire-sbp2 firewire-ohci "\n'
226 content += 'MODULES+="sbp2 ohci1394 ieee1394 "\n'
227 elif module == "=mmc":
228 content += 'MODULES+="mmc_block sdhci sdhci-pci "\n'
229 elif module == "=pcmcia":
230 content += 'MODULES+="pata_pcmcia "\n'
231 else:
232 content += 'MODULES+="' + module + ' "\n'
233 f.write(content)
234 f.close()
235
236 def __create_iso(self, isodir):
237 iso = self._outdir + "/" + self.name + ".iso"
238 genisoimage = fs_related.find_binary_path("genisoimage")
239 args = [genisoimage,
240 "-J", "-r",
241 "-hide-rr-moved", "-hide-joliet-trans-tbl",
242 "-V", self.fslabel,
243 "-o", iso]
244
245 args.extend(self._get_mkisofs_options(isodir))
246
247 args.append(isodir)
248
249 if runner.show(args) != 0:
250 raise CreatorError("ISO creation failed!")
251
252 """ It should be ok still even if you haven't isohybrid """
253 isohybrid = None
254 try:
255 isohybrid = fs_related.find_binary_path("isohybrid")
256 except:
257 pass
258
259 if isohybrid:
260 args = [isohybrid, "-partok", iso ]
261 if runner.show(args) != 0:
262 raise CreatorError("Hybrid ISO creation failed!")
263
264 self.__implant_md5sum(iso)
265
266 def __implant_md5sum(self, iso):
267 """Implant an isomd5sum."""
268 if os.path.exists("/usr/bin/implantisomd5"):
269 implantisomd5 = "/usr/bin/implantisomd5"
270 else:
271 msger.warning("isomd5sum not installed; not setting up mediacheck")
272 implantisomd5 = ""
273 return
274
275 runner.show([implantisomd5, iso])
276
277 def _stage_final_image(self):
278 try:
279 fs_related.makedirs(self.__ensure_isodir() + "/LiveOS")
280
281 minimal_size = self._resparse()
282
283 if not self.skip_minimize:
284 fs_related.create_image_minimizer(self.__isodir + \
285 "/LiveOS/osmin.img",
286 self._image,
287 minimal_size)
288
289 if self.skip_compression:
290 shutil.move(self._image, self.__isodir + "/LiveOS/ext3fs.img")
291 else:
292 fs_related.makedirs(os.path.join(
293 os.path.dirname(self._image),
294 "LiveOS"))
295 shutil.move(self._image,
296 os.path.join(os.path.dirname(self._image),
297 "LiveOS", "ext3fs.img"))
298 fs_related.mksquashfs(os.path.dirname(self._image),
299 self.__isodir + "/LiveOS/squashfs.img")
300
301 self.__create_iso(self.__isodir)
302
303 if self.pack_to:
304 isoimg = os.path.join(self._outdir, self.name + ".iso")
305 packimg = os.path.join(self._outdir, self.pack_to)
306 misc.packing(packimg, isoimg)
307 os.unlink(isoimg)
308
309 finally:
310 shutil.rmtree(self.__isodir, ignore_errors = True)
311 self.__isodir = None
312
313class x86LiveImageCreator(LiveImageCreatorBase):
314 """ImageCreator for x86 machines"""
315 def _get_mkisofs_options(self, isodir):
316 return [ "-b", "isolinux/isolinux.bin",
317 "-c", "isolinux/boot.cat",
318 "-no-emul-boot", "-boot-info-table",
319 "-boot-load-size", "4" ]
320
321 def _get_required_packages(self):
322 return ["syslinux", "syslinux-extlinux"] + \
323 LiveImageCreatorBase._get_required_packages(self)
324
325 def _get_isolinux_stanzas(self, isodir):
326 return ""
327
328 def __find_syslinux_menu(self):
329 for menu in ["vesamenu.c32", "menu.c32"]:
330 if os.path.isfile(self._instroot + "/usr/share/syslinux/" + menu):
331 return menu
332
333 raise CreatorError("syslinux not installed : "
334 "no suitable /usr/share/syslinux/*menu.c32 found")
335
336 def __find_syslinux_mboot(self):
337 #
338 # We only need the mboot module if we have any xen hypervisors
339 #
340 if not glob.glob(self._instroot + "/boot/xen.gz*"):
341 return None
342
343 return "mboot.c32"
344
345 def __copy_syslinux_files(self, isodir, menu, mboot = None):
346 files = ["isolinux.bin", menu]
347 if mboot:
348 files += [mboot]
349
350 for f in files:
351 path = self._instroot + "/usr/share/syslinux/" + f
352
353 if not os.path.isfile(path):
354 raise CreatorError("syslinux not installed : "
355 "%s not found" % path)
356
357 shutil.copy(path, isodir + "/isolinux/")
358
359 def __copy_syslinux_background(self, isodest):
360 background_path = self._instroot + \
361 "/usr/share/branding/default/syslinux/syslinux-vesa-splash.jpg"
362
363 if not os.path.exists(background_path):
364 return False
365
366 shutil.copyfile(background_path, isodest)
367
368 return True
369
370 def __copy_kernel_and_initramfs(self, isodir, version, index):
371 bootdir = self._instroot + "/boot"
372 isDracut = False
373
374 if self._alt_initrd_name:
375 src_initrd_path = os.path.join(bootdir, self._alt_initrd_name)
376 else:
377 if os.path.exists(bootdir + "/initramfs-" + version + ".img"):
378 src_initrd_path = os.path.join(bootdir, "initramfs-" +version+ ".img")
379 isDracut = True
380 else:
381 src_initrd_path = os.path.join(bootdir, "initrd-" +version+ ".img")
382
383 try:
384 msger.debug("copy %s to %s" % (bootdir + "/vmlinuz-" + version, isodir + "/isolinux/vmlinuz" + index))
385 shutil.copyfile(bootdir + "/vmlinuz-" + version,
386 isodir + "/isolinux/vmlinuz" + index)
387
388 msger.debug("copy %s to %s" % (src_initrd_path, isodir + "/isolinux/initrd" + index + ".img"))
389 shutil.copyfile(src_initrd_path,
390 isodir + "/isolinux/initrd" + index + ".img")
391 except:
392 raise CreatorError("Unable to copy valid kernels or initrds, "
393 "please check the repo.")
394
395 is_xen = False
396 if os.path.exists(bootdir + "/xen.gz-" + version[:-3]):
397 shutil.copyfile(bootdir + "/xen.gz-" + version[:-3],
398 isodir + "/isolinux/xen" + index + ".gz")
399 is_xen = True
400
401 return (is_xen,isDracut)
402
403 def __is_default_kernel(self, kernel, kernels):
404 if len(kernels) == 1:
405 return True
406
407 if kernel == self._default_kernel:
408 return True
409
410 if kernel.startswith("kernel-") and kernel[7:] == self._default_kernel:
411 return True
412
413 return False
414
415 def __get_basic_syslinux_config(self, **args):
416 return """
417default %(menu)s
418timeout %(timeout)d
419
420%(background)s
421menu title Welcome to %(distroname)s!
422menu color border 0 #ffffffff #00000000
423menu color sel 7 #ff000000 #ffffffff
424menu color title 0 #ffffffff #00000000
425menu color tabmsg 0 #ffffffff #00000000
426menu color unsel 0 #ffffffff #00000000
427menu color hotsel 0 #ff000000 #ffffffff
428menu color hotkey 7 #ffffffff #ff000000
429menu color timeout_msg 0 #ffffffff #00000000
430menu color timeout 0 #ffffffff #00000000
431menu color cmdline 0 #ffffffff #00000000
432menu hidden
433menu clear
434""" % args
435
436 def __get_image_stanza(self, is_xen, isDracut, **args):
437 if isDracut:
438 args["rootlabel"] = "live:CDLABEL=%(fslabel)s" % args
439 else:
440 args["rootlabel"] = "CDLABEL=%(fslabel)s" % args
441 if not is_xen:
442 template = """label %(short)s
443 menu label %(long)s
444 kernel vmlinuz%(index)s
445 append initrd=initrd%(index)s.img root=%(rootlabel)s rootfstype=iso9660 %(liveargs)s %(extra)s
446"""
447 else:
448 template = """label %(short)s
449 menu label %(long)s
450 kernel mboot.c32
451 append xen%(index)s.gz --- vmlinuz%(index)s root=%(rootlabel)s rootfstype=iso9660 %(liveargs)s %(extra)s --- initrd%(index)s.img
452"""
453 return template % args
454
455 def __get_image_stanzas(self, isodir):
456 versions = []
457 kernels = self._get_kernel_versions()
458 for kernel in kernels:
459 for version in kernels[kernel]:
460 versions.append(version)
461
462 if not versions:
463 raise CreatorError("Unable to find valid kernels, "
464 "please check the repo")
465
466 kernel_options = self._get_kernel_options()
467
468 """ menu can be customized highly, the format is:
469
470 short_name1:long_name1:extra_opts1;short_name2:long_name2:extra_opts2
471
472 e.g.: autoinst:InstallationOnly:systemd.unit=installer-graphical.service
473 but in order to keep compatible with old format, these are still ok:
474
475 liveinst autoinst
476 liveinst;autoinst
477 liveinst::;autoinst::
478 """
479 oldmenus = {"basic": {
480 "short": "basic",
481 "long": "Installation Only (Text based)",
482 "extra": "basic nosplash 4"
483 },
484 "liveinst": {
485 "short": "liveinst",
486 "long": "Installation Only",
487 "extra": "liveinst nosplash 4"
488 },
489 "autoinst": {
490 "short": "autoinst",
491 "long": "Autoinstall (Deletes all existing content)",
492 "extra": "autoinst nosplash 4"
493 },
494 "netinst": {
495 "short": "netinst",
496 "long": "Network Installation",
497 "extra": "netinst 4"
498 },
499 "verify": {
500 "short": "check",
501 "long": "Verify and",
502 "extra": "check"
503 }
504 }
505 menu_options = self._get_menu_options()
506 menus = menu_options.split(";")
507 for i in range(len(menus)):
508 menus[i] = menus[i].split(":")
509 if len(menus) == 1 and len(menus[0]) == 1:
510 """ Keep compatible with the old usage way """
511 menus = menu_options.split()
512 for i in range(len(menus)):
513 menus[i] = [menus[i]]
514
515 cfg = ""
516
517 default_version = None
518 default_index = None
519 index = "0"
520 netinst = None
521 for version in versions:
522 (is_xen, isDracut) = self.__copy_kernel_and_initramfs(isodir, version, index)
523 if index == "0":
524 self._isDracut = isDracut
525
526 default = self.__is_default_kernel(kernel, kernels)
527
528 if default:
529 long = "Boot %s" % self.distro_name
530 elif kernel.startswith("kernel-"):
531 long = "Boot %s(%s)" % (self.name, kernel[7:])
532 else:
533 long = "Boot %s(%s)" % (self.name, kernel)
534
535 oldmenus["verify"]["long"] = "%s %s" % (oldmenus["verify"]["long"],
536 long)
537 # tell dracut not to ask for LUKS passwords or activate mdraid sets
538 if isDracut:
539 kern_opts = kernel_options + " rd.luks=0 rd.md=0 rd.dm=0"
540 else:
541 kern_opts = kernel_options
542
543 cfg += self.__get_image_stanza(is_xen, isDracut,
544 fslabel = self.fslabel,
545 liveargs = kern_opts,
546 long = long,
547 short = "linux" + index,
548 extra = "",
549 index = index)
550
551 if default:
552 cfg += "menu default\n"
553 default_version = version
554 default_index = index
555
556 for menu in menus:
557 if not menu[0]:
558 continue
559 short = menu[0] + index
560
561 if len(menu) >= 2:
562 long = menu[1]
563 else:
564 if menu[0] in oldmenus.keys():
565 if menu[0] == "verify" and not self._has_checkisomd5():
566 continue
567 if menu[0] == "netinst":
568 netinst = oldmenus[menu[0]]
569 continue
570 long = oldmenus[menu[0]]["long"]
571 extra = oldmenus[menu[0]]["extra"]
572 else:
573 long = short.upper() + " X" + index
574 extra = ""
575
576 if len(menu) >= 3:
577 extra = menu[2]
578
579 cfg += self.__get_image_stanza(is_xen, isDracut,
580 fslabel = self.fslabel,
581 liveargs = kernel_options,
582 long = long,
583 short = short,
584 extra = extra,
585 index = index)
586
587 index = str(int(index) + 1)
588
589 if not default_version:
590 default_version = versions[0]
591 if not default_index:
592 default_index = "0"
593
594 if netinst:
595 cfg += self.__get_image_stanza(is_xen, isDracut,
596 fslabel = self.fslabel,
597 liveargs = kernel_options,
598 long = netinst["long"],
599 short = netinst["short"],
600 extra = netinst["extra"],
601 index = default_index)
602
603 return cfg
604
605 def __get_memtest_stanza(self, isodir):
606 memtest = glob.glob(self._instroot + "/boot/memtest86*")
607 if not memtest:
608 return ""
609
610 shutil.copyfile(memtest[0], isodir + "/isolinux/memtest")
611
612 return """label memtest
613 menu label Memory Test
614 kernel memtest
615"""
616
617 def __get_local_stanza(self, isodir):
618 return """label local
619 menu label Boot from local drive
620 localboot 0xffff
621"""
622
623 def _configure_syslinux_bootloader(self, isodir):
624 """configure the boot loader"""
625 fs_related.makedirs(isodir + "/isolinux")
626
627 menu = self.__find_syslinux_menu()
628
629 self.__copy_syslinux_files(isodir, menu,
630 self.__find_syslinux_mboot())
631
632 background = ""
633 if self.__copy_syslinux_background(isodir + "/isolinux/splash.jpg"):
634 background = "menu background splash.jpg"
635
636 cfg = self.__get_basic_syslinux_config(menu = menu,
637 background = background,
638 name = self.name,
639 timeout = self._timeout * 10,
640 distroname = self.distro_name)
641
642 cfg += self.__get_image_stanzas(isodir)
643 cfg += self.__get_memtest_stanza(isodir)
644 cfg += self.__get_local_stanza(isodir)
645 cfg += self._get_isolinux_stanzas(isodir)
646
647 cfgf = open(isodir + "/isolinux/isolinux.cfg", "w")
648 cfgf.write(cfg)
649 cfgf.close()
650
651 def __copy_efi_files(self, isodir):
652 if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"):
653 return False
654 shutil.copy(self._instroot + "/boot/efi/EFI/redhat/grub.efi",
655 isodir + "/EFI/boot/grub.efi")
656 shutil.copy(self._instroot + "/boot/grub/splash.xpm.gz",
657 isodir + "/EFI/boot/splash.xpm.gz")
658
659 return True
660
661 def __get_basic_efi_config(self, **args):
662 return """
663default=0
664splashimage=/EFI/boot/splash.xpm.gz
665timeout %(timeout)d
666hiddenmenu
667
668""" %args
669
670 def __get_efi_image_stanza(self, **args):
671 return """title %(long)s
672 kernel /EFI/boot/vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s
673 initrd /EFI/boot/initrd%(index)s.img
674""" %args
675
676 def __get_efi_image_stanzas(self, isodir, name):
677 # FIXME: this only supports one kernel right now...
678
679 kernel_options = self._get_kernel_options()
680 checkisomd5 = self._has_checkisomd5()
681
682 cfg = ""
683
684 for index in range(0, 9):
685 # we don't support xen kernels
686 if os.path.exists("%s/EFI/boot/xen%d.gz" %(isodir, index)):
687 continue
688 cfg += self.__get_efi_image_stanza(fslabel = self.fslabel,
689 liveargs = kernel_options,
690 long = name,
691 extra = "", index = index)
692 if checkisomd5:
693 cfg += self.__get_efi_image_stanza(
694 fslabel = self.fslabel,
695 liveargs = kernel_options,
696 long = "Verify and Boot " + name,
697 extra = "check",
698 index = index)
699 break
700
701 return cfg
702
703 def _configure_efi_bootloader(self, isodir):
704 """Set up the configuration for an EFI bootloader"""
705 fs_related.makedirs(isodir + "/EFI/boot")
706
707 if not self.__copy_efi_files(isodir):
708 shutil.rmtree(isodir + "/EFI")
709 return
710
711 for f in os.listdir(isodir + "/isolinux"):
712 os.link("%s/isolinux/%s" %(isodir, f),
713 "%s/EFI/boot/%s" %(isodir, f))
714
715
716 cfg = self.__get_basic_efi_config(name = self.name,
717 timeout = self._timeout)
718 cfg += self.__get_efi_image_stanzas(isodir, self.name)
719
720 cfgf = open(isodir + "/EFI/boot/grub.conf", "w")
721 cfgf.write(cfg)
722 cfgf.close()
723
724 # first gen mactel machines get the bootloader name wrong apparently
725 if rpmmisc.getBaseArch() == "i386":
726 os.link(isodir + "/EFI/boot/grub.efi",
727 isodir + "/EFI/boot/boot.efi")
728 os.link(isodir + "/EFI/boot/grub.conf",
729 isodir + "/EFI/boot/boot.conf")
730
731 # for most things, we want them named boot$efiarch
732 efiarch = {"i386": "ia32", "x86_64": "x64"}
733 efiname = efiarch[rpmmisc.getBaseArch()]
734 os.rename(isodir + "/EFI/boot/grub.efi",
735 isodir + "/EFI/boot/boot%s.efi" %(efiname,))
736 os.link(isodir + "/EFI/boot/grub.conf",
737 isodir + "/EFI/boot/boot%s.conf" %(efiname,))
738
739
740 def _configure_bootloader(self, isodir):
741 self._configure_syslinux_bootloader(isodir)
742 self._configure_efi_bootloader(isodir)
743
744arch = "i386"
745if arch in ("i386", "x86_64"):
746 LiveCDImageCreator = x86LiveImageCreator
747elif arch.startswith("arm"):
748 LiveCDImageCreator = LiveImageCreatorBase
749else:
750 raise CreatorError("Architecture not supported!")
diff --git a/scripts/lib/mic/imager/liveusb.py b/scripts/lib/mic/imager/liveusb.py
deleted file mode 100644
index a909928a4c..0000000000
--- a/scripts/lib/mic/imager/liveusb.py
+++ /dev/null
@@ -1,308 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import re
21
22from mic import msger
23from mic.utils import misc, fs_related, runner
24from mic.utils.errors import CreatorError, MountError
25from mic.utils.partitionedfs import PartitionedMount
26from mic.imager.livecd import LiveCDImageCreator
27
28
29class LiveUSBImageCreator(LiveCDImageCreator):
30 def __init__(self, *args):
31 LiveCDImageCreator.__init__(self, *args)
32
33 self._dep_checks.extend(["kpartx", "parted"])
34
35 # remove dependency of genisoimage in parent class
36 if "genisoimage" in self._dep_checks:
37 self._dep_checks.remove("genisoimage")
38
39 def _create_usbimg(self, isodir):
40 overlaysizemb = 64 #default
41 #skipcompress = self.skip_compression?
42 fstype = "vfat"
43 homesizemb=0
44 swapsizemb=0
45 homefile="home.img"
46 plussize=128
47 kernelargs=None
48
49 if fstype == 'vfat':
50 if overlaysizemb > 2047:
51 raise CreatorError("Can't have an overlay of 2048MB or "
52 "greater on VFAT")
53
54 if homesizemb > 2047:
55 raise CreatorError("Can't have an home overlay of 2048MB or "
56 "greater on VFAT")
57
58 if swapsizemb > 2047:
59 raise CreatorError("Can't have an swap overlay of 2048MB or "
60 "greater on VFAT")
61
62 livesize = misc.get_file_size(isodir + "/LiveOS")
63
64 usbimgsize = (overlaysizemb + \
65 homesizemb + \
66 swapsizemb + \
67 livesize + \
68 plussize) * 1024L * 1024L
69
70 disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \
71 % (self._outdir, self.name),
72 usbimgsize)
73 usbmnt = self._mkdtemp("usb-mnt")
74 usbloop = PartitionedMount(usbmnt)
75 usbloop.add_disk('/dev/sdb', disk)
76
77 usbloop.add_partition(usbimgsize/1024/1024,
78 "/dev/sdb",
79 "/",
80 fstype,
81 boot=True)
82
83 usbloop.mount()
84
85 try:
86 fs_related.makedirs(usbmnt + "/LiveOS")
87
88 if os.path.exists(isodir + "/LiveOS/squashfs.img"):
89 shutil.copyfile(isodir + "/LiveOS/squashfs.img",
90 usbmnt + "/LiveOS/squashfs.img")
91 else:
92 fs_related.mksquashfs(os.path.dirname(self._image),
93 usbmnt + "/LiveOS/squashfs.img")
94
95 if os.path.exists(isodir + "/LiveOS/osmin.img"):
96 shutil.copyfile(isodir + "/LiveOS/osmin.img",
97 usbmnt + "/LiveOS/osmin.img")
98
99 if fstype == "vfat" or fstype == "msdos":
100 uuid = usbloop.partitions[0]['mount'].uuid
101 label = usbloop.partitions[0]['mount'].fslabel
102 usblabel = "UUID=%s-%s" % (uuid[0:4], uuid[4:8])
103 overlaysuffix = "-%s-%s-%s" % (label, uuid[0:4], uuid[4:8])
104 else:
105 diskmount = usbloop.partitions[0]['mount']
106 usblabel = "UUID=%s" % diskmount.uuid
107 overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid)
108
109 args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"]
110 rc = runner.show(args)
111 if rc:
112 raise CreatorError("Can't copy isolinux directory %s" \
113 % (isodir + "/isolinux/*"))
114
115 if os.path.isfile("/usr/share/syslinux/isolinux.bin"):
116 syslinux_path = "/usr/share/syslinux"
117 elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"):
118 syslinux_path = "/usr/lib/syslinux"
119 else:
120 raise CreatorError("syslinux not installed : "
121 "cannot find syslinux installation path")
122
123 for f in ("isolinux.bin", "vesamenu.c32"):
124 path = os.path.join(syslinux_path, f)
125 if os.path.isfile(path):
126 args = ['cp', path, usbmnt + "/syslinux/"]
127 rc = runner.show(args)
128 if rc:
129 raise CreatorError("Can't copy syslinux file " + path)
130 else:
131 raise CreatorError("syslinux not installed: "
132 "syslinux file %s not found" % path)
133
134 fd = open(isodir + "/isolinux/isolinux.cfg", "r")
135 text = fd.read()
136 fd.close()
137 pattern = re.compile('CDLABEL=[^ ]*')
138 text = pattern.sub(usblabel, text)
139 pattern = re.compile('rootfstype=[^ ]*')
140 text = pattern.sub("rootfstype=" + fstype, text)
141 if kernelargs:
142 text = text.replace("rd.live.image", "rd.live.image " + kernelargs)
143
144 if overlaysizemb > 0:
145 msger.info("Initializing persistent overlay file")
146 overfile = "overlay" + overlaysuffix
147 if fstype == "vfat":
148 args = ['dd',
149 "if=/dev/zero",
150 "of=" + usbmnt + "/LiveOS/" + overfile,
151 "count=%d" % overlaysizemb,
152 "bs=1M"]
153 else:
154 args = ['dd',
155 "if=/dev/null",
156 "of=" + usbmnt + "/LiveOS/" + overfile,
157 "count=1",
158 "bs=1M",
159 "seek=%d" % overlaysizemb]
160 rc = runner.show(args)
161 if rc:
162 raise CreatorError("Can't create overlay file")
163 text = text.replace("rd.live.image", "rd.live.image rd.live.overlay=" + usblabel)
164 text = text.replace(" ro ", " rw ")
165
166 if swapsizemb > 0:
167 msger.info("Initializing swap file")
168 swapfile = usbmnt + "/LiveOS/" + "swap.img"
169 args = ['dd',
170 "if=/dev/zero",
171 "of=" + swapfile,
172 "count=%d" % swapsizemb,
173 "bs=1M"]
174 rc = runner.show(args)
175 if rc:
176 raise CreatorError("Can't create swap file")
177 args = ["mkswap", "-f", swapfile]
178 rc = runner.show(args)
179 if rc:
180 raise CreatorError("Can't mkswap on swap file")
181
182 if homesizemb > 0:
183 msger.info("Initializing persistent /home")
184 homefile = usbmnt + "/LiveOS/" + homefile
185 if fstype == "vfat":
186 args = ['dd',
187 "if=/dev/zero",
188 "of=" + homefile,
189 "count=%d" % homesizemb,
190 "bs=1M"]
191 else:
192 args = ['dd',
193 "if=/dev/null",
194 "of=" + homefile,
195 "count=1",
196 "bs=1M",
197 "seek=%d" % homesizemb]
198 rc = runner.show(args)
199 if rc:
200 raise CreatorError("Can't create home file")
201
202 mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype)
203 if fstype == "ext2" or fstype == "ext3":
204 args = [mkfscmd, "-F", "-j", homefile]
205 else:
206 args = [mkfscmd, homefile]
207 rc = runner.show(args)
208 if rc:
209 raise CreatorError("Can't mke2fs home file")
210 if fstype == "ext2" or fstype == "ext3":
211 tune2fs = fs_related.find_binary_path("tune2fs")
212 args = [tune2fs,
213 "-c0",
214 "-i0",
215 "-ouser_xattr,acl",
216 homefile]
217 rc = runner.show(args)
218 if rc:
219 raise CreatorError("Can't tune2fs home file")
220
221 if fstype == "vfat" or fstype == "msdos":
222 syslinuxcmd = fs_related.find_binary_path("syslinux")
223 syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg"
224 args = [syslinuxcmd,
225 "-d",
226 "syslinux",
227 usbloop.partitions[0]["device"]]
228
229 elif fstype == "ext2" or fstype == "ext3":
230 extlinuxcmd = fs_related.find_binary_path("extlinux")
231 syslinuxcfg = usbmnt + "/syslinux/extlinux.conf"
232 args = [extlinuxcmd,
233 "-i",
234 usbmnt + "/syslinux"]
235
236 else:
237 raise CreatorError("Invalid file system type: %s" % (fstype))
238
239 os.unlink(usbmnt + "/syslinux/isolinux.cfg")
240 fd = open(syslinuxcfg, "w")
241 fd.write(text)
242 fd.close()
243 rc = runner.show(args)
244 if rc:
245 raise CreatorError("Can't install boot loader.")
246
247 finally:
248 usbloop.unmount()
249 usbloop.cleanup()
250
251 # Need to do this after image is unmounted and device mapper is closed
252 msger.info("set MBR")
253 mbrfile = "/usr/lib/syslinux/mbr.bin"
254 if not os.path.exists(mbrfile):
255 mbrfile = "/usr/share/syslinux/mbr.bin"
256 if not os.path.exists(mbrfile):
257 raise CreatorError("mbr.bin file didn't exist.")
258 mbrsize = os.path.getsize(mbrfile)
259 outimg = "%s/%s.usbimg" % (self._outdir, self.name)
260
261 args = ['dd',
262 "if=" + mbrfile,
263 "of=" + outimg,
264 "seek=0",
265 "conv=notrunc",
266 "bs=1",
267 "count=%d" % (mbrsize)]
268 rc = runner.show(args)
269 if rc:
270 raise CreatorError("Can't set MBR.")
271
272 def _stage_final_image(self):
273 try:
274 isodir = self._get_isodir()
275 fs_related.makedirs(isodir + "/LiveOS")
276
277 minimal_size = self._resparse()
278
279 if not self.skip_minimize:
280 fs_related.create_image_minimizer(isodir + "/LiveOS/osmin.img",
281 self._image,
282 minimal_size)
283
284 if self.skip_compression:
285 shutil.move(self._image,
286 isodir + "/LiveOS/ext3fs.img")
287 else:
288 fs_related.makedirs(os.path.join(
289 os.path.dirname(self._image),
290 "LiveOS"))
291 shutil.move(self._image,
292 os.path.join(os.path.dirname(self._image),
293 "LiveOS", "ext3fs.img"))
294 fs_related.mksquashfs(os.path.dirname(self._image),
295 isodir + "/LiveOS/squashfs.img")
296
297 self._create_usbimg(isodir)
298
299 if self.pack_to:
300 usbimg = os.path.join(self._outdir, self.name + ".usbimg")
301 packimg = os.path.join(self._outdir, self.pack_to)
302 misc.packing(packimg, usbimg)
303 os.unlink(usbimg)
304
305 finally:
306 shutil.rmtree(isodir, ignore_errors = True)
307 self._set_isodir(None)
308
diff --git a/scripts/lib/mic/imager/loop.py b/scripts/lib/mic/imager/loop.py
deleted file mode 100644
index 4d05ef271d..0000000000
--- a/scripts/lib/mic/imager/loop.py
+++ /dev/null
@@ -1,418 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import glob
20import shutil
21
22from mic import kickstart, msger
23from mic.utils.errors import CreatorError, MountError
24from mic.utils import misc, runner, fs_related as fs
25from mic.imager.baseimager import BaseImageCreator
26
27
28# The maximum string length supported for LoopImageCreator.fslabel
29FSLABEL_MAXLEN = 32
30
31
32def save_mountpoints(fpath, loops, arch = None):
33 """Save mount points mapping to file
34
35 :fpath, the xml file to store partition info
36 :loops, dict of partition info
37 :arch, image arch
38 """
39
40 if not fpath or not loops:
41 return
42
43 from xml.dom import minidom
44 doc = minidom.Document()
45 imgroot = doc.createElement("image")
46 doc.appendChild(imgroot)
47 if arch:
48 imgroot.setAttribute('arch', arch)
49 for loop in loops:
50 part = doc.createElement("partition")
51 imgroot.appendChild(part)
52 for (key, val) in loop.items():
53 if isinstance(val, fs.Mount):
54 continue
55 part.setAttribute(key, str(val))
56
57 with open(fpath, 'w') as wf:
58 wf.write(doc.toprettyxml(indent=' '))
59
60 return
61
62def load_mountpoints(fpath):
63 """Load mount points mapping from file
64
65 :fpath, file path to load
66 """
67
68 if not fpath:
69 return
70
71 from xml.dom import minidom
72 mount_maps = []
73 with open(fpath, 'r') as rf:
74 dom = minidom.parse(rf)
75 imgroot = dom.documentElement
76 for part in imgroot.getElementsByTagName("partition"):
77 p = dict(part.attributes.items())
78
79 try:
80 mp = (p['mountpoint'], p['label'], p['name'],
81 int(p['size']), p['fstype'])
82 except KeyError:
83 msger.warning("Wrong format line in file: %s" % fpath)
84 except ValueError:
85 msger.warning("Invalid size '%s' in file: %s" % (p['size'], fpath))
86 else:
87 mount_maps.append(mp)
88
89 return mount_maps
90
91class LoopImageCreator(BaseImageCreator):
92 """Installs a system into a loopback-mountable filesystem image.
93
94 LoopImageCreator is a straightforward ImageCreator subclass; the system
95 is installed into an ext3 filesystem on a sparse file which can be
96 subsequently loopback-mounted.
97
98 When specifying multiple partitions in kickstart file, each partition
99 will be created as a separated loop image.
100 """
101
102 def __init__(self, creatoropts=None, pkgmgr=None,
103 compress_image=None,
104 shrink_image=False):
105 """Initialize a LoopImageCreator instance.
106
107 This method takes the same arguments as ImageCreator.__init__()
108 with the addition of:
109
110 fslabel -- A string used as a label for any filesystems created.
111 """
112
113 BaseImageCreator.__init__(self, creatoropts, pkgmgr)
114
115 self.compress_image = compress_image
116 self.shrink_image = shrink_image
117
118 self.__fslabel = None
119 self.fslabel = self.name
120
121 self.__blocksize = 4096
122 if self.ks:
123 self.__fstype = kickstart.get_image_fstype(self.ks,
124 "ext3")
125 self.__fsopts = kickstart.get_image_fsopts(self.ks,
126 "defaults,noatime")
127
128 allloops = []
129 for part in sorted(kickstart.get_partitions(self.ks),
130 key=lambda p: p.mountpoint):
131 if part.fstype == "swap":
132 continue
133
134 label = part.label
135 mp = part.mountpoint
136 if mp == '/':
137 # the base image
138 if not label:
139 label = self.name
140 else:
141 mp = mp.rstrip('/')
142 if not label:
143 msger.warning('no "label" specified for loop img at %s'
144 ', use the mountpoint as the name' % mp)
145 label = mp.split('/')[-1]
146
147 imgname = misc.strip_end(label, '.img') + '.img'
148 allloops.append({
149 'mountpoint': mp,
150 'label': label,
151 'name': imgname,
152 'size': part.size or 4096L * 1024 * 1024,
153 'fstype': part.fstype or 'ext3',
154 'extopts': part.extopts or None,
155 'loop': None, # to be created in _mount_instroot
156 })
157 self._instloops = allloops
158
159 else:
160 self.__fstype = None
161 self.__fsopts = None
162 self._instloops = []
163
164 self.__imgdir = None
165
166 if self.ks:
167 self.__image_size = kickstart.get_image_size(self.ks,
168 4096L * 1024 * 1024)
169 else:
170 self.__image_size = 0
171
172 self._img_name = self.name + ".img"
173
174 def get_image_names(self):
175 if not self._instloops:
176 return None
177
178 return [lo['name'] for lo in self._instloops]
179
180 def _set_fstype(self, fstype):
181 self.__fstype = fstype
182
183 def _set_image_size(self, imgsize):
184 self.__image_size = imgsize
185
186
187 #
188 # Properties
189 #
190 def __get_fslabel(self):
191 if self.__fslabel is None:
192 return self.name
193 else:
194 return self.__fslabel
195 def __set_fslabel(self, val):
196 if val is None:
197 self.__fslabel = None
198 else:
199 self.__fslabel = val[:FSLABEL_MAXLEN]
200 #A string used to label any filesystems created.
201 #
202 #Some filesystems impose a constraint on the maximum allowed size of the
203 #filesystem label. In the case of ext3 it's 16 characters, but in the case
204 #of ISO9660 it's 32 characters.
205 #
206 #mke2fs silently truncates the label, but mkisofs aborts if the label is
207 #too long. So, for convenience sake, any string assigned to this attribute
208 #is silently truncated to FSLABEL_MAXLEN (32) characters.
209 fslabel = property(__get_fslabel, __set_fslabel)
210
211 def __get_image(self):
212 if self.__imgdir is None:
213 raise CreatorError("_image is not valid before calling mount()")
214 return os.path.join(self.__imgdir, self._img_name)
215 #The location of the image file.
216 #
217 #This is the path to the filesystem image. Subclasses may use this path
218 #in order to package the image in _stage_final_image().
219 #
220 #Note, this directory does not exist before ImageCreator.mount() is called.
221 #
222 #Note also, this is a read-only attribute.
223 _image = property(__get_image)
224
225 def __get_blocksize(self):
226 return self.__blocksize
227 def __set_blocksize(self, val):
228 if self._instloops:
229 raise CreatorError("_blocksize must be set before calling mount()")
230 try:
231 self.__blocksize = int(val)
232 except ValueError:
233 raise CreatorError("'%s' is not a valid integer value "
234 "for _blocksize" % val)
235 #The block size used by the image's filesystem.
236 #
237 #This is the block size used when creating the filesystem image. Subclasses
238 #may change this if they wish to use something other than a 4k block size.
239 #
240 #Note, this attribute may only be set before calling mount().
241 _blocksize = property(__get_blocksize, __set_blocksize)
242
243 def __get_fstype(self):
244 return self.__fstype
245 def __set_fstype(self, val):
246 if val != "ext2" and val != "ext3":
247 raise CreatorError("Unknown _fstype '%s' supplied" % val)
248 self.__fstype = val
249 #The type of filesystem used for the image.
250 #
251 #This is the filesystem type used when creating the filesystem image.
252 #Subclasses may change this if they wish to use something other ext3.
253 #
254 #Note, only ext2 and ext3 are currently supported.
255 #
256 #Note also, this attribute may only be set before calling mount().
257 _fstype = property(__get_fstype, __set_fstype)
258
259 def __get_fsopts(self):
260 return self.__fsopts
261 def __set_fsopts(self, val):
262 self.__fsopts = val
263 #Mount options of filesystem used for the image.
264 #
265 #This can be specified by --fsoptions="xxx,yyy" in part command in
266 #kickstart file.
267 _fsopts = property(__get_fsopts, __set_fsopts)
268
269
270 #
271 # Helpers for subclasses
272 #
273 def _resparse(self, size=None):
274 """Rebuild the filesystem image to be as sparse as possible.
275
276 This method should be used by subclasses when staging the final image
277 in order to reduce the actual space taken up by the sparse image file
278 to be as little as possible.
279
280 This is done by resizing the filesystem to the minimal size (thereby
281 eliminating any space taken up by deleted files) and then resizing it
282 back to the supplied size.
283
284 size -- the size in, in bytes, which the filesystem image should be
285 resized to after it has been minimized; this defaults to None,
286 causing the original size specified by the kickstart file to
287 be used (or 4GiB if not specified in the kickstart).
288 """
289 minsize = 0
290 for item in self._instloops:
291 if item['name'] == self._img_name:
292 minsize = item['loop'].resparse(size)
293 else:
294 item['loop'].resparse(size)
295
296 return minsize
297
298 def _base_on(self, base_on=None):
299 if base_on and self._image != base_on:
300 shutil.copyfile(base_on, self._image)
301
302 def _check_imgdir(self):
303 if self.__imgdir is None:
304 self.__imgdir = self._mkdtemp()
305
306
307 #
308 # Actual implementation
309 #
310 def _mount_instroot(self, base_on=None):
311
312 if base_on and os.path.isfile(base_on):
313 self.__imgdir = os.path.dirname(base_on)
314 imgname = os.path.basename(base_on)
315 self._base_on(base_on)
316 self._set_image_size(misc.get_file_size(self._image))
317
318 # here, self._instloops must be []
319 self._instloops.append({
320 "mountpoint": "/",
321 "label": self.name,
322 "name": imgname,
323 "size": self.__image_size or 4096L,
324 "fstype": self.__fstype or "ext3",
325 "extopts": None,
326 "loop": None
327 })
328
329 self._check_imgdir()
330
331 for loop in self._instloops:
332 fstype = loop['fstype']
333 mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/'))
334 size = loop['size'] * 1024L * 1024L
335 imgname = loop['name']
336
337 if fstype in ("ext2", "ext3", "ext4"):
338 MyDiskMount = fs.ExtDiskMount
339 elif fstype == "btrfs":
340 MyDiskMount = fs.BtrfsDiskMount
341 elif fstype in ("vfat", "msdos"):
342 MyDiskMount = fs.VfatDiskMount
343 else:
344 msger.error('Cannot support fstype: %s' % fstype)
345
346 loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk(
347 os.path.join(self.__imgdir, imgname),
348 size),
349 mp,
350 fstype,
351 self._blocksize,
352 loop['label'])
353
354 if fstype in ("ext2", "ext3", "ext4"):
355 loop['loop'].extopts = loop['extopts']
356
357 try:
358 msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp))
359 fs.makedirs(mp)
360 loop['loop'].mount()
361 except MountError, e:
362 raise
363
364 def _unmount_instroot(self):
365 for item in reversed(self._instloops):
366 try:
367 item['loop'].cleanup()
368 except:
369 pass
370
371 def _stage_final_image(self):
372
373 if self.pack_to or self.shrink_image:
374 self._resparse(0)
375 else:
376 self._resparse()
377
378 for item in self._instloops:
379 imgfile = os.path.join(self.__imgdir, item['name'])
380 if item['fstype'] == "ext4":
381 runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s '
382 % imgfile)
383 if self.compress_image:
384 misc.compressing(imgfile, self.compress_image)
385
386 if not self.pack_to:
387 for item in os.listdir(self.__imgdir):
388 shutil.move(os.path.join(self.__imgdir, item),
389 os.path.join(self._outdir, item))
390 else:
391 msger.info("Pack all loop images together to %s" % self.pack_to)
392 dstfile = os.path.join(self._outdir, self.pack_to)
393 misc.packing(dstfile, self.__imgdir)
394
395 if self.pack_to:
396 mountfp_xml = os.path.splitext(self.pack_to)[0]
397 mountfp_xml = misc.strip_end(mountfp_xml, '.tar') + ".xml"
398 else:
399 mountfp_xml = self.name + ".xml"
400 # save mount points mapping file to xml
401 save_mountpoints(os.path.join(self._outdir, mountfp_xml),
402 self._instloops,
403 self.target_arch)
404
405 def copy_attachment(self):
406 if not hasattr(self, '_attachment') or not self._attachment:
407 return
408
409 self._check_imgdir()
410
411 msger.info("Copying attachment files...")
412 for item in self._attachment:
413 if not os.path.exists(item):
414 continue
415 dpath = os.path.join(self.__imgdir, os.path.basename(item))
416 msger.verbose("Copy attachment %s to %s" % (item, dpath))
417 shutil.copy(item, dpath)
418
diff --git a/scripts/lib/mic/imager/raw.py b/scripts/lib/mic/imager/raw.py
deleted file mode 100644
index 838191a6f1..0000000000
--- a/scripts/lib/mic/imager/raw.py
+++ /dev/null
@@ -1,501 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import stat
20import shutil
21
22from mic import kickstart, msger
23from mic.utils import fs_related, runner, misc
24from mic.utils.partitionedfs import PartitionedMount
25from mic.utils.errors import CreatorError, MountError
26from mic.imager.baseimager import BaseImageCreator
27
28
29class RawImageCreator(BaseImageCreator):
30 """Installs a system into a file containing a partitioned disk image.
31
32 ApplianceImageCreator is an advanced ImageCreator subclass; a sparse file
33 is formatted with a partition table, each partition loopback mounted
34 and the system installed into an virtual disk. The disk image can
35 subsequently be booted in a virtual machine or accessed with kpartx
36 """
37
38 def __init__(self, creatoropts=None, pkgmgr=None, compress_image=None, generate_bmap=None, fstab_entry="uuid"):
39 """Initialize a ApplianceImageCreator instance.
40
41 This method takes the same arguments as ImageCreator.__init__()
42 """
43 BaseImageCreator.__init__(self, creatoropts, pkgmgr)
44
45 self.__instloop = None
46 self.__imgdir = None
47 self.__disks = {}
48 self.__disk_format = "raw"
49 self._disk_names = []
50 self._ptable_format = self.ks.handler.bootloader.ptable
51 self.vmem = 512
52 self.vcpu = 1
53 self.checksum = False
54 self.use_uuid = fstab_entry == "uuid"
55 self.appliance_version = None
56 self.appliance_release = None
57 self.compress_image = compress_image
58 self.bmap_needed = generate_bmap
59 self._need_extlinux = not kickstart.use_installerfw(self.ks, "extlinux")
60 #self.getsource = False
61 #self.listpkg = False
62
63 self._dep_checks.extend(["sync", "kpartx", "parted"])
64 if self._need_extlinux:
65 self._dep_checks.extend(["extlinux"])
66
67 def configure(self, repodata = None):
68 import subprocess
69 def chroot():
70 os.chroot(self._instroot)
71 os.chdir("/")
72
73 if os.path.exists(self._instroot + "/usr/bin/Xorg"):
74 subprocess.call(["/bin/chmod", "u+s", "/usr/bin/Xorg"],
75 preexec_fn = chroot)
76
77 BaseImageCreator.configure(self, repodata)
78
79 def _get_fstab(self):
80 if kickstart.use_installerfw(self.ks, "fstab"):
81 # The fstab file will be generated by installer framework scripts
82 # instead.
83 return None
84
85 s = ""
86 for mp in self.__instloop.mountOrder:
87 p = None
88 for p1 in self.__instloop.partitions:
89 if p1['mountpoint'] == mp:
90 p = p1
91 break
92
93 if self.use_uuid and p['uuid']:
94 device = "UUID=%s" % p['uuid']
95 else:
96 device = "/dev/%s%-d" % (p['disk_name'], p['num'])
97
98 s += "%(device)s %(mountpoint)s %(fstype)s %(fsopts)s 0 0\n" % {
99 'device': device,
100 'mountpoint': p['mountpoint'],
101 'fstype': p['fstype'],
102 'fsopts': "defaults,noatime" if not p['fsopts'] else p['fsopts']}
103
104 if p['mountpoint'] == "/":
105 for subvol in self.__instloop.subvolumes:
106 if subvol['mountpoint'] == "/":
107 continue
108 s += "%(device)s %(mountpoint)s %(fstype)s %(fsopts)s 0 0\n" % {
109 'device': "/dev/%s%-d" % (p['disk_name'], p['num']),
110 'mountpoint': subvol['mountpoint'],
111 'fstype': p['fstype'],
112 'fsopts': "defaults,noatime" if not subvol['fsopts'] else subvol['fsopts']}
113
114 s += "devpts /dev/pts devpts gid=5,mode=620 0 0\n"
115 s += "tmpfs /dev/shm tmpfs defaults 0 0\n"
116 s += "proc /proc proc defaults 0 0\n"
117 s += "sysfs /sys sysfs defaults 0 0\n"
118 return s
119
120 def _create_mkinitrd_config(self):
121 """write to tell which modules to be included in initrd"""
122
123 mkinitrd = ""
124 mkinitrd += "PROBE=\"no\"\n"
125 mkinitrd += "MODULES+=\"ext3 ata_piix sd_mod libata scsi_mod\"\n"
126 mkinitrd += "rootfs=\"ext3\"\n"
127 mkinitrd += "rootopts=\"defaults\"\n"
128
129 msger.debug("Writing mkinitrd config %s/etc/sysconfig/mkinitrd" \
130 % self._instroot)
131 os.makedirs(self._instroot + "/etc/sysconfig/",mode=644)
132 cfg = open(self._instroot + "/etc/sysconfig/mkinitrd", "w")
133 cfg.write(mkinitrd)
134 cfg.close()
135
136 def _get_parts(self):
137 if not self.ks:
138 raise CreatorError("Failed to get partition info, "
139 "please check your kickstart setting.")
140
141 # Set a default partition if no partition is given out
142 if not self.ks.handler.partition.partitions:
143 partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
144 args = partstr.split()
145 pd = self.ks.handler.partition.parse(args[1:])
146 if pd not in self.ks.handler.partition.partitions:
147 self.ks.handler.partition.partitions.append(pd)
148
149 # partitions list from kickstart file
150 return kickstart.get_partitions(self.ks)
151
152 def get_disk_names(self):
153 """ Returns a list of physical target disk names (e.g., 'sdb') which
154 will be created. """
155
156 if self._disk_names:
157 return self._disk_names
158
159 #get partition info from ks handler
160 parts = self._get_parts()
161
162 for i in range(len(parts)):
163 if parts[i].disk:
164 disk_name = parts[i].disk
165 else:
166 raise CreatorError("Failed to create disks, no --ondisk "
167 "specified in partition line of ks file")
168
169 if parts[i].mountpoint and not parts[i].fstype:
170 raise CreatorError("Failed to create disks, no --fstype "
171 "specified for partition with mountpoint "
172 "'%s' in the ks file")
173
174 self._disk_names.append(disk_name)
175
176 return self._disk_names
177
178 def _full_name(self, name, extention):
179 """ Construct full file name for a file we generate. """
180 return "%s-%s.%s" % (self.name, name, extention)
181
182 def _full_path(self, path, name, extention):
183 """ Construct full file path to a file we generate. """
184 return os.path.join(path, self._full_name(name, extention))
185
186 #
187 # Actual implemention
188 #
189 def _mount_instroot(self, base_on = None):
190 parts = self._get_parts()
191 self.__instloop = PartitionedMount(self._instroot)
192
193 for p in parts:
194 self.__instloop.add_partition(int(p.size),
195 p.disk,
196 p.mountpoint,
197 p.fstype,
198 p.label,
199 fsopts = p.fsopts,
200 boot = p.active,
201 align = p.align,
202 part_type = p.part_type)
203
204 self.__instloop.layout_partitions(self._ptable_format)
205
206 # Create the disks
207 self.__imgdir = self._mkdtemp()
208 for disk_name, disk in self.__instloop.disks.items():
209 full_path = self._full_path(self.__imgdir, disk_name, "raw")
210 msger.debug("Adding disk %s as %s with size %s bytes" \
211 % (disk_name, full_path, disk['min_size']))
212
213 disk_obj = fs_related.SparseLoopbackDisk(full_path,
214 disk['min_size'])
215 self.__disks[disk_name] = disk_obj
216 self.__instloop.add_disk(disk_name, disk_obj)
217
218 self.__instloop.mount()
219 self._create_mkinitrd_config()
220
221 def _get_required_packages(self):
222 required_packages = BaseImageCreator._get_required_packages(self)
223 if self._need_extlinux:
224 if not self.target_arch or not self.target_arch.startswith("arm"):
225 required_packages += ["syslinux", "syslinux-extlinux"]
226 return required_packages
227
228 def _get_excluded_packages(self):
229 return BaseImageCreator._get_excluded_packages(self)
230
231 def _get_syslinux_boot_config(self):
232 rootdev = None
233 root_part_uuid = None
234 for p in self.__instloop.partitions:
235 if p['mountpoint'] == "/":
236 rootdev = "/dev/%s%-d" % (p['disk_name'], p['num'])
237 root_part_uuid = p['partuuid']
238
239 return (rootdev, root_part_uuid)
240
241 def _create_syslinux_config(self):
242
243 splash = os.path.join(self._instroot, "boot/extlinux")
244 if os.path.exists(splash):
245 splashline = "menu background splash.jpg"
246 else:
247 splashline = ""
248
249 (rootdev, root_part_uuid) = self._get_syslinux_boot_config()
250 options = self.ks.handler.bootloader.appendLine
251
252 #XXX don't hardcode default kernel - see livecd code
253 syslinux_conf = ""
254 syslinux_conf += "prompt 0\n"
255 syslinux_conf += "timeout 1\n"
256 syslinux_conf += "\n"
257 syslinux_conf += "default vesamenu.c32\n"
258 syslinux_conf += "menu autoboot Starting %s...\n" % self.distro_name
259 syslinux_conf += "menu hidden\n"
260 syslinux_conf += "\n"
261 syslinux_conf += "%s\n" % splashline
262 syslinux_conf += "menu title Welcome to %s!\n" % self.distro_name
263 syslinux_conf += "menu color border 0 #ffffffff #00000000\n"
264 syslinux_conf += "menu color sel 7 #ffffffff #ff000000\n"
265 syslinux_conf += "menu color title 0 #ffffffff #00000000\n"
266 syslinux_conf += "menu color tabmsg 0 #ffffffff #00000000\n"
267 syslinux_conf += "menu color unsel 0 #ffffffff #00000000\n"
268 syslinux_conf += "menu color hotsel 0 #ff000000 #ffffffff\n"
269 syslinux_conf += "menu color hotkey 7 #ffffffff #ff000000\n"
270 syslinux_conf += "menu color timeout_msg 0 #ffffffff #00000000\n"
271 syslinux_conf += "menu color timeout 0 #ffffffff #00000000\n"
272 syslinux_conf += "menu color cmdline 0 #ffffffff #00000000\n"
273
274 versions = []
275 kernels = self._get_kernel_versions()
276 symkern = "%s/boot/vmlinuz" % self._instroot
277
278 if os.path.lexists(symkern):
279 v = os.path.realpath(symkern).replace('%s-' % symkern, "")
280 syslinux_conf += "label %s\n" % self.distro_name.lower()
281 syslinux_conf += "\tmenu label %s (%s)\n" % (self.distro_name, v)
282 syslinux_conf += "\tlinux ../vmlinuz\n"
283 if self._ptable_format == 'msdos':
284 rootstr = rootdev
285 else:
286 if not root_part_uuid:
287 raise MountError("Cannot find the root GPT partition UUID")
288 rootstr = "PARTUUID=%s" % root_part_uuid
289 syslinux_conf += "\tappend ro root=%s %s\n" % (rootstr, options)
290 syslinux_conf += "\tmenu default\n"
291 else:
292 for kernel in kernels:
293 for version in kernels[kernel]:
294 versions.append(version)
295
296 footlabel = 0
297 for v in versions:
298 syslinux_conf += "label %s%d\n" \
299 % (self.distro_name.lower(), footlabel)
300 syslinux_conf += "\tmenu label %s (%s)\n" % (self.distro_name, v)
301 syslinux_conf += "\tlinux ../vmlinuz-%s\n" % v
302 syslinux_conf += "\tappend ro root=%s %s\n" \
303 % (rootdev, options)
304 if footlabel == 0:
305 syslinux_conf += "\tmenu default\n"
306 footlabel += 1;
307
308 msger.debug("Writing syslinux config %s/boot/extlinux/extlinux.conf" \
309 % self._instroot)
310 cfg = open(self._instroot + "/boot/extlinux/extlinux.conf", "w")
311 cfg.write(syslinux_conf)
312 cfg.close()
313
314 def _install_syslinux(self):
315 for name in self.__disks.keys():
316 loopdev = self.__disks[name].device
317
318 # Set MBR
319 mbrfile = "%s/usr/share/syslinux/" % self._instroot
320 if self._ptable_format == 'gpt':
321 mbrfile += "gptmbr.bin"
322 else:
323 mbrfile += "mbr.bin"
324
325 msger.debug("Installing syslinux bootloader '%s' to %s" % \
326 (mbrfile, loopdev))
327
328 mbrsize = os.stat(mbrfile)[stat.ST_SIZE]
329 rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev])
330 if rc != 0:
331 raise MountError("Unable to set MBR to %s" % loopdev)
332
333
334 # Ensure all data is flushed to disk before doing syslinux install
335 runner.quiet('sync')
336
337 fullpathsyslinux = fs_related.find_binary_path("extlinux")
338 rc = runner.show([fullpathsyslinux,
339 "-i",
340 "%s/boot/extlinux" % self._instroot])
341 if rc != 0:
342 raise MountError("Unable to install syslinux bootloader to %s" \
343 % loopdev)
344
345 def _create_bootconfig(self):
346 #If syslinux is available do the required configurations.
347 if self._need_extlinux \
348 and os.path.exists("%s/usr/share/syslinux/" % (self._instroot)) \
349 and os.path.exists("%s/boot/extlinux/" % (self._instroot)):
350 self._create_syslinux_config()
351 self._install_syslinux()
352
353 def _unmount_instroot(self):
354 if not self.__instloop is None:
355 try:
356 self.__instloop.cleanup()
357 except MountError, err:
358 msger.warning("%s" % err)
359
360 def _resparse(self, size = None):
361 return self.__instloop.resparse(size)
362
363 def _get_post_scripts_env(self, in_chroot):
364 env = BaseImageCreator._get_post_scripts_env(self, in_chroot)
365
366 # Export the file-system UUIDs and partition UUIDs (AKA PARTUUIDs)
367 for p in self.__instloop.partitions:
368 env.update(self._set_part_env(p['ks_pnum'], "UUID", p['uuid']))
369 env.update(self._set_part_env(p['ks_pnum'], "PARTUUID", p['partuuid']))
370
371 return env
372
373 def _stage_final_image(self):
374 """Stage the final system image in _outdir.
375 write meta data
376 """
377 self._resparse()
378
379 if self.compress_image:
380 for imgfile in os.listdir(self.__imgdir):
381 if imgfile.endswith('.raw') or imgfile.endswith('bin'):
382 imgpath = os.path.join(self.__imgdir, imgfile)
383 misc.compressing(imgpath, self.compress_image)
384
385 if self.pack_to:
386 dst = os.path.join(self._outdir, self.pack_to)
387 msger.info("Pack all raw images to %s" % dst)
388 misc.packing(dst, self.__imgdir)
389 else:
390 msger.debug("moving disks to stage location")
391 for imgfile in os.listdir(self.__imgdir):
392 src = os.path.join(self.__imgdir, imgfile)
393 dst = os.path.join(self._outdir, imgfile)
394 msger.debug("moving %s to %s" % (src,dst))
395 shutil.move(src,dst)
396 self._write_image_xml()
397
398 def _write_image_xml(self):
399 imgarch = "i686"
400 if self.target_arch and self.target_arch.startswith("arm"):
401 imgarch = "arm"
402 xml = "<image>\n"
403
404 name_attributes = ""
405 if self.appliance_version:
406 name_attributes += " version='%s'" % self.appliance_version
407 if self.appliance_release:
408 name_attributes += " release='%s'" % self.appliance_release
409 xml += " <name%s>%s</name>\n" % (name_attributes, self.name)
410 xml += " <domain>\n"
411 # XXX don't hardcode - determine based on the kernel we installed for
412 # grub baremetal vs xen
413 xml += " <boot type='hvm'>\n"
414 xml += " <guest>\n"
415 xml += " <arch>%s</arch>\n" % imgarch
416 xml += " </guest>\n"
417 xml += " <os>\n"
418 xml += " <loader dev='hd'/>\n"
419 xml += " </os>\n"
420
421 i = 0
422 for name in self.__disks.keys():
423 full_name = self._full_name(name, self.__disk_format)
424 xml += " <drive disk='%s' target='hd%s'/>\n" \
425 % (full_name, chr(ord('a') + i))
426 i = i + 1
427
428 xml += " </boot>\n"
429 xml += " <devices>\n"
430 xml += " <vcpu>%s</vcpu>\n" % self.vcpu
431 xml += " <memory>%d</memory>\n" %(self.vmem * 1024)
432 for network in self.ks.handler.network.network:
433 xml += " <interface/>\n"
434 xml += " <graphics/>\n"
435 xml += " </devices>\n"
436 xml += " </domain>\n"
437 xml += " <storage>\n"
438
439 if self.checksum is True:
440 for name in self.__disks.keys():
441 diskpath = self._full_path(self._outdir, name, \
442 self.__disk_format)
443 full_name = self._full_name(name, self.__disk_format)
444
445 msger.debug("Generating disk signature for %s" % full_name)
446
447 xml += " <disk file='%s' use='system' format='%s'>\n" \
448 % (full_name, self.__disk_format)
449
450 hashes = misc.calc_hashes(diskpath, ('sha1', 'sha256'))
451
452 xml += " <checksum type='sha1'>%s</checksum>\n" \
453 % hashes[0]
454 xml += " <checksum type='sha256'>%s</checksum>\n" \
455 % hashes[1]
456 xml += " </disk>\n"
457 else:
458 for name in self.__disks.keys():
459 full_name = self._full_name(name, self.__disk_format)
460 xml += " <disk file='%s' use='system' format='%s'/>\n" \
461 % (full_name, self.__disk_format)
462
463 xml += " </storage>\n"
464 xml += "</image>\n"
465
466 msger.debug("writing image XML to %s/%s.xml" %(self._outdir, self.name))
467 cfg = open("%s/%s.xml" % (self._outdir, self.name), "w")
468 cfg.write(xml)
469 cfg.close()
470
471 def generate_bmap(self):
472 """ Generate block map file for the image. The idea is that while disk
473 images we generate may be large (e.g., 4GiB), they may actually contain
474 only little real data, e.g., 512MiB. This data are files, directories,
475 file-system meta-data, partition table, etc. In other words, when
476 flashing the image to the target device, you do not have to copy all the
477 4GiB of data, you can copy only 512MiB of it, which is 4 times faster.
478
479 This function generates the block map file for an arbitrary image that
480 mic has generated. The block map file is basically an XML file which
481 contains a list of blocks which have to be copied to the target device.
482 The other blocks are not used and there is no need to copy them. """
483
484 if self.bmap_needed is None:
485 return
486
487 from mic.utils import BmapCreate
488 msger.info("Generating the map file(s)")
489
490 for name in self.__disks.keys():
491 image = self._full_path(self.__imgdir, name, self.__disk_format)
492 bmap_file = self._full_path(self._outdir, name, "bmap")
493
494 msger.debug("Generating block map file '%s'" % bmap_file)
495
496 try:
497 creator = BmapCreate.BmapCreate(image, bmap_file)
498 creator.generate()
499 del creator
500 except BmapCreate.Error as err:
501 raise CreatorError("Failed to create bmap file: %s" % str(err))
diff --git a/scripts/lib/mic/plugins/imager/direct_plugin.py b/scripts/lib/mic/plugins/imager/direct_plugin.py
index fc7c10c3df..d3a0ba75d3 100644
--- a/scripts/lib/mic/plugins/imager/direct_plugin.py
+++ b/scripts/lib/mic/plugins/imager/direct_plugin.py
@@ -30,7 +30,7 @@ import shutil
30import re 30import re
31import tempfile 31import tempfile
32 32
33from mic import chroot, msger 33from mic import msger
34from mic.utils import misc, fs_related, errors, runner, cmdln 34from mic.utils import misc, fs_related, errors, runner, cmdln
35from mic.conf import configmgr 35from mic.conf import configmgr
36from mic.plugin import pluginmgr 36from mic.plugin import pluginmgr
diff --git a/scripts/lib/mic/plugins/imager/fs_plugin.py b/scripts/lib/mic/plugins/imager/fs_plugin.py
deleted file mode 100644
index 6bcaf00729..0000000000
--- a/scripts/lib/mic/plugins/imager/fs_plugin.py
+++ /dev/null
@@ -1,143 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import sys
20
21from mic import chroot, msger
22from mic.utils import cmdln, misc, errors, fs_related
23from mic.imager import fs
24from mic.conf import configmgr
25from mic.plugin import pluginmgr
26
27from mic.pluginbase import ImagerPlugin
28class FsPlugin(ImagerPlugin):
29 name = 'fs'
30
31 @classmethod
32 @cmdln.option("--include-src",
33 dest="include_src",
34 action="store_true",
35 default=False,
36 help="Generate a image with source rpms included")
37 def do_create(self, subcmd, opts, *args):
38 """${cmd_name}: create fs image
39
40 Usage:
41 ${name} ${cmd_name} <ksfile> [OPTS]
42
43 ${cmd_option_list}
44 """
45
46 if len(args) != 1:
47 raise errors.Usage("Extra arguments given")
48
49 creatoropts = configmgr.create
50 ksconf = args[0]
51
52 if creatoropts['runtime'] == 'bootstrap':
53 configmgr._ksconf = ksconf
54 rt_util.bootstrap_mic()
55
56 recording_pkgs = []
57 if len(creatoropts['record_pkgs']) > 0:
58 recording_pkgs = creatoropts['record_pkgs']
59
60 if creatoropts['release'] is not None:
61 if 'name' not in recording_pkgs:
62 recording_pkgs.append('name')
63 if 'vcs' not in recording_pkgs:
64 recording_pkgs.append('vcs')
65
66 configmgr._ksconf = ksconf
67
68 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
69 if creatoropts['release'] is not None:
70 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
71
72 # try to find the pkgmgr
73 pkgmgr = None
74 backends = pluginmgr.get_plugins('backend')
75 if 'auto' == creatoropts['pkgmgr']:
76 for key in configmgr.prefer_backends:
77 if key in backends:
78 pkgmgr = backends[key]
79 break
80 else:
81 for key in backends.keys():
82 if key == creatoropts['pkgmgr']:
83 pkgmgr = backends[key]
84 break
85
86 if not pkgmgr:
87 raise errors.CreatorError("Can't find backend: %s, "
88 "available choices: %s" %
89 (creatoropts['pkgmgr'],
90 ','.join(backends.keys())))
91
92 creator = fs.FsImageCreator(creatoropts, pkgmgr)
93 creator._include_src = opts.include_src
94
95 if len(recording_pkgs) > 0:
96 creator._recording_pkgs = recording_pkgs
97
98 self.check_image_exists(creator.destdir,
99 creator.pack_to,
100 [creator.name],
101 creatoropts['release'])
102
103 try:
104 creator.check_depend_tools()
105 creator.mount(None, creatoropts["cachedir"])
106 creator.install()
107 #Download the source packages ###private options
108 if opts.include_src:
109 installed_pkgs = creator.get_installed_packages()
110 msger.info('--------------------------------------------------')
111 msger.info('Generating the image with source rpms included ...')
112 if not misc.SrcpkgsDownload(installed_pkgs, creatoropts["repomd"], creator._instroot, creatoropts["cachedir"]):
113 msger.warning("Source packages can't be downloaded")
114
115 creator.configure(creatoropts["repomd"])
116 creator.copy_kernel()
117 creator.unmount()
118 creator.package(creatoropts["outdir"])
119 if creatoropts['release'] is not None:
120 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
121 creator.print_outimage_info()
122 except errors.CreatorError:
123 raise
124 finally:
125 creator.cleanup()
126
127 msger.info("Finished.")
128 return 0
129
130 @classmethod
131 def do_chroot(self, target, cmd=[]):#chroot.py parse opts&args
132 try:
133 if len(cmd) != 0:
134 cmdline = ' '.join(cmd)
135 else:
136 cmdline = "/bin/bash"
137 envcmd = fs_related.find_binary_inchroot("env", target)
138 if envcmd:
139 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
140 chroot.chroot(target, None, cmdline)
141 finally:
142 chroot.cleanup_after_chroot("dir", None, None, None)
143 return 1
diff --git a/scripts/lib/mic/plugins/imager/livecd_plugin.py b/scripts/lib/mic/plugins/imager/livecd_plugin.py
deleted file mode 100644
index 82cb1af7dc..0000000000
--- a/scripts/lib/mic/plugins/imager/livecd_plugin.py
+++ /dev/null
@@ -1,255 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import tempfile
21
22from mic import chroot, msger
23from mic.utils import misc, fs_related, errors
24from mic.conf import configmgr
25import mic.imager.livecd as livecd
26from mic.plugin import pluginmgr
27
28from mic.pluginbase import ImagerPlugin
29class LiveCDPlugin(ImagerPlugin):
30 name = 'livecd'
31
32 @classmethod
33 def do_create(self, subcmd, opts, *args):
34 """${cmd_name}: create livecd image
35
36 Usage:
37 ${name} ${cmd_name} <ksfile> [OPTS]
38
39 ${cmd_option_list}
40 """
41
42 if len(args) != 1:
43 raise errors.Usage("Extra arguments given")
44
45 creatoropts = configmgr.create
46 ksconf = args[0]
47
48 if creatoropts['runtime'] == 'bootstrap':
49 configmgr._ksconf = ksconf
50 rt_util.bootstrap_mic()
51
52 if creatoropts['arch'] and creatoropts['arch'].startswith('arm'):
53 msger.warning('livecd cannot support arm images, Quit')
54 return
55
56 recording_pkgs = []
57 if len(creatoropts['record_pkgs']) > 0:
58 recording_pkgs = creatoropts['record_pkgs']
59
60 if creatoropts['release'] is not None:
61 if 'name' not in recording_pkgs:
62 recording_pkgs.append('name')
63 if 'vcs' not in recording_pkgs:
64 recording_pkgs.append('vcs')
65
66 configmgr._ksconf = ksconf
67
68 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
69 if creatoropts['release'] is not None:
70 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
71
72 # try to find the pkgmgr
73 pkgmgr = None
74 backends = pluginmgr.get_plugins('backend')
75 if 'auto' == creatoropts['pkgmgr']:
76 for key in configmgr.prefer_backends:
77 if key in backends:
78 pkgmgr = backends[key]
79 break
80 else:
81 for key in backends.keys():
82 if key == creatoropts['pkgmgr']:
83 pkgmgr = backends[key]
84 break
85
86 if not pkgmgr:
87 raise errors.CreatorError("Can't find backend: %s, "
88 "available choices: %s" %
89 (creatoropts['pkgmgr'],
90 ','.join(backends.keys())))
91
92 creator = livecd.LiveCDImageCreator(creatoropts, pkgmgr)
93
94 if len(recording_pkgs) > 0:
95 creator._recording_pkgs = recording_pkgs
96
97 self.check_image_exists(creator.destdir,
98 creator.pack_to,
99 [creator.name + ".iso"],
100 creatoropts['release'])
101
102 try:
103 creator.check_depend_tools()
104 creator.mount(None, creatoropts["cachedir"])
105 creator.install()
106 creator.configure(creatoropts["repomd"])
107 creator.copy_kernel()
108 creator.unmount()
109 creator.package(creatoropts["outdir"])
110 if creatoropts['release'] is not None:
111 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
112 creator.print_outimage_info()
113
114 except errors.CreatorError:
115 raise
116 finally:
117 creator.cleanup()
118
119 msger.info("Finished.")
120 return 0
121
122 @classmethod
123 def do_chroot(cls, target, cmd=[]):
124 os_image = cls.do_unpack(target)
125 os_image_dir = os.path.dirname(os_image)
126
127 # unpack image to target dir
128 imgsize = misc.get_file_size(os_image) * 1024L * 1024L
129 imgtype = misc.get_image_type(os_image)
130 if imgtype == "btrfsimg":
131 fstype = "btrfs"
132 myDiskMount = fs_related.BtrfsDiskMount
133 elif imgtype in ("ext3fsimg", "ext4fsimg"):
134 fstype = imgtype[:4]
135 myDiskMount = fs_related.ExtDiskMount
136 else:
137 raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
138
139 extmnt = misc.mkdtemp()
140 extloop = myDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
141 extmnt,
142 fstype,
143 4096,
144 "%s label" % fstype)
145 try:
146 extloop.mount()
147
148 except errors.MountError:
149 extloop.cleanup()
150 shutil.rmtree(extmnt, ignore_errors = True)
151 shutil.rmtree(os_image_dir, ignore_errors = True)
152 raise
153
154 try:
155 if len(cmd) != 0:
156 cmdline = ' '.join(cmd)
157 else:
158 cmdline = "/bin/bash"
159 envcmd = fs_related.find_binary_inchroot("env", extmnt)
160 if envcmd:
161 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
162 chroot.chroot(extmnt, None, cmdline)
163 except:
164 raise errors.CreatorError("Failed to chroot to %s." %target)
165 finally:
166 chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
167
168 @classmethod
169 def do_pack(cls, base_on):
170 import subprocess
171
172 def __mkinitrd(instance):
173 kernelver = instance._get_kernel_versions().values()[0][0]
174 args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
175 try:
176 subprocess.call(args, preexec_fn = instance._chroot)
177 except OSError, (err, msg):
178 raise errors.CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
179
180 def __run_post_cleanups(instance):
181 kernelver = instance._get_kernel_versions().values()[0][0]
182 args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
183
184 try:
185 subprocess.call(args, preexec_fn = instance._chroot)
186 except OSError, (err, msg):
187 raise errors.CreatorError("Failed to run post cleanups: %s" % msg)
188
189 convertoropts = configmgr.convert
190 convertoropts['name'] = os.path.splitext(os.path.basename(base_on))[0]
191 convertor = livecd.LiveCDImageCreator(convertoropts)
192 imgtype = misc.get_image_type(base_on)
193 if imgtype == "btrfsimg":
194 fstype = "btrfs"
195 elif imgtype in ("ext3fsimg", "ext4fsimg"):
196 fstype = imgtype[:4]
197 else:
198 raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
199 convertor._set_fstype(fstype)
200 try:
201 convertor.mount(base_on)
202 __mkinitrd(convertor)
203 convertor._create_bootconfig()
204 __run_post_cleanups(convertor)
205 convertor.launch_shell(convertoropts['shell'])
206 convertor.unmount()
207 convertor.package()
208 convertor.print_outimage_info()
209 finally:
210 shutil.rmtree(os.path.dirname(base_on), ignore_errors = True)
211
212 @classmethod
213 def do_unpack(cls, srcimg):
214 img = srcimg
215 imgmnt = misc.mkdtemp()
216 imgloop = fs_related.DiskMount(fs_related.LoopbackDisk(img, 0), imgmnt)
217 try:
218 imgloop.mount()
219 except errors.MountError:
220 imgloop.cleanup()
221 raise
222
223 # legacy LiveOS filesystem layout support, remove for F9 or F10
224 if os.path.exists(imgmnt + "/squashfs.img"):
225 squashimg = imgmnt + "/squashfs.img"
226 else:
227 squashimg = imgmnt + "/LiveOS/squashfs.img"
228
229 tmpoutdir = misc.mkdtemp()
230 # unsquashfs requires outdir mustn't exist
231 shutil.rmtree(tmpoutdir, ignore_errors = True)
232 misc.uncompress_squashfs(squashimg, tmpoutdir)
233
234 try:
235 # legacy LiveOS filesystem layout support, remove for F9 or F10
236 if os.path.exists(tmpoutdir + "/os.img"):
237 os_image = tmpoutdir + "/os.img"
238 else:
239 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
240
241 if not os.path.exists(os_image):
242 raise errors.CreatorError("'%s' is not a valid live CD ISO : neither "
243 "LiveOS/ext3fs.img nor os.img exist" %img)
244
245 imgname = os.path.basename(srcimg)
246 imgname = os.path.splitext(imgname)[0] + ".img"
247 rtimage = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), imgname)
248 shutil.copyfile(os_image, rtimage)
249
250 finally:
251 imgloop.cleanup()
252 shutil.rmtree(tmpoutdir, ignore_errors = True)
253 shutil.rmtree(imgmnt, ignore_errors = True)
254
255 return rtimage
diff --git a/scripts/lib/mic/plugins/imager/liveusb_plugin.py b/scripts/lib/mic/plugins/imager/liveusb_plugin.py
deleted file mode 100644
index 3d53c84410..0000000000
--- a/scripts/lib/mic/plugins/imager/liveusb_plugin.py
+++ /dev/null
@@ -1,260 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import tempfile
21
22from mic import chroot, msger
23from mic.utils import misc, fs_related, errors
24from mic.utils.partitionedfs import PartitionedMount
25from mic.conf import configmgr
26from mic.plugin import pluginmgr
27
28import mic.imager.liveusb as liveusb
29
30from mic.pluginbase import ImagerPlugin
31class LiveUSBPlugin(ImagerPlugin):
32 name = 'liveusb'
33
34 @classmethod
35 def do_create(self, subcmd, opts, *args):
36 """${cmd_name}: create liveusb image
37
38 Usage:
39 ${name} ${cmd_name} <ksfile> [OPTS]
40
41 ${cmd_option_list}
42 """
43
44 if len(args) != 1:
45 raise errors.Usage("Extra arguments given")
46
47 creatoropts = configmgr.create
48 ksconf = args[0]
49
50 if creatoropts['runtime'] == "bootstrap":
51 configmgr._ksconf = ksconf
52 rt_util.bootstrap_mic()
53
54 if creatoropts['arch'] and creatoropts['arch'].startswith('arm'):
55 msger.warning('liveusb cannot support arm images, Quit')
56 return
57
58 recording_pkgs = []
59 if len(creatoropts['record_pkgs']) > 0:
60 recording_pkgs = creatoropts['record_pkgs']
61
62 if creatoropts['release'] is not None:
63 if 'name' not in recording_pkgs:
64 recording_pkgs.append('name')
65 if 'vcs' not in recording_pkgs:
66 recording_pkgs.append('vcs')
67
68 configmgr._ksconf = ksconf
69
70 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
71 if creatoropts['release'] is not None:
72 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
73
74 # try to find the pkgmgr
75 pkgmgr = None
76 backends = pluginmgr.get_plugins('backend')
77 if 'auto' == creatoropts['pkgmgr']:
78 for key in configmgr.prefer_backends:
79 if key in backends:
80 pkgmgr = backends[key]
81 break
82 else:
83 for key in backends.keys():
84 if key == creatoropts['pkgmgr']:
85 pkgmgr = backends[key]
86 break
87
88 if not pkgmgr:
89 raise errors.CreatorError("Can't find backend: %s, "
90 "available choices: %s" %
91 (creatoropts['pkgmgr'],
92 ','.join(backends.keys())))
93
94 creator = liveusb.LiveUSBImageCreator(creatoropts, pkgmgr)
95
96 if len(recording_pkgs) > 0:
97 creator._recording_pkgs = recording_pkgs
98
99 self.check_image_exists(creator.destdir,
100 creator.pack_to,
101 [creator.name + ".usbimg"],
102 creatoropts['release'])
103 try:
104 creator.check_depend_tools()
105 creator.mount(None, creatoropts["cachedir"])
106 creator.install()
107 creator.configure(creatoropts["repomd"])
108 creator.copy_kernel()
109 creator.unmount()
110 creator.package(creatoropts["outdir"])
111 if creatoropts['release'] is not None:
112 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
113 creator.print_outimage_info()
114
115 except errors.CreatorError:
116 raise
117 finally:
118 creator.cleanup()
119
120 msger.info("Finished.")
121 return 0
122
123 @classmethod
124 def do_chroot(cls, target, cmd=[]):
125 os_image = cls.do_unpack(target)
126 os_image_dir = os.path.dirname(os_image)
127
128 # unpack image to target dir
129 imgsize = misc.get_file_size(os_image) * 1024L * 1024L
130 imgtype = misc.get_image_type(os_image)
131 if imgtype == "btrfsimg":
132 fstype = "btrfs"
133 myDiskMount = fs_related.BtrfsDiskMount
134 elif imgtype in ("ext3fsimg", "ext4fsimg"):
135 fstype = imgtype[:4]
136 myDiskMount = fs_related.ExtDiskMount
137 else:
138 raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
139
140 extmnt = misc.mkdtemp()
141 extloop = myDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
142 extmnt,
143 fstype,
144 4096,
145 "%s label" % fstype)
146
147 try:
148 extloop.mount()
149
150 except errors.MountError:
151 extloop.cleanup()
152 shutil.rmtree(extmnt, ignore_errors = True)
153 raise
154
155 try:
156 if len(cmd) != 0:
157 cmdline = ' '.join(cmd)
158 else:
159 cmdline = "/bin/bash"
160 envcmd = fs_related.find_binary_inchroot("env", extmnt)
161 if envcmd:
162 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
163 chroot.chroot(extmnt, None, cmdline)
164 except:
165 raise errors.CreatorError("Failed to chroot to %s." %target)
166 finally:
167 chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
168
169 @classmethod
170 def do_pack(cls, base_on):
171 import subprocess
172
173 def __mkinitrd(instance):
174 kernelver = instance._get_kernel_versions().values()[0][0]
175 args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
176 try:
177 subprocess.call(args, preexec_fn = instance._chroot)
178
179 except OSError, (err, msg):
180 raise errors.CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
181
182 def __run_post_cleanups(instance):
183 kernelver = instance._get_kernel_versions().values()[0][0]
184 args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
185
186 try:
187 subprocess.call(args, preexec_fn = instance._chroot)
188 except OSError, (err, msg):
189 raise errors.CreatorError("Failed to run post cleanups: %s" % msg)
190
191 convertoropts = configmgr.convert
192 convertoropts['name'] = os.path.splitext(os.path.basename(base_on))[0]
193 convertor = liveusb.LiveUSBImageCreator(convertoropts)
194 imgtype = misc.get_image_type(base_on)
195 if imgtype == "btrfsimg":
196 fstype = "btrfs"
197 elif imgtype in ("ext3fsimg", "ext4fsimg"):
198 fstype = imgtype[:4]
199 else:
200 raise errors.CreatorError("Unsupported filesystem type: %s" % fstyp)
201 convertor._set_fstype(fstype)
202 try:
203 convertor.mount(base_on)
204 __mkinitrd(convertor)
205 convertor._create_bootconfig()
206 __run_post_cleanups(convertor)
207 convertor.launch_shell(convertoropts['shell'])
208 convertor.unmount()
209 convertor.package()
210 convertor.print_outimage_info()
211 finally:
212 shutil.rmtree(os.path.dirname(base_on), ignore_errors = True)
213
214 @classmethod
215 def do_unpack(cls, srcimg):
216 img = srcimg
217 imgsize = misc.get_file_size(img) * 1024L * 1024L
218 imgmnt = misc.mkdtemp()
219 disk = fs_related.SparseLoopbackDisk(img, imgsize)
220 imgloop = PartitionedMount(imgmnt, skipformat = True)
221 imgloop.add_disk('/dev/sdb', disk)
222 imgloop.add_partition(imgsize/1024/1024, "/dev/sdb", "/", "vfat", boot=False)
223 try:
224 imgloop.mount()
225 except errors.MountError:
226 imgloop.cleanup()
227 raise
228
229 # legacy LiveOS filesystem layout support, remove for F9 or F10
230 if os.path.exists(imgmnt + "/squashfs.img"):
231 squashimg = imgmnt + "/squashfs.img"
232 else:
233 squashimg = imgmnt + "/LiveOS/squashfs.img"
234
235 tmpoutdir = misc.mkdtemp()
236 # unsquashfs requires outdir mustn't exist
237 shutil.rmtree(tmpoutdir, ignore_errors = True)
238 misc.uncompress_squashfs(squashimg, tmpoutdir)
239
240 try:
241 # legacy LiveOS filesystem layout support, remove for F9 or F10
242 if os.path.exists(tmpoutdir + "/os.img"):
243 os_image = tmpoutdir + "/os.img"
244 else:
245 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
246
247 if not os.path.exists(os_image):
248 raise errors.CreatorError("'%s' is not a valid live CD ISO : neither "
249 "LiveOS/ext3fs.img nor os.img exist" %img)
250 imgname = os.path.basename(srcimg)
251 imgname = os.path.splitext(imgname)[0] + ".img"
252 rtimage = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), imgname)
253 shutil.copyfile(os_image, rtimage)
254
255 finally:
256 imgloop.cleanup()
257 shutil.rmtree(tmpoutdir, ignore_errors = True)
258 shutil.rmtree(imgmnt, ignore_errors = True)
259
260 return rtimage
diff --git a/scripts/lib/mic/plugins/imager/loop_plugin.py b/scripts/lib/mic/plugins/imager/loop_plugin.py
deleted file mode 100644
index 2a05b3c238..0000000000
--- a/scripts/lib/mic/plugins/imager/loop_plugin.py
+++ /dev/null
@@ -1,255 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import tempfile
21
22from mic import chroot, msger
23from mic.utils import misc, fs_related, errors, cmdln
24from mic.conf import configmgr
25from mic.plugin import pluginmgr
26from mic.imager.loop import LoopImageCreator, load_mountpoints
27
28from mic.pluginbase import ImagerPlugin
29class LoopPlugin(ImagerPlugin):
30 name = 'loop'
31
32 @classmethod
33 @cmdln.option("--compress-disk-image", dest="compress_image",
34 type='choice', choices=("gz", "bz2"), default=None,
35 help="Same with --compress-image")
36 # alias to compress-image for compatibility
37 @cmdln.option("--compress-image", dest="compress_image",
38 type='choice', choices=("gz", "bz2"), default=None,
39 help="Compress all loop images with 'gz' or 'bz2'")
40 @cmdln.option("--shrink", action='store_true', default=False,
41 help="Whether to shrink loop images to minimal size")
42 def do_create(self, subcmd, opts, *args):
43 """${cmd_name}: create loop image
44
45 Usage:
46 ${name} ${cmd_name} <ksfile> [OPTS]
47
48 ${cmd_option_list}
49 """
50
51 if len(args) != 1:
52 raise errors.Usage("Extra arguments given")
53
54 creatoropts = configmgr.create
55 ksconf = args[0]
56
57 if creatoropts['runtime'] == "bootstrap":
58 configmgr._ksconf = ksconf
59 rt_util.bootstrap_mic()
60
61 recording_pkgs = []
62 if len(creatoropts['record_pkgs']) > 0:
63 recording_pkgs = creatoropts['record_pkgs']
64
65 if creatoropts['release'] is not None:
66 if 'name' not in recording_pkgs:
67 recording_pkgs.append('name')
68 if 'vcs' not in recording_pkgs:
69 recording_pkgs.append('vcs')
70
71 configmgr._ksconf = ksconf
72
73 # Called After setting the configmgr._ksconf
74 # as the creatoropts['name'] is reset there.
75 if creatoropts['release'] is not None:
76 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'],
77 creatoropts['release'],
78 creatoropts['name'])
79 # try to find the pkgmgr
80 pkgmgr = None
81 backends = pluginmgr.get_plugins('backend')
82 if 'auto' == creatoropts['pkgmgr']:
83 for key in configmgr.prefer_backends:
84 if key in backends:
85 pkgmgr = backends[key]
86 break
87 else:
88 for key in backends.keys():
89 if key == creatoropts['pkgmgr']:
90 pkgmgr = backends[key]
91 break
92
93 if not pkgmgr:
94 raise errors.CreatorError("Can't find backend: %s, "
95 "available choices: %s" %
96 (creatoropts['pkgmgr'],
97 ','.join(backends.keys())))
98
99 creator = LoopImageCreator(creatoropts,
100 pkgmgr,
101 opts.compress_image,
102 opts.shrink)
103
104 if len(recording_pkgs) > 0:
105 creator._recording_pkgs = recording_pkgs
106
107 image_names = [creator.name + ".img"]
108 image_names.extend(creator.get_image_names())
109 self.check_image_exists(creator.destdir,
110 creator.pack_to,
111 image_names,
112 creatoropts['release'])
113
114 try:
115 creator.check_depend_tools()
116 creator.mount(None, creatoropts["cachedir"])
117 creator.install()
118 creator.configure(creatoropts["repomd"])
119 creator.copy_kernel()
120 creator.unmount()
121 creator.package(creatoropts["outdir"])
122
123 if creatoropts['release'] is not None:
124 creator.release_output(ksconf,
125 creatoropts['outdir'],
126 creatoropts['release'])
127 creator.print_outimage_info()
128
129 except errors.CreatorError:
130 raise
131 finally:
132 creator.cleanup()
133
134 msger.info("Finished.")
135 return 0
136
137 @classmethod
138 def _do_chroot_tar(cls, target, cmd=[]):
139 mountfp_xml = os.path.splitext(target)[0] + '.xml'
140 if not os.path.exists(mountfp_xml):
141 raise errors.CreatorError("No mount point file found for this tar "
142 "image, please check %s" % mountfp_xml)
143
144 import tarfile
145 tar = tarfile.open(target, 'r')
146 tmpdir = misc.mkdtemp()
147 tar.extractall(path=tmpdir)
148 tar.close()
149
150 mntdir = misc.mkdtemp()
151
152 loops = []
153 for (mp, label, name, size, fstype) in load_mountpoints(mountfp_xml):
154 if fstype in ("ext2", "ext3", "ext4"):
155 myDiskMount = fs_related.ExtDiskMount
156 elif fstype == "btrfs":
157 myDiskMount = fs_related.BtrfsDiskMount
158 elif fstype in ("vfat", "msdos"):
159 myDiskMount = fs_related.VfatDiskMount
160 else:
161 msger.error("Cannot support fstype: %s" % fstype)
162
163 name = os.path.join(tmpdir, name)
164 size = size * 1024L * 1024L
165 loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size),
166 os.path.join(mntdir, mp.lstrip('/')),
167 fstype, size, label)
168
169 try:
170 msger.verbose("Mount %s to %s" % (mp, mntdir + mp))
171 fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/')))
172 loop.mount()
173
174 except:
175 loop.cleanup()
176 for lp in reversed(loops):
177 chroot.cleanup_after_chroot("img", lp, None, mntdir)
178
179 shutil.rmtree(tmpdir, ignore_errors=True)
180 raise
181
182 loops.append(loop)
183
184 try:
185 if len(cmd) != 0:
186 cmdline = "/usr/bin/env HOME=/root " + ' '.join(cmd)
187 else:
188 cmdline = "/usr/bin/env HOME=/root /bin/bash"
189 chroot.chroot(mntdir, None, cmdline)
190 except:
191 raise errors.CreatorError("Failed to chroot to %s." % target)
192 finally:
193 for loop in reversed(loops):
194 chroot.cleanup_after_chroot("img", loop, None, mntdir)
195
196 shutil.rmtree(tmpdir, ignore_errors=True)
197
198 @classmethod
199 def do_chroot(cls, target, cmd=[]):
200 if target.endswith('.tar'):
201 import tarfile
202 if tarfile.is_tarfile(target):
203 LoopPlugin._do_chroot_tar(target, cmd)
204 return
205 else:
206 raise errors.CreatorError("damaged tarball for loop images")
207
208 img = target
209 imgsize = misc.get_file_size(img) * 1024L * 1024L
210 imgtype = misc.get_image_type(img)
211 if imgtype == "btrfsimg":
212 fstype = "btrfs"
213 myDiskMount = fs_related.BtrfsDiskMount
214 elif imgtype in ("ext3fsimg", "ext4fsimg"):
215 fstype = imgtype[:4]
216 myDiskMount = fs_related.ExtDiskMount
217 else:
218 raise errors.CreatorError("Unsupported filesystem type: %s" \
219 % imgtype)
220
221 extmnt = misc.mkdtemp()
222 extloop = myDiskMount(fs_related.SparseLoopbackDisk(img, imgsize),
223 extmnt,
224 fstype,
225 4096,
226 "%s label" % fstype)
227 try:
228 extloop.mount()
229
230 except errors.MountError:
231 extloop.cleanup()
232 shutil.rmtree(extmnt, ignore_errors=True)
233 raise
234
235 try:
236 if len(cmd) != 0:
237 cmdline = ' '.join(cmd)
238 else:
239 cmdline = "/bin/bash"
240 envcmd = fs_related.find_binary_inchroot("env", extmnt)
241 if envcmd:
242 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
243 chroot.chroot(extmnt, None, cmdline)
244 except:
245 raise errors.CreatorError("Failed to chroot to %s." % img)
246 finally:
247 chroot.cleanup_after_chroot("img", extloop, None, extmnt)
248
249 @classmethod
250 def do_unpack(cls, srcimg):
251 image = os.path.join(tempfile.mkdtemp(dir="/var/tmp", prefix="tmp"),
252 "target.img")
253 msger.info("Copying file system ...")
254 shutil.copyfile(srcimg, image)
255 return image
diff --git a/scripts/lib/mic/plugins/imager/raw_plugin.py b/scripts/lib/mic/plugins/imager/raw_plugin.py
deleted file mode 100644
index f9625b87e8..0000000000
--- a/scripts/lib/mic/plugins/imager/raw_plugin.py
+++ /dev/null
@@ -1,275 +0,0 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import re
21import tempfile
22
23from mic import chroot, msger
24from mic.utils import misc, fs_related, errors, runner, cmdln
25from mic.conf import configmgr
26from mic.plugin import pluginmgr
27from mic.utils.partitionedfs import PartitionedMount
28
29import mic.imager.raw as raw
30
31from mic.pluginbase import ImagerPlugin
32class RawPlugin(ImagerPlugin):
33 name = 'raw'
34
35 @classmethod
36 @cmdln.option("--compress-disk-image", dest="compress_image", type='choice',
37 choices=("gz", "bz2"), default=None,
38 help="Same with --compress-image")
39 @cmdln.option("--compress-image", dest="compress_image", type='choice',
40 choices=("gz", "bz2"), default = None,
41 help="Compress all raw images before package")
42 @cmdln.option("--generate-bmap", action="store_true", default = None,
43 help="also generate the block map file")
44 @cmdln.option("--fstab-entry", dest="fstab_entry", type='choice',
45 choices=("name", "uuid"), default="uuid",
46 help="Set fstab entry, 'name' means using device names, "
47 "'uuid' means using filesystem uuid")
48 def do_create(self, subcmd, opts, *args):
49 """${cmd_name}: create raw image
50
51 Usage:
52 ${name} ${cmd_name} <ksfile> [OPTS]
53
54 ${cmd_option_list}
55 """
56
57 if len(args) != 1:
58 raise errors.Usage("Extra arguments given")
59
60 creatoropts = configmgr.create
61 ksconf = args[0]
62
63 if creatoropts['runtime'] == "bootstrap":
64 configmgr._ksconf = ksconf
65 rt_util.bootstrap_mic()
66
67 recording_pkgs = []
68 if len(creatoropts['record_pkgs']) > 0:
69 recording_pkgs = creatoropts['record_pkgs']
70
71 if creatoropts['release'] is not None:
72 if 'name' not in recording_pkgs:
73 recording_pkgs.append('name')
74 if 'vcs' not in recording_pkgs:
75 recording_pkgs.append('vcs')
76
77 configmgr._ksconf = ksconf
78
79 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
80 if creatoropts['release'] is not None:
81 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
82
83 # try to find the pkgmgr
84 pkgmgr = None
85 backends = pluginmgr.get_plugins('backend')
86 if 'auto' == creatoropts['pkgmgr']:
87 for key in configmgr.prefer_backends:
88 if key in backends:
89 pkgmgr = backends[key]
90 break
91 else:
92 for key in backends.keys():
93 if key == creatoropts['pkgmgr']:
94 pkgmgr = backends[key]
95 break
96
97 if not pkgmgr:
98 raise errors.CreatorError("Can't find backend: %s, "
99 "available choices: %s" %
100 (creatoropts['pkgmgr'],
101 ','.join(backends.keys())))
102
103 creator = raw.RawImageCreator(creatoropts, pkgmgr, opts.compress_image,
104 opts.generate_bmap, opts.fstab_entry)
105
106 if len(recording_pkgs) > 0:
107 creator._recording_pkgs = recording_pkgs
108
109 images = ["%s-%s.raw" % (creator.name, disk_name)
110 for disk_name in creator.get_disk_names()]
111 self.check_image_exists(creator.destdir,
112 creator.pack_to,
113 images,
114 creatoropts['release'])
115
116 try:
117 creator.check_depend_tools()
118 creator.mount(None, creatoropts["cachedir"])
119 creator.install()
120 creator.configure(creatoropts["repomd"])
121 creator.copy_kernel()
122 creator.unmount()
123 creator.generate_bmap()
124 creator.package(creatoropts["outdir"])
125 if creatoropts['release'] is not None:
126 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
127 creator.print_outimage_info()
128
129 except errors.CreatorError:
130 raise
131 finally:
132 creator.cleanup()
133
134 msger.info("Finished.")
135 return 0
136
137 @classmethod
138 def do_chroot(cls, target, cmd=[]):
139 img = target
140 imgsize = misc.get_file_size(img) * 1024L * 1024L
141 partedcmd = fs_related.find_binary_path("parted")
142 disk = fs_related.SparseLoopbackDisk(img, imgsize)
143 imgmnt = misc.mkdtemp()
144 imgloop = PartitionedMount(imgmnt, skipformat = True)
145 imgloop.add_disk('/dev/sdb', disk)
146 img_fstype = "ext3"
147
148 msger.info("Partition Table:")
149 partnum = []
150 for line in runner.outs([partedcmd, "-s", img, "print"]).splitlines():
151 # no use strip to keep line output here
152 if "Number" in line:
153 msger.raw(line)
154 if line.strip() and line.strip()[0].isdigit():
155 partnum.append(line.strip()[0])
156 msger.raw(line)
157
158 rootpart = None
159 if len(partnum) > 1:
160 rootpart = msger.choice("please choose root partition", partnum)
161
162 # Check the partitions from raw disk.
163 # if choose root part, the mark it as mounted
164 if rootpart:
165 root_mounted = True
166 else:
167 root_mounted = False
168 partition_mounts = 0
169 for line in runner.outs([partedcmd,"-s",img,"unit","B","print"]).splitlines():
170 line = line.strip()
171
172 # Lines that start with number are the partitions,
173 # because parted can be translated we can't refer to any text lines.
174 if not line or not line[0].isdigit():
175 continue
176
177 # Some vars have extra , as list seperator.
178 line = line.replace(",","")
179
180 # Example of parted output lines that are handled:
181 # Number Start End Size Type File system Flags
182 # 1 512B 3400000511B 3400000000B primary
183 # 2 3400531968B 3656384511B 255852544B primary linux-swap(v1)
184 # 3 3656384512B 3720347647B 63963136B primary fat16 boot, lba
185
186 partition_info = re.split("\s+",line)
187
188 size = partition_info[3].split("B")[0]
189
190 if len(partition_info) < 6 or partition_info[5] in ["boot"]:
191 # No filesystem can be found from partition line. Assuming
192 # btrfs, because that is the only MeeGo fs that parted does
193 # not recognize properly.
194 # TODO: Can we make better assumption?
195 fstype = "btrfs"
196 elif partition_info[5] in ["ext2","ext3","ext4","btrfs"]:
197 fstype = partition_info[5]
198 elif partition_info[5] in ["fat16","fat32"]:
199 fstype = "vfat"
200 elif "swap" in partition_info[5]:
201 fstype = "swap"
202 else:
203 raise errors.CreatorError("Could not recognize partition fs type '%s'." % partition_info[5])
204
205 if rootpart and rootpart == line[0]:
206 mountpoint = '/'
207 elif not root_mounted and fstype in ["ext2","ext3","ext4","btrfs"]:
208 # TODO: Check that this is actually the valid root partition from /etc/fstab
209 mountpoint = "/"
210 root_mounted = True
211 elif fstype == "swap":
212 mountpoint = "swap"
213 else:
214 # TODO: Assing better mount points for the rest of the partitions.
215 partition_mounts += 1
216 mountpoint = "/media/partition_%d" % partition_mounts
217
218 if "boot" in partition_info:
219 boot = True
220 else:
221 boot = False
222
223 msger.verbose("Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" % (size, fstype, mountpoint, boot))
224 # TODO: add_partition should take bytes as size parameter.
225 imgloop.add_partition((int)(size)/1024/1024, "/dev/sdb", mountpoint, fstype = fstype, boot = boot)
226
227 try:
228 imgloop.mount()
229
230 except errors.MountError:
231 imgloop.cleanup()
232 raise
233
234 try:
235 if len(cmd) != 0:
236 cmdline = ' '.join(cmd)
237 else:
238 cmdline = "/bin/bash"
239 envcmd = fs_related.find_binary_inchroot("env", imgmnt)
240 if envcmd:
241 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
242 chroot.chroot(imgmnt, None, cmdline)
243 except:
244 raise errors.CreatorError("Failed to chroot to %s." %img)
245 finally:
246 chroot.cleanup_after_chroot("img", imgloop, None, imgmnt)
247
248 @classmethod
249 def do_unpack(cls, srcimg):
250 srcimgsize = (misc.get_file_size(srcimg)) * 1024L * 1024L
251 srcmnt = misc.mkdtemp("srcmnt")
252 disk = fs_related.SparseLoopbackDisk(srcimg, srcimgsize)
253 srcloop = PartitionedMount(srcmnt, skipformat = True)
254
255 srcloop.add_disk('/dev/sdb', disk)
256 srcloop.add_partition(srcimgsize/1024/1024, "/dev/sdb", "/", "ext3", boot=False)
257 try:
258 srcloop.mount()
259
260 except errors.MountError:
261 srcloop.cleanup()
262 raise
263
264 image = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), "target.img")
265 args = ['dd', "if=%s" % srcloop.partitions[0]['device'], "of=%s" % image]
266
267 msger.info("`dd` image ...")
268 rc = runner.show(args)
269 srcloop.cleanup()
270 shutil.rmtree(os.path.dirname(srcmnt), ignore_errors = True)
271
272 if rc != 0:
273 raise errors.CreatorError("Failed to dd")
274 else:
275 return image
diff --git a/scripts/lib/mic/plugins/source/bootimg-efi.py b/scripts/lib/mic/plugins/source/bootimg-efi.py
index aecda6b0f1..95e1c059b9 100644
--- a/scripts/lib/mic/plugins/source/bootimg-efi.py
+++ b/scripts/lib/mic/plugins/source/bootimg-efi.py
@@ -29,7 +29,7 @@ import shutil
29import re 29import re
30import tempfile 30import tempfile
31 31
32from mic import kickstart, chroot, msger 32from mic import kickstart, msger
33from mic.utils import misc, fs_related, errors, runner, cmdln 33from mic.utils import misc, fs_related, errors, runner, cmdln
34from mic.conf import configmgr 34from mic.conf import configmgr
35from mic.plugin import pluginmgr 35from mic.plugin import pluginmgr
diff --git a/scripts/lib/mic/plugins/source/bootimg-pcbios.py b/scripts/lib/mic/plugins/source/bootimg-pcbios.py
index 6488ae9729..9959645606 100644
--- a/scripts/lib/mic/plugins/source/bootimg-pcbios.py
+++ b/scripts/lib/mic/plugins/source/bootimg-pcbios.py
@@ -29,7 +29,7 @@ import shutil
29import re 29import re
30import tempfile 30import tempfile
31 31
32from mic import kickstart, chroot, msger 32from mic import kickstart, msger
33from mic.utils import misc, fs_related, errors, runner, cmdln 33from mic.utils import misc, fs_related, errors, runner, cmdln
34from mic.conf import configmgr 34from mic.conf import configmgr
35from mic.plugin import pluginmgr 35from mic.plugin import pluginmgr
diff --git a/scripts/lib/mic/plugins/source/rootfs.py b/scripts/lib/mic/plugins/source/rootfs.py
index a4d4547318..8cb576d5b9 100644
--- a/scripts/lib/mic/plugins/source/rootfs.py
+++ b/scripts/lib/mic/plugins/source/rootfs.py
@@ -30,7 +30,7 @@ import shutil
30import re 30import re
31import tempfile 31import tempfile
32 32
33from mic import kickstart, chroot, msger 33from mic import kickstart, msger
34from mic.utils import misc, fs_related, errors, runner, cmdln 34from mic.utils import misc, fs_related, errors, runner, cmdln
35from mic.conf import configmgr 35from mic.conf import configmgr
36from mic.plugin import pluginmgr 36from mic.plugin import pluginmgr