call copy_attachment() after configure() and move attachment files
[tools/mic.git] / plugins / imager / raw_plugin.py
old mode 100644 (file)
new mode 100755 (executable)
index 5f58001..ef537a4
@@ -1,29 +1,30 @@
 #!/usr/bin/python -tt
 #
-# Copyright 2011 Intel, Inc.
+# Copyright (c) 2011 Intel, Inc.
 #
-# This copyrighted material is made available to anyone wishing to use, modify,
-# copy, or redistribute it subject to the terms and conditions of the GNU
-# General Public License v.2.  This program is distributed in the hope that it
-# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
-# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the GNU General Public License for more details.
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; version 2 of the License
 #
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  Any Red Hat
-# trademarks that are incorporated in the source code or documentation are not
-# subject to the GNU General Public License and may only be used or replicated
-# with the express permission of Red Hat, Inc.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
 #
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 import os
+import subprocess
 import shutil
 import re
 import tempfile
 
-from mic import configmgr, pluginmgr, chroot, msger
+from mic import chroot, msger, rt_util
 from mic.utils import misc, fs_related, errors, runner
+from mic.conf import configmgr
+from mic.plugin import pluginmgr
 from mic.utils.partitionedfs import PartitionedMount
 
 import mic.imager.raw as raw
@@ -33,55 +34,80 @@ class RawPlugin(ImagerPlugin):
     name = 'raw'
 
     @classmethod
-    def do_create(self, subcmd, opts, *args):
+    def do_create(self, args):
         """${cmd_name}: create raw image
 
-        ${cmd_usage}
+        Usage:
+            ${name} ${cmd_name} <ksfile> [OPTS]
+
         ${cmd_option_list}
         """
 
-        if not args:
-            raise errors.Usage("More arguments needed")
+        creatoropts = configmgr.create
+        ksconf = args.ksfile
 
-        if len(args) != 1:
-            raise errors.Usage("Extra arguments given")
+        if creatoropts['runtime'] == "bootstrap":
+            configmgr._ksconf = ksconf
+            rt_util.bootstrap_mic()
 
-        cfgmgr = configmgr.getConfigMgr()
-        creatoropts = cfgmgr.create
-        ksconf = args[0]
+        recording_pkgs = []
+        if len(creatoropts['record_pkgs']) > 0:
+            recording_pkgs = creatoropts['record_pkgs']
 
-        recording_pkgs = None
         if creatoropts['release'] is not None:
-            recording_pkgs = "name"
-            ksconf = misc.save_ksconf_file(ksconf, creatoropts['release'])
-            name = os.path.splitext(os.path.basename(ksconf))[0]
-            creatoropts['outdir'] = "%s/%s-%s/" % (creatoropts['outdir'], name, creatoropts['release'])
-        cfgmgr._ksconf = ksconf
+            if 'name' not in recording_pkgs:
+                recording_pkgs.append('name')
+            if 'vcs' not in recording_pkgs:
+                recording_pkgs.append('vcs')
+
+        configmgr._ksconf = ksconf
 
         # try to find the pkgmgr
         pkgmgr = None
-        for (key, pcls) in pluginmgr.PluginMgr().get_plugins('backend').iteritems():
-            if key == creatoropts['pkgmgr']:
-                pkgmgr = pcls
-                break
+        backends = pluginmgr.get_plugins('backend')
+        if 'auto' == creatoropts['pkgmgr']:
+            for key in configmgr.prefer_backends:
+                if key in backends:
+                    pkgmgr = backends[key]
+                    break
+        else:
+            for key in backends.keys():
+                if key == creatoropts['pkgmgr']:
+                    pkgmgr = backends[key]
+                    break
 
         if not pkgmgr:
-            raise errors.CreatorError("Can't find package manager: %s" % creatoropts['pkgmgr'])
+            raise errors.CreatorError("Can't find backend: %s, "
+                                      "available choices: %s" %
+                                      (creatoropts['pkgmgr'],
+                                       ','.join(backends.keys())))
 
-        creator = raw.RawImageCreator(creatoropts, pkgmgr)
+        creator = raw.RawImageCreator(creatoropts, pkgmgr, args.compress_image,
+                                      args.generate_bmap, args.fstab_entry)
 
-        if recording_pkgs is not None:
+        if len(recording_pkgs) > 0:
             creator._recording_pkgs = recording_pkgs
 
+        images = ["%s-%s.raw" % (creator.name, disk_name)
+                  for disk_name in creator.get_disk_names()]
+        self.check_image_exists(creator.destdir,
+                                creator.pack_to,
+                                images,
+                                creatoropts['release'])
+
         try:
             creator.check_depend_tools()
             creator.mount(None, creatoropts["cachedir"])
             creator.install()
             creator.configure(creatoropts["repomd"])
+            creator.copy_kernel()
+            creator.copy_attachment()
             creator.unmount()
-            creator.package(creatoropts["outdir"])
+            creator.generate_bmap()
+            creator.package(creatoropts["destdir"])
+            creator.create_manifest()
             if creatoropts['release'] is not None:
-                creator.release_output(ksconf, creatoropts['outdir'], creatoropts['name'], creatoropts['release'])
+                creator.release_output(ksconf, creatoropts['destdir'], creatoropts['release'])
             creator.print_outimage_info()
 
         except errors.CreatorError:
@@ -89,23 +115,51 @@ class RawPlugin(ImagerPlugin):
         finally:
             creator.cleanup()
 
+        #Run script of --run_script after image created
+        if creatoropts['run_script']:
+            cmd = creatoropts['run_script']
+            try:
+                runner.show(cmd)
+            except OSError,err:
+                msger.warning(str(err))
+
+
         msger.info("Finished.")
         return 0
 
     @classmethod
