# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-import os, sys
+import os
+import sys
import stat
import tempfile
import shutil
from mic.archive import get_archive_suffixes
from mic.conf import configmgr
from mic.utils.grabber import myurlgrab
-#post script max run time
+# post script max run time
MAX_RUN_TIME = 120
+
class BaseImageCreator(object):
"""Installs a system to a chroot directory.
def __del__(self):
self.cleanup()
- def __init__(self, createopts = None, pkgmgr = None):
+ def __init__(self, createopts=None, pkgmgr=None):
"""Initialize an ImageCreator instance.
ks -- a pykickstart.KickstartParser instance; this instance will be
if createopts:
# Mapping table for variables that have different names.
- optmap = {"pkgmgr" : "pkgmgr_name",
- "arch" : "target_arch",
- "local_pkgs_path" : "_local_pkgs_path",
- "copy_kernel" : "_need_copy_kernel",
- "strict_mode" : "strict_mode",
- }
+ optmap = {"pkgmgr": "pkgmgr_name",
+ "arch": "target_arch",
+ "local_pkgs_path": "_local_pkgs_path",
+ "copy_kernel": "_need_copy_kernel",
+ "strict_mode": "strict_mode",
+ }
# update setting from createopts
for key in list(createopts.keys()):
self._dep_checks.append("mkfs.btrfs")
break
if part.cpioopts:
- if part.fstype == "cpio":
+ if part.fstype == "cpio":
part.fstype = "ext4"
else:
- raise KsError("The '--fstype' in ks file need to set 'cpio' when you want to generate image by cpio.")
+ raise KsError(
+ "The '--fstype' in ks file need to set 'cpio' when you want to generate image by cpio.")
if len(self.ks.handler.partition.partitions) > 1:
self.multiple_partitions = True
self._dep_checks.append("qemu-arm-static")
if os.path.exists("/proc/sys/vm/vdso_enabled"):
- vdso_fh = open("/proc/sys/vm/vdso_enabled","r")
+ vdso_fh = open("/proc/sys/vm/vdso_enabled", "r")
vdso_value = vdso_fh.read().strip()
vdso_fh.close()
if (int)(vdso_value) == 1:
msger.warning("vdso is enabled on your host, which might "
- "cause problems with arm emulations.\n"
- "\tYou can disable vdso with following command before "
- "starting image build:\n"
- "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
+ "cause problems with arm emulations.\n"
+ "\tYou can disable vdso with following command before "
+ "starting image build:\n"
+ "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
elif self.target_arch == "mipsel":
for dep in self._dep_checks:
if dep == "extlinux":
self._dep_checks.append("qemu-mipsel-static")
if os.path.exists("/proc/sys/vm/vdso_enabled"):
- vdso_fh = open("/proc/sys/vm/vdso_enabled","r")
+ vdso_fh = open("/proc/sys/vm/vdso_enabled", "r")
vdso_value = vdso_fh.read().strip()
vdso_fh.close()
if (int)(vdso_value) == 1:
msger.warning("vdso is enabled on your host, which might "
- "cause problems with mipsel emulations.\n"
- "\tYou can disable vdso with following command before "
- "starting image build:\n"
- "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
+ "cause problems with mipsel emulations.\n"
+ "\tYou can disable vdso with following command before "
+ "starting image build:\n"
+ "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
# make sure the specified tmpdir and cachedir exist
if not os.path.exists(self.tmpdir):
if not os.path.exists(self.cachedir):
os.makedirs(self.cachedir)
-
#
# Properties
#
+
def __get_instroot(self):
if self.__builddir is None:
raise CreatorError("_instroot is not valid before calling mount()")
"""
-
#
# Hooks for subclasses
#
- def _mount_instroot(self, base_on = None):
+ def _mount_instroot(self, base_on=None):
"""Mount or prepare the install root directory.
This is the hook where subclasses may prepare the install root by e.g.
"""Save the list or content of installed packages to file.
"""
pkgs = list(self._pkgs_content.keys())
- pkgs.sort() # inplace op
+ pkgs.sort() # inplace op
if not os.path.exists(destdir):
os.makedirs(destdir)
content = None
if 'vcs' in self._recording_pkgs:
- vcslst = ["%s %s" % (k, v) for (k, v) in list(self._pkgs_vcsinfo.items())]
+ vcslst = ["%s %s" % (k, v)
+ for (k, v) in list(self._pkgs_vcsinfo.items())]
content = '\n'.join(sorted(vcslst))
elif 'name' in self._recording_pkgs:
content = '\n'.join(pkgs)
f = open(licensefile, "w")
f.write('Summary:\n')
- for license in reversed(sorted(self._pkgs_license, key=\
- lambda license: len(self._pkgs_license[license]))):
- f.write(" - %s: %s\n" \
+ for license in reversed(sorted(self._pkgs_license, key=lambda license: len(self._pkgs_license[license]))):
+ f.write(" - %s: %s\n"
% (license, len(self._pkgs_license[license])))
f.write('\nDetails:\n')
- for license in reversed(sorted(self._pkgs_license, key=\
- lambda license: len(self._pkgs_license[license]))):
+ for license in reversed(sorted(self._pkgs_license, key=lambda license: len(self._pkgs_license[license]))):
f.write(" - %s:\n" % (license))
for pkg in sorted(self._pkgs_license[license]):
f.write(" - %s\n" % (pkg))
if self._local_pkgs_path:
if os.path.isdir(self._local_pkgs_path):
return glob.glob(
- os.path.join(self._local_pkgs_path, '*.rpm'))
+ os.path.join(self._local_pkgs_path, '*.rpm'))
elif os.path.splitext(self._local_pkgs_path)[-1] == '.rpm':
return [self._local_pkgs_path]
A sensible default implementation is provided.
"""
- s = "/dev/root / %s %s 0 0\n" \
- % (self._fstype,
- "defaults,noatime" if not self._fsopts else self._fsopts)
+ s = "/dev/root / %s %s 0 0\n" \
+ % (self._fstype,
+ "defaults,noatime" if not self._fsopts else self._fsopts)
s += self._get_fstab_special()
return s
value = str(value)
name = self.installerfw_prefix + ("PART%d_" % pnum) + prop
- return { name : value }
+ return {name: value}
def _get_post_scripts_env(self, in_chroot):
"""Return an environment dict for %post scripts.
return ret
-
#
# Helpers for subclasses
#
+
def _do_bindmounts(self):
"""Mount various system directories onto _instroot.
os.chroot(self._instroot)
os.chdir("/")
- def _mkdtemp(self, prefix = "tmp-"):
+ def _mkdtemp(self, prefix="tmp-"):
"""Create a temporary directory.
This method may be used by subclasses to create a temporary directory
"""
self.__ensure_builddir()
- return tempfile.mkdtemp(dir = self.__builddir, prefix = prefix)
+ return tempfile.mkdtemp(dir=self.__builddir, prefix=prefix)
- def _mkstemp(self, prefix = "tmp-"):
+ def _mkstemp(self, prefix="tmp-"):
"""Create a temporary file.
This method may be used by subclasses to create a temporary file
"""
self.__ensure_builddir()
- return tempfile.mkstemp(dir = self.__builddir, prefix = prefix)
+ return tempfile.mkstemp(dir=self.__builddir, prefix=prefix)
- def _mktemp(self, prefix = "tmp-"):
+ def _mktemp(self, prefix="tmp-"):
"""Create a temporary file.
This method simply calls _mkstemp() and closes the returned file
os.close(f)
return path
-
#
# Actual implementation
#
+
def __ensure_builddir(self):
if not self.__builddir is None:
return
self.workdir = os.path.join(self.tmpdir, "build")
if not os.path.exists(self.workdir):
os.makedirs(self.workdir)
- self.__builddir = tempfile.mkdtemp(dir = self.workdir,
- prefix = "imgcreate-")
+ self.__builddir = tempfile.mkdtemp(dir=self.workdir,
+ prefix="imgcreate-")
except OSError as msg:
raise CreatorError("Failed create build directory in %s: %s" %
(self.tmpdir, msg))
- def get_cachedir(self, cachedir = None):
+ def get_cachedir(self, cachedir=None):
if self.cachedir:
return self.cachedir
"""Create a minimal /dev so that we don't corrupt the host /dev"""
origumask = os.umask(0000)
devices = (('null', 1, 3, 0o666),
- ('urandom',1, 9, 0o666),
+ ('urandom', 1, 9, 0o666),
('random', 1, 8, 0o666),
('full', 1, 7, 0o666),
('ptmx', 5, 2, 0o666),
if not os.path.exists(self._instroot + "/dev/" + node):
os.mknod(self._instroot + "/dev/" + node,
perm | stat.S_IFCHR,
- os.makedev(major,minor))
+ os.makedev(major, minor))
for (src, dest) in links:
if not os.path.exists(self._instroot + dest):
runner.show('umount -l %s' % self.workdir)
def cp_tpk(self):
- #Add tpk-install option
+ # Add tpk-install option
createopts = configmgr.create
if createopts['tpk_install']:
path = createopts['tpk_install']
for f in file_list:
sub = os.path.splitext(f)[1]
if sub != ".tpk":
- raise CreatorError("Not all files in the path: "+path +" is tpk")
+ raise CreatorError(
+ "Not all files in the path: "+path + " is tpk")
tpk_dir = "/usr/apps/.preload-tpk"
fs.makedirs(self._instroot + "/usr/apps")
fs.makedirs(self._instroot + tpk_dir)
for f in file_list:
- shutil.copy(path+"/"+f,self._instroot + tpk_dir)
+ shutil.copy(path+"/"+f, self._instroot + tpk_dir)
- def mount(self, base_on = None, cachedir = None):
+ def mount(self, base_on=None, cachedir=None):
"""Setup the target filesystem in preparation for an install.
This function sets up the filesystem which the ImageCreator will
fs.makedirs(self._instroot + d)
if self.target_arch and self.target_arch.startswith("arm") or \
- self.target_arch == "aarch64":
+ self.target_arch == "aarch64":
self.qemu_emulators = misc.setup_qemu_emulator(self._instroot,
- self.target_arch)
+ self.target_arch)
self.get_cachedir(cachedir)
("/proc/sys/fs/binfmt_misc", None),
("/dev/pts", None)]:
self.__bindmounts.append(
- fs.BindChrootMount(
- f, self._instroot, dest))
+ fs.BindChrootMount(
+ f, self._instroot, dest))
self._do_bindmounts()
os.unlink(self._instroot + "/etc/mtab")
os.symlink("../proc/mounts", self._instroot + "/etc/mtab")
- #self.__write_fstab()
+ # self.__write_fstab()
# get size of available space in 'instroot' fs
self._root_fs_avail = misc.get_filesystem_avail(self._instroot)
try:
instroot_pdir = os.path.dirname(self._instroot + self._instroot)
if os.path.exists(instroot_pdir):
- shutil.rmtree(instroot_pdir, ignore_errors = True)
+ shutil.rmtree(instroot_pdir, ignore_errors=True)
yumlibdir = self._instroot + "/var/lib/yum"
if os.path.exists(yumlibdir):
- shutil.rmtree(yumlibdir, ignore_errors = True)
+ shutil.rmtree(yumlibdir, ignore_errors=True)
except OSError:
pass
# reset settings of popup dialog in Ubuntu(s)
misc.unhide_loopdev_presentation()
-
def cleanup(self):
"""Unmounts the target filesystem and deletes temporary files.
self.unmount()
- shutil.rmtree(self.__builddir, ignore_errors = True)
+ shutil.rmtree(self.__builddir, ignore_errors=True)
self.__builddir = None
self.__clean_tmpdir()
return True
else:
continue
-
+
return False
def showErrorInfo(filepath):
if 'debuginfo' in self.install_pkgs:
pkg_manager.install_debuginfo = True
-
for repo in kickstart.get_repos(self.ks, repo_urls, self.ignore_ksrepo):
(name, baseurl, mirrorlist, inc, exc,
proxy, proxy_username, proxy_password, debuginfo,
ssl_verify = get_ssl_verify(ssl_verify)
yr = pkg_manager.addRepository(name, baseurl, mirrorlist, proxy,
- proxy_username, proxy_password, inc, exc, ssl_verify,
- nocache, cost, priority)
+ proxy_username, proxy_password, inc, exc, ssl_verify,
+ nocache, cost, priority)
if kickstart.exclude_docs(self.ks):
rpm.addMacro("_excludedocs", "1")
self.__select_packages(pkg_manager)
self.__select_groups(pkg_manager)
self.__deselect_packages(pkg_manager)
- #self.__localinst_packages(pkg_manager)
+ # self.__localinst_packages(pkg_manager)
self.__check_packages(pkg_manager)
- BOOT_SAFEGUARD = 256 * 1024 * 1024 # 256M
+ BOOT_SAFEGUARD = 256 * 1024 * 1024 # 256M
checksize = self._root_fs_avail
if checksize:
checksize -= BOOT_SAFEGUARD
pkg_manager.runInstall(checksize)
except CreatorError as e:
raise
- except KeyboardInterrupt:
+ except KeyboardInterrupt:
raise
else:
self._pkgs_content = pkg_manager.getAllContent()
if checkScriptletError(self._instroot + "/tmp/.postscript/error/", "_error"):
showErrorInfo(self._instroot + "/tmp/.preload_install_error")
raise CreatorError('scriptlet errors occurred')
-
+
# hook post install
self.postinstall()
for pkg in tpk_pkgs:
flag = 0
for tpk_repo in tpk_repoList:
- if hasattr(tpk_repo,'baseurl') and tpk_repo.baseurl.startswith("file:"):
- tpk_repourl = tpk_repo.baseurl.replace('file:','')
+ if hasattr(tpk_repo, 'baseurl') and tpk_repo.baseurl.startswith("file:"):
+ tpk_repourl = tpk_repo.baseurl.replace('file:', '')
tpk_repourl = "/%s" % tpk_repourl.lstrip('/')
- tpk_pkgpath = tpk_repourl + "/"+ pkg
+ tpk_pkgpath = tpk_repourl + "/" + pkg
if os.path.isfile(tpk_pkgpath):
- shutil.copy(tpk_pkgpath,self._instroot + tpk_dir)
+ shutil.copy(tpk_pkgpath, self._instroot + tpk_dir)
flag = 1
break
- elif hasattr(tpk_repo,'baseurl'):
+ elif hasattr(tpk_repo, 'baseurl'):
url = tpk_repo.baseurl.join(pkg)
filename = self._instroot+tpk_dir+"/"+pkg
if tpk_repo.baseurl.startswith("http:"):
- import urllib.request, urllib.parse, urllib.error
+ import urllib.request
+ import urllib.parse
+ import urllib.error
status = urllib.request.urlopen(url).code
if status == 200:
filename = myurlgrab(url.full, filename, None)
break
elif status == 404 or status == None:
continue
- #url is ok, then download, url wrong, check other url.
- elif tpk_repo.baseurl.startswith("https:") :
+ # url is ok, then download, url wrong, check other url.
+ elif tpk_repo.baseurl.startswith("https:"):
try:
flag = 1
filename = myurlgrab(url.full, filename, None)
return env
def run_sign_scripts(self):
- if kickstart.get_sign_scripts(self.ks)==[]:
+ if kickstart.get_sign_scripts(self.ks) == []:
return
msger.info("Running sign scripts ...")
if os.path.exists(self._instroot + "/tmp"):
shutil.rmtree(self._instroot + "/tmp")
- os.mkdir (self._instroot + "/tmp", 0o755)
+ os.mkdir(self._instroot + "/tmp", 0o755)
for s in kickstart.get_sign_scripts(self.ks):
- (fd, path) = tempfile.mkstemp(prefix = "ks-runscript-",
- dir = self._instroot + "/tmp")
+ (fd, path) = tempfile.mkstemp(prefix="ks-runscript-",
+ dir=self._instroot + "/tmp")
s.script = s.script.replace("\r", "")
os.write(fd, s.script)
if s.interp == '/bin/sh' or s.interp == '/bin/bash':
try:
try:
p = subprocess.Popen([s.interp, path],
- env = env,
- stdout = subprocess.PIPE,
- stderr = subprocess.STDOUT)
+ env=env,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
while p.poll() == None:
msger.info(p.stdout.readline().strip())
if p.returncode != 0:
msger.info("Running post scripts ...")
if os.path.exists(self._instroot + "/tmp"):
shutil.rmtree(self._instroot + "/tmp")
- os.mkdir (self._instroot + "/tmp", 0o755)
+ os.mkdir(self._instroot + "/tmp", 0o755)
for s in kickstart.get_post_scripts(self.ks):
- (fd, path) = tempfile.mkstemp(prefix = "ks-postscript-",
- dir = self._instroot + "/tmp")
+ (fd, path) = tempfile.mkstemp(prefix="ks-postscript-",
+ dir=self._instroot + "/tmp")
s.script = s.script.replace("\r", "")
os.write(fd, s.script)
try:
try:
p = subprocess.Popen([s.interp, script],
- preexec_fn = preexec,
- env = env,
- stdout = subprocess.PIPE,
- stderr = subprocess.STDOUT)
+ preexec_fn=preexec,
+ env=env,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
while p.poll() == None:
- msger.info(p.stdout.readline().strip())
+ msger.info(p.stdout.readline().strip())
end_time = time.time()
if (end_time - start_time)/60 > MAX_RUN_TIME:
- raise CreatorError("Your post script is executed more than "+MAX_RUN_TIME+"mins, please check it!")
+ raise CreatorError(
+ "Your post script is executed more than "+MAX_RUN_TIME+"mins, please check it!")
if p.returncode != 0:
raise CreatorError("Failed to execute %%post script "
"with '%s'" % (s.interp))
fs.makedirs(self._instroot + gpgkeydir)
for repo in repodata:
if repo["repokey"]:
- repokey = gpgkeydir + "/RPM-GPG-KEY-%s" % repo["name"]
+ repokey = gpgkeydir + "/RPM-GPG-KEY-%s" % repo["name"]
shutil.copy(repo["repokey"], self._instroot + repokey)
- def configure(self, repodata = None):
+ def configure(self, repodata=None):
"""Configure the system image according to the kickstart.
This method applies the (e.g. keyboard or network) configuration
kickstart.LanguageConfig(self._instroot).apply(ksh.lang)
kickstart.KeyboardConfig(self._instroot).apply(ksh.keyboard)
kickstart.TimezoneConfig(self._instroot).apply(ksh.timezone)
- #kickstart.AuthConfig(self._instroot).apply(ksh.authconfig)
+ # kickstart.AuthConfig(self._instroot).apply(ksh.authconfig)
kickstart.FirewallConfig(self._instroot).apply(ksh.firewall)
kickstart.UserConfig(self._instroot).apply(ksh.user)
kickstart.RootPasswordConfig(self._instroot).apply(ksh.rootpw)
kickstart.RPMMacroConfig(self._instroot).apply(self.ks)
kickstart.DesktopConfig(self._instroot).apply(ksh.desktop)
self.__save_repo_keys(repodata)
- kickstart.MoblinRepoConfig(self._instroot).apply(ksh.repo, repodata, self.repourl)
+ kickstart.MoblinRepoConfig(self._instroot).apply(
+ ksh.repo, repodata, self.repourl)
except:
msger.warning("Failed to apply configuration to image")
raise
"""
if launch:
msger.info("Launching shell. Exit to continue.")
- subprocess.call(["/bin/bash"], preexec_fn = self._chroot)
+ subprocess.call(["/bin/bash"], preexec_fn=self._chroot)
def do_genchecksum(self, image_name):
if not self._genchecksum:
cpiocmd = fs.find_binary_path('cpio')
if cpiocmd:
oldoutdir = os.getcwd()
- os.chdir(os.path.join(self._instroot, item['mountpoint'].lstrip('/')))
+ os.chdir(os.path.join(self._instroot,
+ item['mountpoint'].lstrip('/')))
# find . | cpio --create --'format=newc' | gzip > ../ramdisk.img
- runner.show('find . | cpio --create %s | gzip > %s' % (item['cpioopts'], tmp_cpio_imgfile))
+ runner.show('find . | cpio --create %s | gzip > %s' %
+ (item['cpioopts'], tmp_cpio_imgfile))
os.chdir(oldoutdir)
except OSError as msg:
raise CreatorError("Create image by cpio error: %s" % msg)
for item in self._instloops:
if item['cpioopts']:
tmp_cpio = self.__builddir + "/tmp-cpio"
- msger.info("Copy cpio image from %s to %s." %(tmp_cpio, self._imgdir))
+ msger.info("Copy cpio image from %s to %s." %
+ (tmp_cpio, self._imgdir))
try:
- shutil.copyfile(os.path.join(tmp_cpio, item['name']),os.path.join(self._imgdir, item['name']))
+ shutil.copyfile(os.path.join(tmp_cpio, item['name']), os.path.join(
+ self._imgdir, item['name']))
except IOError:
raise CreatorError("Copy cpio image error")
os.remove(os.path.join(tmp_cpio, item['name']))
if not os.listdir(tmp_cpio):
shutil.rmtree(tmp_cpio, ignore_errors=True)
- def package(self, destdir = "."):
+ def package(self, destdir="."):
"""Prepares the created image for final delivery.
In its simplest form, this method merely copies the install root to the
# For image formats with two or multiple image files, it will be
# better to put them under a directory
if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"):
- destdir = os.path.join(destdir, "%s-%s" \
+ destdir = os.path.join(destdir, "%s-%s"
% (self.name, self.image_format))
msger.debug("creating destination dir: %s" % destdir)
fs.makedirs(destdir)
for tool in self._dep_checks:
fs.find_binary_path(tool)
- def package_output(self, image_format, destdir = ".", package="none"):
+ def package_output(self, image_format, destdir=".", package="none"):
if not package or package == "none":
return
destdir = os.path.abspath(os.path.expanduser(destdir))
(pkg, comp) = os.path.splitext(package)
if comp:
- comp=comp.lstrip(".")
+ comp = comp.lstrip(".")
if pkg == "tar":
if comp:
for file in self.outimage:
msger.info("adding %s to %s" % (file, dst))
tar.add(file,
- arcname=os.path.join("%s-%s" \
- % (self.name, image_format),
- os.path.basename(file)))
+ arcname=os.path.join("%s-%s"
+ % (self.name, image_format),
+ os.path.basename(file)))
if os.path.isdir(file):
- shutil.rmtree(file, ignore_errors = True)
+ shutil.rmtree(file, ignore_errors=True)
else:
os.remove(file)
outimages.append("%s/%s" % (destdir, hash_name))
hash_dict = {
- 'MD5SUMS' : misc.get_md5sum,
- 'SHA1SUMS' : misc.get_sha1sum,
- 'SHA256SUMS' : misc.get_sha256sum
- }
+ 'MD5SUMS': misc.get_md5sum,
+ 'SHA1SUMS': misc.get_sha1sum,
+ 'SHA256SUMS': misc.get_sha256sum
+ }
for k, v in list(hash_dict.items()):
generate_hashsum(k, v)
pass
def get_pkg_manager(self):
- return self.pkgmgr(target_arch = self.target_arch,
- instroot = self._instroot,
- cachedir = self.cachedir,
- strict_mode = self.strict_mode)
+ return self.pkgmgr(target_arch=self.target_arch,
+ instroot=self._instroot,
+ cachedir=self.cachedir,
+ strict_mode=self.strict_mode)
def create_manifest(self):
def get_pack_suffix():