Add new section 'runscript_out_bootstrap' for kickstart to run script on host pc... 70/313370/14
authorwanchao-xu <wanchao.xu@samsung.com>
Tue, 25 Jun 2024 03:09:37 +0000 (11:09 +0800)
committerwanchao-xu <wanchao.xu@samsung.com>
Fri, 5 Jul 2024 06:52:09 +0000 (14:52 +0800)
Change-Id: I3dbbfb17a1d16b6f6cb9e275563e6c1b49ab701e
Signed-off-by: wanchao-xu <wanchao.xu@samsung.com>
mic/3rdparty/pykickstart/constants.py
mic/3rdparty/pykickstart/parser.py
mic/3rdparty/pykickstart/sections.py
mic/kickstart/__init__.py
mic/rt_util.py
tools/mic

index cb1b685..b0eda5e 100644 (file)
@@ -55,6 +55,7 @@ KS_SCRIPT_PREINSTALL = 3
 KS_SCRIPT_ONERROR = 4
 KS_SCRIPT_RUN = 5
 KS_SCRIPT_UMOUNT = 6
+KS_SCRIPT_RUN_OUT_BOOTSTRAP = 7
 
 KS_WAIT = 0
 KS_REBOOT = 1
index f75dc5b..cd04e23 100644 (file)
@@ -44,7 +44,8 @@ from pykickstart.options import KSOptionParser
 from pykickstart.load import load_to_str
 from pykickstart.sections import PackageSection, PreScriptSection, PreInstallScriptSection, \
                                  PostScriptSection, TracebackScriptSection, OnErrorScriptSection, \
-                                 NullSection, RunScriptSection, PostUmountScriptSection, TpkPackageSection
+                                 NullSection, RunScriptSection, PostUmountScriptSection, \
+                                 RunScriptOutBootstrapSection, TpkPackageSection
 
 from pykickstart.i18n import _
 
@@ -855,6 +856,7 @@ class KickstartParser(object):
         self.registerSection(TracebackScriptSection(self.handler, dataObj=Script))
         self.registerSection(RunScriptSection(self.handler, dataObj=Script))
         self.registerSection(PostUmountScriptSection(self.handler, dataObj=Script))
+        self.registerSection(RunScriptOutBootstrapSection(self.handler, dataObj=Script))
         self.registerSection(PackageSection(self.handler))
         self.registerSection(TpkPackageSection(self.handler))
 
index a452a90..81e32ba 100644 (file)
@@ -33,7 +33,8 @@ import warnings
 from pykickstart.constants import KS_SCRIPT_PRE, KS_SCRIPT_POST, KS_SCRIPT_TRACEBACK, \
                                   KS_SCRIPT_PREINSTALL, KS_SCRIPT_ONERROR, \
                                   KS_MISSING_IGNORE, KS_MISSING_PROMPT, \
-                                  KS_BROKEN_IGNORE, KS_BROKEN_REPORT, KS_SCRIPT_RUN, KS_SCRIPT_UMOUNT
+                                  KS_BROKEN_IGNORE, KS_BROKEN_REPORT, KS_SCRIPT_RUN,\
+                                  KS_SCRIPT_UMOUNT, KS_SCRIPT_RUN_OUT_BOOTSTRAP
 from pykickstart.errors import KickstartError, KickstartParseError, KickstartDeprecationWarning
 from pykickstart.options import KSOptionParser
 from pykickstart.version import FC4, F7, F9, F18, F21, F22, F24, F32, F34, RHEL6, RHEL7, RHEL9, \
@@ -477,6 +478,13 @@ class PostUmountScriptSection(ScriptSection):
                     raise KickstartError("%runscript and %post-umount " \
                                          "can not be defined together")
 
+class RunScriptOutBootstrapSection(ScriptSection):
+    sectionOpen = "%runscript_out_bootstrap"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_RUN_OUT_BOOTSTRAP
+
 class PackageSection(Section):
     sectionOpen = "%packages"
     _title = "Package Selection"
