support both %runscript and %post-umount to perform scripts before packaging
authorDohyung Kim <dohyung2.kim@samsung.com>
Tue, 21 Nov 2017 05:55:28 +0000 (14:55 +0900)
committermao xiaojuan <xiaojuan.mao@samsung.com>
Fri, 26 Jan 2018 07:53:51 +0000 (15:53 +0800)
- add %post-umount section which behaves the same as %runscript
  (if both %runscript and %post-umount are defined then KickstartError occurs)
- move post umount scripts from /var/tmp/post_umount_scripts/ on image to host
- post umount scripts can be use UMOUNT_SCRIPTS_PATH env variable
  (UMOUNT_SCRIPTS_PATH: directory path where post umount scripts are located on host)

Change-Id: Ib88c103f0d3e84c067d0d6683f406a5cac92739a
Signed-off-by: Dohyung Kim <dohyung2.kim@samsung.com>
mic/3rdparty/pykickstart/constants.py
mic/3rdparty/pykickstart/parser.py
mic/3rdparty/pykickstart/sections.py
mic/imager/loop.py
mic/kickstart/__init__.py

index 92f8325..050d124 100644 (file)
@@ -40,6 +40,7 @@ KS_SCRIPT_PRE = 0
 KS_SCRIPT_POST = 1
 KS_SCRIPT_TRACEBACK = 2
 KS_SCRIPT_RUN = 3
+KS_SCRIPT_UMOUNT = 4
 
 KS_WAIT = 0
 KS_REBOOT = 1
index cf4db4c..02a0f32 100644 (file)
@@ -204,6 +204,8 @@ class Script(KickstartObject):
             retval += '\n%traceback'
         elif self.type == constants.KS_SCRIPT_RUN:
             retval += '\n%runscript'
+        elif self.type == constants.KS_SCRIPT_UMOUNT:
+            retval += '\n%post-umount'
 
         if self.interp != "/bin/sh" and self.interp != "":
             retval += " --interpreter=%s" % self.interp
@@ -702,4 +704,5 @@ class KickstartParser:
         self.registerSection(PostScriptSection(self.handler, dataObj=Script))
         self.registerSection(TracebackScriptSection(self.handler, dataObj=Script))
         self.registerSection(RunScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PostUmountScriptSection(self.handler, dataObj=Script))
         self.registerSection(PackageSection(self.handler))
index 51cba3b..9452767 100644 (file)
@@ -30,6 +30,7 @@ is necessary is to create a new subclass of Section and call
 parser.registerSection with an instance of your new class.
 """
 from constants import *
+from errors import *
 from options import KSOptionParser
 from version import *
 
@@ -196,9 +197,34 @@ class TracebackScriptSection(ScriptSection):
 
 class RunScriptSection(ScriptSection):
     sectionOpen = "%runscript"
+
     def _resetScript(self):
         ScriptSection._resetScript(self)
         self._script["type"] = KS_SCRIPT_RUN
+
+    def finalize(self):
+        ScriptSection.finalize(self)
+        if self.handler:
+            for s in self.handler.scripts:
+                if s.type == KS_SCRIPT_UMOUNT:
+                    raise KickstartError("%runscript and %post-umount " \
+                                         "can not be defined together")
+
+class PostUmountScriptSection(ScriptSection):
+    sectionOpen = "%post-umount"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_UMOUNT
+
+    def finalize(self):
+        ScriptSection.finalize(self)
+        if self.handler:
+            for s in self.handler.scripts:
+                if s.type == KS_SCRIPT_RUN:
+                    raise KickstartError("%runscript and %post-umount " \
+                                         "can not be defined together")
+
 class PackageSection(Section):
     sectionOpen = "%packages"
 
index fd4830c..e9815c9 100755 (executable)
@@ -180,6 +180,7 @@ class LoopImageCreator(BaseImageCreator):
             self._instloops = []
 
         self._imgdir = None
+        self._umountdir = None
 
         if self.ks:
             self.__image_size = kickstart.get_image_size(self.ks,
@@ -404,6 +405,15 @@ class LoopImageCreator(BaseImageCreator):
             except:
                 pass
 
+    def _get_sign_scripts_env(self):
+        env = BaseImageCreator._get_sign_scripts_env(self)
+
+        # Directory path of %post-umounts scripts
+        if self._umountdir:
+            env['UMOUNT_SCRIPTS_PATH'] = str(self._umountdir)
+
+        return env
+
     def _stage_final_image(self):
 
         if self.pack_to or self.shrink_image:
@@ -505,6 +515,23 @@ class LoopImageCreator(BaseImageCreator):
             msger.verbose("Move attachment %s to %s" % (item, dpath))
             shutil.move(item, dpath)
 
+    def move_post_umount_scripts(self):
+        scripts_dir = self._instroot + "/var/tmp/post_umount_scripts"
+        if not os.path.exists(scripts_dir):
+            return
+        self._umountdir = self._mkdtemp("umount")
+        msger.info("Moving post umount scripts...")
+        for item in os.listdir(scripts_dir):
+            spath = os.path.join(scripts_dir, item)
+            dpath = os.path.join(self._umountdir, item)
+            msger.verbose("Move post umount scripts %s to %s" % (spath, dpath))
+            shutil.move(spath, dpath)
+        shutil.rmtree(scripts_dir)
+
+    def postinstall(self):
+        BaseImageCreator.postinstall(self)
+        self.move_post_umount_scripts()
+
     def create_manifest(self):
         if self.compress_image:
             self.image_files.update({'compress': self.compress_image})
index 76cc525..bc97e2e 100755 (executable)
@@ -823,10 +823,11 @@ def get_post_scripts(ks):
 def get_sign_scripts(ks):
     scripts = []
     for s in ks.handler.scripts:
-        if s.type != ksparser.KS_SCRIPT_RUN:
-            continue
-        scripts.append(s)
+        if (s.type == ksparser.KS_SCRIPT_RUN or \
+            s.type == ksparser.KS_SCRIPT_UMOUNT):
+            scripts.append(s)
     return scripts
+
 def add_repo(ks, repostr):
     args = repostr.split()
     repoobj = ks.handler.repo.parse(args[1:])