-    def do_chroot(cls, target):
+    def do_chroot(cls, target, cmd=[]):
         img = target
         imgsize = misc.get_file_size(img) * 1024L * 1024L
         partedcmd = fs_related.find_binary_path("parted")
         disk = fs_related.SparseLoopbackDisk(img, imgsize)
         imgmnt = misc.mkdtemp()
-        imgloop = PartitionedMount({'/dev/sdb':disk}, imgmnt, skipformat = True)
+        imgloop = PartitionedMount(imgmnt, skipformat = True)
+        imgloop.add_disk('/dev/sdb', disk)
         img_fstype = "ext3"
 
+        msger.info("Partition Table:")
+        partnum = []
+        for line in runner.outs([partedcmd, "-s", img, "print"]).splitlines():
+            # no use strip to keep line output here
+            if "Number" in line:
+                msger.raw(line)
+            if line.strip() and line.strip()[0].isdigit():
+                partnum.append(line.strip()[0])
+                msger.raw(line)
+
+        rootpart = None
+        if len(partnum) > 1:
+            rootpart = msger.choice("please choose root partition", partnum)
+
         # Check the partitions from raw disk.
-        root_mounted = False
+        # if choose root part, the mark it as mounted
+        if rootpart:
+            root_mounted = True
+        else:
+            root_mounted = False
         partition_mounts = 0
-        for line in runner.outs([partedcmd,"-s",img,"unit","B","print"]).splitlines():
+        for line in runner.outs([ partedcmd, "-s", img, "unit", "B", "print" ]).splitlines():
             line = line.strip()
 
             # Lines that start with number are the partitions,
@@ -117,12 +171,12 @@ class RawPlugin(ImagerPlugin):
             line = line.replace(",","")
 
             # Example of parted output lines that are handled:
-            # Number  Start        End          Size         Type     File system     Flags
+            # Number  Start        End          Size         Type     File system    Flags
             #  1      512B         3400000511B  3400000000B  primary
             #  2      3400531968B  3656384511B  255852544B   primary  linux-swap(v1)
-            #  3      3656384512B  3720347647B  63963136B    primary  fat16           boot, lba
+            #  3      3656384512B  3720347647B  63963136B    primary  fat16          boot, lba
 
-            partition_info = re.split("\s+",line)
+            partition_info = re.split("\s+", line)
 
             size = partition_info[3].split("B")[0]
 
@@ -132,16 +186,19 @@ class RawPlugin(ImagerPlugin):
                 # not recognize properly.
                 # TODO: Can we make better assumption?
                 fstype = "btrfs"
-            elif partition_info[5] in ["ext2","ext3","ext4","btrfs"]:
+            elif partition_info[5] in [ "ext2", "ext3", "ext4", "btrfs" ]:
                 fstype = partition_info[5]
-            elif partition_info[5] in ["fat16","fat32"]:
+            elif partition_info[5] in [ "fat16", "fat32" ]:
                 fstype = "vfat"
             elif "swap" in partition_info[5]:
                 fstype = "swap"
             else:
-                raise errors.CreatorError("Could not recognize partition fs type '%s'." % partition_info[5])
+                raise errors.CreatorError("Could not recognize partition fs type '%s'." %
+                        partition_info[5])
 
-            if not root_mounted and fstype in ["ext2","ext3","ext4","btrfs"]:
+            if rootpart and rootpart == line[0]:
+                mountpoint = '/'
+            elif not root_mounted and fstype in [ "ext2", "ext3", "ext4", "btrfs" ]:
                 # TODO: Check that this is actually the valid root partition from /etc/fstab
                 mountpoint = "/"
                 root_mounted = True
@@ -157,9 +214,11 @@ class RawPlugin(ImagerPlugin):
             else:
                 boot = False
 
-            msger.verbose("Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" % (size, fstype, mountpoint, boot))
+            msger.verbose("Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" %
+                    (size, fstype, mountpoint, boot))
             # TODO: add_partition should take bytes as size parameter.
-            imgloop.add_partition((int)(size)/1024/1024, "/dev/sdb", mountpoint, fstype = fstype, boot = boot)
+            imgloop.add_partition((int)(size)/1024/1024, "/dev/sdb", mountpoint,
+                    fstype = fstype, boot = boot)
 
         try:
             imgloop.mount()
@@ -169,7 +228,14 @@ class RawPlugin(ImagerPlugin):
             raise
 
         try:
-            chroot.chroot(imgmnt, None,  "/bin/env HOME=/root /bin/bash")
+            if len(cmd) != 0:
+                cmdline = ' '.join(cmd)
+            else:
+                cmdline = "/bin/bash"
+            envcmd = fs_related.find_binary_inchroot("env", imgmnt)
+            if envcmd:
+                cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
+            chroot.chroot(imgmnt, None, cmdline)
         except:
             raise errors.CreatorError("Failed to chroot to %s." %img)
         finally:
@@ -180,8 +246,9 @@ class RawPlugin(ImagerPlugin):
         srcimgsize = (misc.get_file_size(srcimg)) * 1024L * 1024L
         srcmnt = misc.mkdtemp("srcmnt")
         disk = fs_related.SparseLoopbackDisk(srcimg, srcimgsize)
-        srcloop = PartitionedMount({'/dev/sdb':disk}, srcmnt, skipformat = True)
+        srcloop = PartitionedMount(srcmnt, skipformat = True)
 
+        srcloop.add_disk('/dev/sdb', disk)
         srcloop.add_partition(srcimgsize/1024/1024, "/dev/sdb", "/", "ext3", boot=False)
         try:
             srcloop.mount()