index 049dbb0..17efc18 100755 (executable)
@@ -886,6 +886,14 @@ def get_sign_scripts(ks):
             scripts.append(s)
     return scripts
 
+def get_out_bootstarp_scripts(ks):
+    scripts = []
+    for s in ks.handler.scripts:
+        if s.type != ksparser.constants.KS_SCRIPT_RUN_OUT_BOOTSTRAP:
+            continue
+        scripts.append(s)
+    return scripts
+
 def add_repo(ks, repostr):
     args = repostr.split()
     repoobj = ks.handler.repo.parse(args[1:])
index 5867d93..359a4e0 100644 (file)
@@ -21,9 +21,10 @@ import glob
 import re
 import shutil
 import subprocess
+import tempfile
 import ctypes
 
-from mic import bootstrap, msger
+from mic import bootstrap, msger, kickstart
 from mic.conf import configmgr
 from mic.utils import errors, proxy
 from mic.utils.fs_related import find_binary_path, makedirs
@@ -77,6 +78,45 @@ def mic_py2_in_mic_bootstrap(binpth_in_micbootstrap):
         return True
     return False
 
+# Provide '%runscript_out_bootstrap' section for kickstart, and runscript_out_bootstrap can
+# be run on local PC after image created. The default interpreter is /bin/sh,
+# use '--interpreter' to specify interpreter ('%runscript_out_bootstrap --interpreter=/bin/bash')
+def run_scripts_out_bootstrap(ks, rundir, env=None):
+    if kickstart.get_out_bootstarp_scripts(ks)==[]:
+        return
+
+    msger.info("Running scripts out bootstrap ...")
+    for s in kickstart.get_out_bootstarp_scripts(ks):
+        (fd, path) = tempfile.mkstemp(prefix="ks-runscript-out-bootstrap-")
+        s.script = s.script.replace("\r", "")
+        os.write(fd, s.script.encode())
+        if s.interp == '/bin/sh' or s.interp == '/bin/bash':
+            os.write(fd, '\n'.encode())
+            os.write(fd, 'exit 0\n'.encode())
+        os.close(fd)
+        os.chmod(path, 0o700)
+
+        oldoutdir = os.getcwd()
+        if os.path.exists(rundir):
+            os.chdir(rundir)
+        try:
+            try:
+                p = subprocess.Popen([s.interp, path],
+                                     env = env,
+                                     stdout = subprocess.PIPE,
+                                     stderr = subprocess.STDOUT)
+                while p.poll() == None:
+                    msger.info(p.stdout.readline().strip().decode())
+                if p.returncode != 0:
+                    raise errors.CreatorError("Failed to execute script out bootstrap "
+                                              "with '%s'" % (s.interp))
+            except OSError as msg:
+                    raise errors.CreatorError("Failed to execute script out bootstrap "
+                                              "with '%s' : %s" % (s.interp, msg))
+        finally:
+            os.chdir(oldoutdir)
+            os.unlink(path)
+
 def bootstrap_mic(argv=None):
     def mychroot():
         os.chroot(rootdir)
@@ -146,6 +186,8 @@ def bootstrap_mic(argv=None):
         value,tb = sys.exc_info()[1:]
         raise errors.CreatorError((value,tb))
     else:
+        if not ret:
+            run_scripts_out_bootstrap(cropts['ks'], cropts['outdir'])
         sys.exit(ret)
     finally:
         bsenv.cleanup()
index ad2c8d5..df8fe53 100755 (executable)
--- a/tools/mic
+++ b/tools/mic
@@ -137,7 +137,7 @@ def create_parser(parser):
                                 dest='interactive', default=True,
                                help='interactive output')
     parent_parser.add_argument('--run_script', action='store', dest='run_script',
-                                                   default=None, help='Run script on local PC after image created')
+                                                   default=None, help='Run script on mic bootstrap after image created')
     parent_parser.add_argument('--tpk_install', action='store', dest='tpk_install',
                                                                        default=None, help='Copy tpk file to /usr/apps/.preload-tpk')
     parent_parser.add_argument('--rpm-debug', action='store_true', dest='rpm_debug', help='Set debug mode for rpm install')