[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Fedora-livecd-list] Targetting other file systems besides iso



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]