[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: [Fedora-livecd-list] Targetting other file systems besides iso
- From: Mark McLoughlin <markmc redhat com>
- To: fedora-livecd-list redhat com
- Subject: Re: [Fedora-livecd-list] Targetting other file systems besides iso
- Date: Thu, 26 Apr 2007 10:22:21 +0100
On Wed, 2007-04-25 at 13:41 -0400, David Zeuthen wrote:
> On Tue, 2007-04-24 at 15:10 -0400, John (J5) Palmieri wrote:
> > At OLPC we need to support ext3 and jffs2 builds even more so than
> > livecd isos. Since most of the process is the same up until the final
> > image and bootloaders we would like to add this support into the livecd
> > tools so that all fedora projects use one toolchain. The question is
> > how can this best be accomplished?
> >
> > I think passing a --variant switch (i.e. --variant=jffs2) should switch
> > the backend to generating the correct image.
>
> I think adding an option
>
> --target=[livecd|
> disk_msdos_ext3|
> disk_msdos_ext3_separate_boot|
> ext3|
> jffs2]
>
> with this help text (for --help)
>
> --target Choose target mode; defaults to livecd
> livecd: A compressed livecd ISO with the root file system
> disk_msdos_ext3 : An image with a MSDOS partitioning
> table, a single ext3 data partition and
> a bootloader for IBM PC hardware
> disk_msdos_ext3_separate_boot : Like disk_msdos_ext3 only
> that /boot is on a separate partition.
> ext3 : A single ext3 partition
> jffs2 : A jffs2 file system
>
> is what we want. Perhaps disk_msdos_ext3_separate_boot can be achieved
> by a separate option just like we have --skip-compression for
> --target=livecd. Thoughts?
I've a few of patches to do something similar, except I've been using
livecd-creator to build xen system images for the likes of image based
deployment (e.g. stateless) or this virtual appliances notion.
See the attached patches - the first makes LiveCDTarget be a sub-class
of InstallationTarget, the second adds --target and the last adds
RawTarget which I've been playing with.
Cheers,
Mark.
Index: livecd/creator/livecd-creator
===================================================================
--- livecd.orig/creator/livecd-creator
+++ livecd/creator/livecd-creator
@@ -325,48 +325,11 @@ class InstallationTarget:
if not self.repos:
raise InstallationError("No repositories specified")
- def base_on_iso(self, base_on):
- """helper function to extract ext3 file system from a live CD ISO"""
-
- isoloop = LoopbackMount(base_on, "%s/base_on_iso" %(self.build_dir,))
-
- squashloop = LoopbackMount("%s/squashfs.img" %(isoloop.mountdir,),
- "%s/base_on_squashfs" %(self.build_dir,),
- "squashfs")
-
- try:
- try:
- isoloop.mount()
- except MountError, e:
- raise InstallationError("Failed to loopback mount '%s' : %s" % (base_on, e))
-
- if not os.path.exists(squashloop.lofile):
- raise InstallationError("'%s' is not a valid live CD ISO : squashfs.img doesn't exist" % base_on)
-
- try:
- squashloop.mount()
- except MountError, e:
- raise InstallationError("Failed to loopback mount squashfs.img from '%s' : %s" % (base_on, e))
-
- os_image = self.build_dir + "/base_on_squashfs/os.img"
-
- if not os.path.exists(os_image):
- raise InstallationError("'%s' is not a valid live CD ISO : os.img doesn't exist" % base_on)
-
- shutil.copyfile(os_image, self.build_dir + "/data/os.img")
- finally:
- # unmount and tear down the mount points and loop devices used
- squashloop.cleanup()
- isoloop.cleanup()
+ def base_on(self, base_on):
+ pass
def write_fstab(self):
- fstab = open(self.build_dir + "/install_root/etc/fstab", "w")
- fstab.write("/dev/mapper/livecd-rw / ext3 defaults,noatime 0 0\n")
- fstab.write("devpts /dev/pts devpts gid=5,mode=620 0 0\n")
- fstab.write("tmpfs /dev/shm tmpfs defaults 0 0\n")
- fstab.write("proc /proc proc defaults 0 0\n")
- fstab.write("sysfs /sys sysfs defaults 0 0\n")
- fstab.close()
+ pass
def setup(self, image_size, base_on = None):
"""setup target ext3 file system in preparation for an install"""
@@ -377,15 +340,13 @@ class InstallationTarget:
except OSError, (err, msg):
raise InstallationError("Failed create build directory in /var/tmp: %s" % msg)
- os.makedirs(self.build_dir + "/out/isolinux")
- os.makedirs(self.build_dir + "/out/sysroot")
+ os.makedirs(self.build_dir + "/out")
os.makedirs(self.build_dir + "/data/sysroot")
os.makedirs(self.build_dir + "/install_root")
os.makedirs(self.build_dir + "/yum-cache")
if base_on:
- # get backing ext3 image if we're based this build on an existing live CD ISO
- self.base_on_iso(base_on)
+ self.base_on(base_on)
self.instloop = LoopbackMount("%s/data/os.img" %(self.build_dir,),
"%s/install_root" %(self.build_dir,))
@@ -748,6 +709,90 @@ class InstallationTarget:
return kernels[0]
+ def relabelSystem(self):
+ # finally relabel all files
+ if self.ksparser.handler.selinux.selinux:
+ instroot = "%s/install_root" %(self.build_dir,)
+ if os.path.exists("%s/sbin/restorecon" %(instroot,)):
+ subprocess.call(["/sbin/restorecon", "-v", "-r", "/"],
+ preexec_fn=self.run_in_root)
+
+ def prelinkSystem(self):
+ # prelink the system
+ if not self.skip_prelink:
+ instroot = "%s/install_root" %(self.build_dir,)
+ if os.path.exists("%s/usr/sbin/prelink" %(instroot,)):
+ subprocess.call(["/usr/sbin/prelink", "-mRaN"],
+ preexec_fn=self.run_in_root)
+
+ def launchShell(self):
+ subprocess.call(["/bin/bash"], preexec_fn=self.run_in_root)
+
+ def install(self):
+ for (name, url) in self.repos:
+ self.ayum.addRepository(name, url)
+
+ self.installPackages(self.packages, self.epackages, self.groups)
+ self.configureSystem()
+ self.configureNetwork()
+ self.relabelSystem()
+ self.prelinkSystem()
+
+ def package(self):
+ pass
+
+class LiveCDTarget(InstallationTarget):
+ def __init__(self, repos, packages, epackages, groups, fs_label, skip_compression, skip_prelink):
+ InstallationTarget.__init__(self, repos, packages, epackages, groups, fs_label, skip_compression, skip_prelink)
+
+ def base_on(self, base_on):
+ """helper function to extract ext3 file system from a live CD ISO"""
+
+ isoloop = LoopbackMount(base_on, "%s/base_on_iso" %(self.build_dir,))
+
+ squashloop = LoopbackMount("%s/squashfs.img" %(isoloop.mountdir,),
+ "%s/base_on_squashfs" %(self.build_dir,),
+ "squashfs")
+
+ try:
+ try:
+ isoloop.mount()
+ except MountError, e:
+ raise InstallationError("Failed to loopback mount '%s' : %s" % (base_on, e))
+
+ if not os.path.exists(squashloop.lofile):
+ raise InstallationError("'%s' is not a valid live CD ISO : squashfs.img doesn't exist" % base_on)
+
+ try:
+ squashloop.mount()
+ except MountError, e:
+ raise InstallationError("Failed to loopback mount squashfs.img from '%s' : %s" % (base_on, e))
+
+ os_image = self.build_dir + "/base_on_squashfs/os.img"
+
+ if not os.path.exists(os_image):
+ raise InstallationError("'%s' is not a valid live CD ISO : os.img doesn't exist" % base_on)
+
+ shutil.copyfile(os_image, self.build_dir + "/data/os.img")
+ finally:
+ # unmount and tear down the mount points and loop devices used
+ squashloop.cleanup()
+ isoloop.cleanup()
+
+ def write_fstab(self):
+ fstab = open(self.build_dir + "/install_root/etc/fstab", "w")
+ fstab.write("/dev/mapper/livecd-rw / ext3 defaults,noatime 0 0\n")
+ fstab.write("devpts /dev/pts devpts gid=5,mode=620 0 0\n")
+ fstab.write("tmpfs /dev/shm tmpfs defaults 0 0\n")
+ fstab.write("proc /proc proc defaults 0 0\n")
+ fstab.write("sysfs /sys sysfs defaults 0 0\n")
+ fstab.close()
+
+ def setup(self, image_size, base_on = None):
+ """setup target ext3 file system in preparation for an install"""
+ InstallationTarget.setup(self, image_size, base_on)
+ os.makedirs(self.build_dir + "/out/isolinux")
+
def createInitramfs(self):
# Create initramfs
if not os.path.isfile("/usr/lib/livecd-creator/mayflower"):
@@ -770,25 +815,6 @@ class InstallationTarget:
for f in ("/sbin/mayflower", "/etc/mayflower.conf"):
os.unlink("%s/install_root/%s" %(self.build_dir, f))
- def relabelSystem(self):
- # finally relabel all files
- if self.ksparser.handler.selinux.selinux:
- instroot = "%s/install_root" %(self.build_dir,)
- if os.path.exists("%s/sbin/restorecon" %(instroot,)):
- subprocess.call(["/sbin/restorecon", "-v", "-r", "/"],
- preexec_fn=self.run_in_root)
-
- def prelinkSystem(self):
- # prelink the system
- instroot = "%s/install_root" %(self.build_dir,)
- if os.path.exists("%s/usr/sbin/prelink" %(instroot,)):
- subprocess.call(["/usr/sbin/prelink", "-mRaN"],
- preexec_fn=self.run_in_root)
- return True
-
- def launchShell(self):
- subprocess.call(["/bin/bash"], preexec_fn=self.run_in_root)
-
def configureBootloader(self):
"""configure the boot loader"""
@@ -859,15 +885,7 @@ menu color hotkey 0 #ffffffff #ff000000
# TODO: enable external entitity to partipate in adding boot entries
def install(self):
- for (name, url) in self.repos:
- self.ayum.addRepository(name, url)
-
- self.installPackages(self.packages, self.epackages, self.groups)
- self.configureSystem()
- self.configureNetwork()
- self.relabelSystem()
- if not self.skip_prelink:
- self.prelinkSystem()
+ InstallationTarget.install(self)
self.createInitramfs()
self.configureBootloader()
@@ -900,6 +918,7 @@ menu color hotkey 0 #ffffffff #ff000000
"%s/out/ext3fs.img" %(self.build_dir,))
def package(self):
+ InstallationTarget.package(self)
self.createSquashFS()
self.createIso()
@@ -1047,13 +1066,13 @@ def main():
print >> sys.stderr, "You must run livecd-creator as root"
return 1
- target = InstallationTarget(options.repos,
- options.packages,
- options.epackages,
- options.groups,
- options.fs_label,
- options.skip_compression,
- options.skip_prelink)
+ target = LiveCDTarget(options.repos,
+ options.packages,
+ options.epackages,
+ options.groups,
+ options.fs_label,
+ options.skip_compression,
+ options.skip_prelink)
try:
target.parse(options.kscfg)
Index: livecd/creator/livecd-creator
===================================================================
--- livecd.orig/creator/livecd-creator
+++ livecd/creator/livecd-creator
@@ -925,6 +925,7 @@ menu color hotkey 0 #ffffffff #ff000000
def usage(out):
print >> out, """
usage: livecd-creator [--help]
+ [--type=<livecd|...>]
[--config=<path-to-kickstart-file> | --repo=<name>,<url> --package=<p>]
[--repo=<name1>,<url1>] [--repo=<name2>,<url2> ...]
[--package=<p1>] [--package=<p2> ...]
@@ -936,6 +937,7 @@ usage: livecd-creator [--help]
[--shell]
--help : Print usage and exit
+ --type : The target type e.g. "livecd" or ...
--config : Path to kickstart config file
--repo : Add / override yum repository
--package : Include this package
@@ -968,6 +970,7 @@ class Options:
self.packages = []
self.groups = []
self.epackages = []
+ self.target_class = LiveCDTarget
self.fs_label = "livecd-" + time.strftime("%Y%m%d-%H%M")
self.base_on = None
self.kscfg = None
@@ -978,8 +981,8 @@ class Options:
def parse_options(args):
try:
- opts, args = getopt.getopt(args, "hr:b:p:e:f:c:su:l",
- ["help", "repo=", "base-on=", "package=",
+ opts, args = getopt.getopt(args, "ht:r:b:p:e:f:c:su:l",
+ ["help", "type=", "repo=", "base-on=", "package=",
"exclude-package=", "fslabel=", "config=",
"skip-compression", "uncompressed-size=",
"shell", "no-prelink", "prelink"])
@@ -991,6 +994,12 @@ def parse_options(args):
for o, a in opts:
if o in ("-h", "--help"):
raise Usage(no_error = True)
+ if o in ("-t", "--type"):
+ if a == "livecd":
+ options.target_class = LiveCDTarget
+ else:
+ raise Usage("'%s' is not a known installation target type." % a)
+ continue
if o in ("-l", "--shell"):
options.give_shell = True
continue
@@ -1066,13 +1075,13 @@ def main():
print >> sys.stderr, "You must run livecd-creator as root"
return 1
- target = LiveCDTarget(options.repos,
- options.packages,
- options.epackages,
- options.groups,
- options.fs_label,
- options.skip_compression,
- options.skip_prelink)
+ target = options.target_class(options.repos,
+ options.packages,
+ options.epackages,
+ options.groups,
+ options.fs_label,
+ options.skip_compression,
+ options.skip_prelink)
try:
target.parse(options.kscfg)
Index: livecd/creator/livecd-creator
===================================================================
--- livecd.orig/creator/livecd-creator
+++ livecd/creator/livecd-creator
@@ -922,10 +922,100 @@ menu color hotkey 0 #ffffffff #ff000000
self.createSquashFS()
self.createIso()
+class RawTarget(InstallationTarget):
+ def __init__(self, repos, packages, epackages, groups, fs_label, skip_compression, skip_prelink):
+ InstallationTarget.__init__(self, repos, packages, epackages, groups, fs_label, skip_compression, skip_prelink)
+
+ def base_on(self, base_on):
+ raise InstallationError("--base-on is not supported with --type=raw")
+
+ def write_fstab(self):
+ fstab = open(self.build_dir + "/install_root/etc/fstab", "w")
+ fstab.write("/dev/root / ext3 defaults,noatime 0 0\n")
+ fstab.write("devpts /dev/pts devpts gid=5,mode=620 0 0\n")
+ fstab.write("tmpfs /dev/shm tmpfs defaults 0 0\n")
+ fstab.write("proc /proc proc defaults 0 0\n")
+ fstab.write("sysfs /sys sysfs defaults 0 0\n")
+ fstab.close()
+
+ def setup(self, image_size, base_on = None):
+ return InstallationTarget.setup(self, image_size, base_on)
+
+ def createInitramfs(self):
+ conf = open(self.build_dir + "/install_root/etc/sysconfig/mkinitrd", "w")
+ conf.write('PROBE="no"\n')
+ conf.write('MODULES="xenblk xennet ext3"\n')
+ conf.close()
+
+ subprocess.call(["/sbin/mkinitrd", "-f",
+ "--rootdev", "/dev/xvda",
+ "--rootopts", "defaults",
+ "--rootfs", "ext3",
+ "/boot/livecd-initramfs.img", self.get_kernel_version()],
+ preexec_fn=self.run_in_root)
+
+ os.mkdir(self.build_dir + "/out/" + self.fs_label)
+
+ shutil.copyfile(self.build_dir + "/install_root/boot/vmlinuz-" + self.get_kernel_version(),
+ self.build_dir + "/out/" + self.fs_label + "/vmlinuz")
+ shutil.copyfile(self.build_dir + "/install_root/boot/livecd-initramfs.img",
+ self.build_dir + "/out/" + self.fs_label + "/initrd.img")
+
+ def install(self):
+ InstallationTarget.install(self)
+ self.createInitramfs()
+
+ def writeXML(self):
+ xml = open(self.build_dir + "/out/" + self.fs_label + "/livecd.xml", "w")
+ xml.write("<domain>\n")
+ xml.write(" <name>%s</name>\n" % self.fs_label)
+ xml.write(" <os>\n")
+ xml.write(" <type>linux</type>\n")
+ xml.write(" <kernel>%s/%s/vmlinuz</kernel>\n" % (os.getcwd(), self.fs_label))
+ xml.write(" <initrd>%s/%s/initrd.img</initrd>\n" % (os.getcwd(), self.fs_label))
+ xml.write(" <cmdline>debug console=xvc0</cmdline>\n")
+ xml.write(" </os>\n")
+ xml.write(" <memory>131072</memory>\n")
+ xml.write(" <vcpu>1</vcpu>\n")
+ xml.write(" <devices>\n")
+ xml.write(" <disk type='file'>\n")
+ #
+ # Fantasy land
+ #
+ # if not self.skip_compression:
+ # xml.write(" <driver name='tap' type='qcow' />\n")
+ # xml.write(" <source file='%s/%s/os.qcow' />\n" % (os.getcwd(), self.fs_label))
+ xml.write(" <source file='%s/%s/os.img' />\n" % (os.getcwd(), self.fs_label))
+ xml.write(" <target dev='xvda' />\n")
+ xml.write(" </disk>\n")
+ xml.write(" <interface />\n")
+ xml.write(" </devices>\n")
+ xml.write("</domain>\n")
+ xml.close()
+
+ def package(self):
+ InstallationTarget.package(self)
+
+ #
+ # Fantasy land
+ #
+ # if not self.skip_compression:
+ # subprocess.call(["/usr/sbin/img2qcow",
+ # self.build_dir + "/out/" + self.fs_label + "/os.qcow",
+ # self.build_dir + "/data/os.img"])
+
+ shutil.move(self.build_dir + "/data/os.img",
+ self.build_dir + "/out/" + self.fs_label + "/os.img")
+
+ self.writeXML()
+
+ shutil.move(self.build_dir + "/out/" + self.fs_label, self.fs_label)
+
+
def usage(out):
print >> out, """
usage: livecd-creator [--help]
- [--type=<livecd|...>]
+ [--type=<livecd|raw>]
[--config=<path-to-kickstart-file> | --repo=<name>,<url> --package=<p>]
[--repo=<name1>,<url1>] [--repo=<name2>,<url2> ...]
[--package=<p1>] [--package=<p2> ...]
@@ -997,6 +1087,8 @@ def parse_options(args):
if o in ("-t", "--type"):
if a == "livecd":
options.target_class = LiveCDTarget
+ elif a == "raw":
+ options.target_class = RawTarget
else:
raise Usage("'%s' is not a known installation target type." % a)
continue
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]