From: wanchao-xu Date: Tue, 25 Jun 2024 03:09:37 +0000 (+0800) Subject: Add new section 'runscript_out_bootstrap' for kickstart to run script on host pc... X-Git-Tag: accepted/tools/devbase/tools/20250527.103804~7^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F70%2F313370%2F14;p=tools%2Fmic.git Add new section 'runscript_out_bootstrap' for kickstart to run script on host pc after image created. Change-Id: I3dbbfb17a1d16b6f6cb9e275563e6c1b49ab701e Signed-off-by: wanchao-xu --- diff --git a/mic/3rdparty/pykickstart/constants.py b/mic/3rdparty/pykickstart/constants.py index cb1b685..b0eda5e 100644 --- a/mic/3rdparty/pykickstart/constants.py +++ b/mic/3rdparty/pykickstart/constants.py @@ -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 diff --git a/mic/3rdparty/pykickstart/parser.py b/mic/3rdparty/pykickstart/parser.py index f75dc5b..cd04e23 100644 --- a/mic/3rdparty/pykickstart/parser.py +++ b/mic/3rdparty/pykickstart/parser.py @@ -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)) diff --git a/mic/3rdparty/pykickstart/sections.py b/mic/3rdparty/pykickstart/sections.py index a452a90..81e32ba 100644 --- a/mic/3rdparty/pykickstart/sections.py +++ b/mic/3rdparty/pykickstart/sections.py @@ -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" diff --git a/mic/kickstart/__init__.py b/mic/kickstart/__init__.py index 049dbb0..17efc18 100755 --- a/mic/kickstart/__init__.py +++ b/mic/kickstart/__init__.py @@ -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:]) diff --git a/mic/rt_util.py b/mic/rt_util.py index 5867d93..359a4e0 100644 --- a/mic/rt_util.py +++ b/mic/rt_util.py @@ -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() diff --git a/tools/mic b/tools/mic index ad2c8d5..df8fe53 100755 --- 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')