/usr/share/pyshared/mic/appcreate/nand.py is in mic2 0.24.12-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | #
# Copyright (c) 2009 Intel Corporation
#
# 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
#
# 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.
#
# nand.py : NandImageCreator class for creating NAND images
#
import os
import os.path
import stat
import glob
import shutil
import subprocess
import time
from mic.imgcreate.errors import *
from mic.imgcreate.fs import *
from mic.imgcreate.creator import *
from mic.appcreate.appliance import *
from mic.imgcreate.pkgmanagers import *
class NandImageCreator(ApplianceImageCreator):
def __init__(self, ks, name, initrd_url = None, initrd_path = None,
kernel_url = None, kernel_path = None,
kernel_rpm_url = None,
kernel_rpm_path = None,
bootimg_only = None):
self.__initrd_url = initrd_url
self.__initrd_path = initrd_path
self.__kernel_url = kernel_url
self.__kernel_path = kernel_path
self.__kernel_rpm_url = kernel_rpm_url
self.__kernel_rpm_path = kernel_rpm_path
self.__bootimg_only = bootimg_only
# call parent __init__, but the last two parameters just place holder
ApplianceImageCreator.__init__(self, ks, name, 'bin', 1, 1)
self.__modules = ["=nand", "=mrst"]
self.__modules.extend(kickstart.get_modules(self.ks))
self.__override_initrd = True
if self.__kernel_url or \
self.__initrd_url or \
self.__kernel_rpm_url:
self._dep_checks.append("curl")
#
# Private helper functions
#
""" Copy boot related files from instroot to outdir """
def __copy_boot_files(self, version, index):
""" The needed files are vmlinuz, initrd and bootstub. """
bootdir = self._instroot + "/boot"
bootstub_path = None
for subpath in ('boot', 'usr/share/bootstub'):
bootstub_path = os.path.join(self._instroot, subpath, 'bootstub')
if os.path.exists(bootstub_path):
break
if not bootstub_path:
raise CreatorError("Lost required bootstub file")
""" Copy bootstub file """
try:
shutil.copyfile(bootstub_path, self._outdir + "/bootstub")
except IOError, e:
# failed to copy needed files
raise CreatorError("Unable to copy boot files %s" % e)
""" Following the rules to fetch kernel and initrd:
1. If specified url in cmdline, fetch it
1.1 If failed, raise exception
2. or if path provided, copy it in
2.1 If cannot copy, raise exception
3. or else, copy from bootdir
3.1 If cannot copy, raise exception
"""
""" Copy kernel image file.
If need to override the kernel image from repo, use another one from
cmdline parameter instead.
"""
kernel_path = os.path.join(self._outdir, "vmlinuz" + index)
if self.__kernel_url:
print "Retrieving kernel from %s ########### " % self.__kernel_url,
sys.stdout.flush()
rc = subprocess.call(["curl", "-s", "-o", kernel_path, self.__kernel_url])
if rc != 0 or not os.path.exists(kernel_path):
print '[FAILED]'
raise CreatorError("Unable to fetch kernel from %s" % self.__kernel_url)
print '[OK]'
else:
src_kernel_path = self.__kernel_path or \
os.path.join(bootdir, "vmlinuz-" + version)
try:
shutil.copyfile(src_kernel_path, kernel_path)
except IOError, e:
# failed to copy needed files
raise CreatorError("Unable to copy boot files %s" % e)
""" Copy initrd image file. """
initrd_path = os.path.join(self._outdir, "initrd" + index + ".img")
if self.__initrd_url:
print "Retrieving initrd from %s ########### " % self.__initrd_url,
sys.stdout.flush()
rc = subprocess.call(["curl", "-s", "-o", initrd_path, self.__initrd_url])
if rc != 0 or not os.path.exists(initrd_path):
print '[FAILED]'
raise CreatorError("Unable to fetch initrd from %s" % self.__initrd_url)
print '[OK]'
else:
if self.__initrd_path:
src_initrd_path = self.__initrd_path
elif self._alt_initrd_name:
src_initrd_path = os.path.join(bootdir, self._alt_initrd_name)
elif version:
src_initrd_path = os.path.join(bootdir, "initrd-" + version + ".img")
else:
raise CreatorError("Unable to find valid initrd.img")
try:
shutil.copyfile(src_initrd_path, initrd_path)
except IOError, e:
raise CreatorError("Unable to copy boot files %s" % e)
""" Write required data to nand image to enable it bootable """
def __bootable_nandimg(self, cmdline, bootstub, vmlinuz, initrd):
# get the file size of vmlinuz and initrd
try:
vm_size = os.stat(vmlinuz)[stat.ST_SIZE]
rd_size = os.stat(initrd)[stat.ST_SIZE]
except IOError, e:
raise CreatorError("Cannot access files : %s or %s, %s" % (vmlinuz, initrd, e))
if not vm_size or not rd_size:
raise CreatorError("Invalid boot files : %s or %s, %s" % (vmlinuz, initrd))
# bootimg_size == bzimage_size + initrd_size + two 4096 block
bootimg_size = vm_size + rd_size + 4096 + 4096
MEGA = 1024 * 1024
bootimg_size = (bootimg_size + MEGA - 1) / MEGA #round to megas
# create bootimg file
imgpath = os.path.join(self._outdir, '%s-boot.bin' % self.name)
try:
imgfile = open(imgpath, 'wb')
except IOError, e:
raise CreatorError("Cannot create file : %s, %s" % (imgpath, e))
print 'Writing boot image file:'
try:
# add cmdline to the first part of boot image
imgfile.write(cmdline)
import struct
# fill vmlinuz and initrd size
imgfile.seek(256, 0)
imgfile.write(struct.pack('<i', vm_size))
imgfile.seek(260, 0)
imgfile.write(struct.pack('<i', rd_size))
print ' Writing cmdline and meta info ...... [OK]'
# append bootstub
imgfile.seek(4096, 0) # seek from beginning
imgfile.write(open(bootstub, 'rb').read())
print ' Writing bootstub file .............. [OK]'
# append vmlinuz and initrd
imgfile.seek(4096*2, 0) # seek from beginning
imgfile.write(open(vmlinuz, 'rb').read())
print ' Writing vmlinuz file ............... [OK]'
imgfile.write(open(initrd, 'rb').read())
print ' Writing initrd file ................ [OK]'
except IOError, e:
raise CreatorError("IO error: %s" % e)
finally:
imgfile.close()
os.remove(bootstub)
os.remove(vmlinuz)
os.remove(initrd)
#
# Actual implementation
#
def _create_mkinitrd_config(self):
#write to tell which modules to be included in initrd
mkinitrd = ""
mkinitrd += "PROBE=\"no\"\n"
mkinitrd += "MODULES+=\"ext3\"\n"
mkinitrd += "NANDLIVE+=\"yes\"\n"
mkinitrd += "rootfs=\"ext3\"\n"
mkinitrd += "rootopts=\"defaults\"\n"
logging.debug("Writing mkinitrd config %s/etc/sysconfig/mkinitrd" % self._instroot)
os.makedirs(self._instroot + "/etc/sysconfig/",mode=644)
cfg = open(self._instroot + "/etc/sysconfig/mkinitrd", "w")
cfg.write(mkinitrd)
cfg.close()
def _get_required_packages(self):
return ImageCreator._get_required_packages(self) + \
["bootstub"]
def _get_excluded_packages(self):
if self.__kernel_rpm_path or self.__kernel_rpm_url:
return ImageCreator._get_excluded_packages(self) + \
["kernel*"]
else:
return ImageCreator._get_excluded_packages(self)
def _get_local_packages(self):
rpm_path = os.path.join(self._outdir, 'kernel.rpm')
if self.__kernel_rpm_url:
print "Retrieving kernel rpm from %s ########### " % self.__kernel_rpm_url,
sys.stdout.flush()
rc = subprocess.call(["curl", "-s", "-o", rpm_path, self.__kernel_rpm_url])
if rc != 0 or not os.path.exists(rpm_path):
print '[FAILED]'
raise CreatorError("Unable to fetch kernel rpm from %s" % self.__kernel_rpm_url)
print '[OK]'
return ImageCreator._get_local_packages(self) + \
[rpm_path]
elif self.__kernel_rpm_path:
try:
shutil.copyfile(self.__kernel_rpm_path, rpm_path)
except IOError, e:
# failed to copy needed files
raise CreatorError("Unable to copy rpm files %s" % e)
return ImageCreator._get_local_packages(self) + \
[rpm_path]
else:
return ImageCreator._get_local_packages(self)
def _create_bootconfig(self):
if self.__kernel_path or self.__kernel_url:
return self.__copy_boot_files(None, "0")
# get the default kernel version
kernel_versions = self._get_kernel_versions()
kernel_ver = None
try:
kernel_ver = kernel_versions.values()[0][0]
except:
raise CreatorError("Unable to find valid kernel")
# copy boot related files from instroot to outdir
self.__copy_boot_files(kernel_ver, "0")
def install(self, repo_urls = {}):
if not self.__bootimg_only:
return ApplianceImageCreator.install(self, repo_urls)
yum_conf = self._mktemp(prefix = "yum.conf-")
self._required_pkgs = self._get_required_packages()
self._excluded_pkgs = self._get_excluded_packages()
keep_record = None
if self._include_src:
keep_record = 'include_src'
if self._recording_pkgs in ('name', 'content'):
keep_record = self._recording_pkgs
pkg_manager = self.get_pkg_manager(keep_record, target_arch = self.target_arch)
pkg_manager.setup(yum_conf, self._instroot)
for repo in kickstart.get_repos(self.ks, repo_urls):
(name, baseurl, mirrorlist, inc, exc, proxy, proxy_username, proxy_password, debuginfo, source, gpgkey, disable) = repo
yr = pkg_manager.addRepository(name, baseurl, mirrorlist, proxy, proxy_username, proxy_password)
if inc:
yr.includepkgs = inc
if exc:
yr.exclude = exc
rpm.addMacro("_excludedocs", "1")
rpm.addMacro("__file_context_path", "%{nil}")
try:
try:
pkg_manager.selectPackage('bootstub')
#if not (self.__initrd_path or self.__initrd_url):
# pkg_manager.selectPackage('initrd*')
if self.__kernel_rpm_path or self.__kernel_rpm_url:
# install local kernel rpm
for rpm_path in self._get_local_packages():
pkg_manager.installLocal(rpm_path)
elif self.__kernel_path or self.__kernel_url:
if not (self.__initrd_path or self.__initrd_url):
raise CreatorError("NO initrd.img specified")
else:
kernel_found = None
self._required_pkgs.append("kernel")
for pkg in self._required_pkgs:
if not pkg.startswith('kernel'):
continue
kernel_found = True
e = pkg_manager.selectPackage(pkg)
if e:
raise CreatorError("Failed to find package '%s' : %s" %
(pkg, e))
if not kernel_found:
raise CreatorError("NO kernel packages specified")
for pkg in self._excluded_pkgs:
pkg_manager.deselectPackage(pkg)
pkg_manager.runInstall()
except CreatorError, e:
raise CreatorError("%s" % (e,))
finally:
if keep_record:
self._pkgs_content = pkg_manager.getAllContent()
pkg_manager.closeRpmDB()
pkg_manager.close()
os.unlink(yum_conf)
def configure(self, repodata = None):
if not self.__bootimg_only:
# call root class
ImageCreator.configure(self, repodata)
# copy initrd to instroot
if (self.__initrd_url or self.__initrd_path) and self.__override_initrd:
initrd_path = os.path.join(self._outdir, "initrd0.img")
initrd_path_in_root = os.path.join(
os.path.join(self._instroot, "boot"), \
os.path.basename(self.__initrd_path or \
self.__initrd_url))
try:
shutil.copyfile(initrd_path, initrd_path_in_root)
except IOError:
raise CreatorError("Unable to copy initrd files to instroot")
else:
# if bootimg only, only call this
self._create_bootconfig()
""" Start to create boot image in _outdir """
# get the actual path of boot files
bootstub = self._outdir + "/bootstub"
vmlinuzs = glob.glob(self._outdir + "/vmlinuz*")
initrds = glob.glob(self._outdir + "/initrd*")
# cmdline to be written to image
# cmdline = "ro boot=usb single pci=noearly console=tty1 console=ttyMS0 earlyprintk=mrst loglevel=8 notsc "
# read boot cmdline from ks file
cmdline = self.ks.handler.bootloader.appendLine
self.__bootable_nandimg(cmdline, bootstub, vmlinuzs[0], initrds[0])
|