def prep_boot(kernel, initrd): # check for systems that need mdadm.conf if boot.need_mdadmconf(): log.info("appending /etc/mdadm.conf to initrd") boot.initramfs_append_files(initrd, "/etc/mdadm.conf") # look for updates, and add them to initrd if found updates = [] try: updates = list(listdir(update_img_dir)) except (IOError, OSError) as e: log.info("can't list update img dir %s: %s", update_img_dir, e.strerror) if updates: log.info("found updates in %s, appending to initrd", update_img_dir) boot.initramfs_append_images(initrd, updates) # make a dir in /lib/modules to hold a copy of the new kernel's modules # (the initramfs will copy/bind them into place when we reboot) kv = kernelver(kernel) if kv: moddir = os.path.join("/lib/modules", kv) log.info("creating module dir %s", moddir) mkdir_p(moddir) else: log.warn("can't determine version of kernel image '%s'", kernel) # set up the boot args modify_bootloader(kernel, initrd)
def save_repo_configs(): '''save repo configuration files for later use''' repodir = os.path.join(cachedir, 'yum.repos.d') mkdir_p(repodir) for repo in self.repos.listEnabled(): repofile = os.path.join(repodir, "%s.repo" % repo.id) try: repo.write(open(repofile), 'w') except IOError as e: log.warn("couldn't write repofile for %s: %s", repo.id, str(e))
def download_boot_images(self, arch=None): # helper function to grab and checksum image files listed in .treeinfo def grab_and_check(imgarch, imgtype, outpath): relpath = self.treeinfo.get_image(imgarch, imgtype) log.debug("grabbing %s %s", imgarch, imgtype) log.info("downloading %s to %s", relpath, outpath) if self.treeinfo.checkfile(outpath, relpath): log.debug("file already exists and checksum OK") return outpath def checkfile(cb): log.debug("checking %s", relpath) if not self.treeinfo.checkfile(cb.filename, relpath): log.info("checksum doesn't match - retrying") raise yum.URLGrabError(-1) return self.instrepo.grab.urlgrab(relpath, outpath, checkfunc=checkfile, reget=None, copy_local=True) # download the images try: if not arch: arch = self.treeinfo.get('general', 'arch') kernel = grab_and_check(arch, 'kernel', kernelpath) # cache the initrd somewhere so we don't have to fetch it again # if it gets modified later. cacheinitrd = os.path.join(cachedir, os.path.basename(initrdpath)) initrd = grab_and_check(arch, 'upgrade', cacheinitrd) # copy the downloaded initrd to the target path copy2(initrd, initrdpath) initrd = initrdpath except TreeinfoError as e: raise YumBaseError(_("invalid data in .treeinfo: %s") % str(e)) except yum.URLGrabError as e: err = e.strerror if e.errno == 256: err += "\n" + _("Last error was: %s") % e.errors[-1][1] raise YumBaseError(_("couldn't get boot images: %s") % err) except KeyboardInterrupt: # if an IOError occurs while writing the file to disk, F17 # urlgrabber actually raises *KeyboardInterrupt* for some reason. # But urlgrabber.__version__ hasn't been changed since F12, so: if not hasattr(yum.urlgrabber.grabber, 'exception2msg'): # <=F17 raise KeyboardInterrupt(_("or possible error writing file")) else: # The exception actually was a KeyBoardInterrupt, re-raise it raise # Save kernel/initrd info so we can clean it up later mkdir_p(os.path.dirname(upgradeconf)) with Config(upgradeconf) as conf: conf.set("boot", "kernel", kernel) conf.set("boot", "initrd", initrd) return kernel, initrd
def link_pkgs(pkgs): '''link the named pkgs into packagedir, overwriting existing files. also removes any .rpm files in packagedir that aren't in pkgs. finally, write a list of packages to upgrade and a list of dirs to clean up after successful upgrade.''' log.info("linking required packages into packagedir") log.info("packagedir = %s", packagedir) mkdir_p(packagedir) pkgbasenames = set() for pkg in pkgs: pkgpath = pkg.localPkg() if pkg.remote_url.startswith("file://"): pkgbasename = "media/%s" % pkg.relativepath pkgbasenames.add(pkgbasename) continue if not os.path.exists(pkgpath): log.warning("%s missing", pkgpath) continue pkgbasename = os.path.basename(pkgpath) pkgbasenames.add(pkgbasename) target = os.path.join(packagedir, pkgbasename) if os.path.exists(target) and os.lstat(pkgpath) == os.lstat(target): log.info("%s already in packagedir", pkgbasename) continue else: if os.path.isdir(target): log.info("deleting weirdo directory named %s", pkgbasename) rm_rf(target) elif os.path.exists(target): os.remove(target) try: os.link(pkgpath, target) except OSError as e: if e.errno == 18: copy2(pkgpath, target) else: raise # remove spurious / leftover RPMs for f in os.listdir(packagedir): if f.endswith(".rpm") and f not in pkgbasenames: os.remove(os.path.join(packagedir, f)) # write packagelist with open(packagelist, 'w') as outf: outf.writelines(p+'\n' for p in pkgbasenames) # write cleanup data with Config(upgradeconf) as conf: # packagedir should probably be last, since it contains upgradeconf cleanupdirs = [cachedir, packagedir] conf.set("cleanup", "dirs", ';'.join(cleanupdirs))
def setup_media_mount(mnt): # make a "media" subdir where all the packages are mountpath = os.path.join(upgradelink, "media") log.info("setting up mount for %s at %s", mnt.dev, mountpath) mkdir_p(mountpath) # make a directory to place a unit mkdir_p(upgrade_target_wants) # make a modified mnt entry that puts it at mountpath mediamnt = mnt._replace(rawmnt=mountpath) # finally, write out a systemd unit to mount media there unit = write_systemd_unit(mediamnt, upgrade_target_wants) log.info("wrote %s", unit)
def treeinfo(self): if self._treeinfo is None: mkdir_p(cachedir) outfile = os.path.join(cachedir, '.treeinfo') if self.cacheonly: log.debug("using cached .treeinfo %s", outfile) self._treeinfo = Treeinfo(outfile) else: log.debug("fetching .treeinfo from repo '%s'", self.instrepoid) if os.path.exists(outfile): os.remove(outfile) fn = self.instrepo.grab.urlgrab('.treeinfo', outfile, reget=None) self._treeinfo = Treeinfo(fn) log.debug(".treeinfo saved at %s", fn) self._treeinfo.checkvalues() return self._treeinfo
def download_boot_images(self, arch=None): # helper function to grab and checksum image files listed in .treeinfo def grab_and_check(imgarch, imgtype, outpath): relpath = self.treeinfo.get_image(imgarch, imgtype) log.debug("grabbing %s %s", imgarch, imgtype) log.info("downloading %s to %s", relpath, outpath) if self.treeinfo.checkfile(outpath, relpath): log.debug("file already exists and checksum OK") return outpath def checkfile(cb): log.debug("checking %s", relpath) if not self.treeinfo.checkfile(cb.filename, relpath): log.info("checksum doesn't match - retrying") raise yum.URLGrabError(-1) return self.instrepo.grab.urlgrab(relpath, outpath, checkfunc=checkfile, reget=None, copy_local=True) # download the images try: if not arch: arch = self.treeinfo.get('general', 'arch') kernel = grab_and_check(arch, 'kernel', kernelpath) initrd = grab_and_check(arch, 'upgrade', initrdpath) except TreeinfoError as e: raise YumBaseError(_("invalid data in .treeinfo: %s") % str(e)) except yum.URLGrabError as e: f = os.path.basename(self.failstate.lasturl) if e.errno >= 256: err = str(self.failstate.lastexc) else: err = str(e) raise YumBaseError(_("couldn't get %s:\n %s") % (f, err)) # Save kernel/initrd info so we can clean it up later mkdir_p(os.path.dirname(upgradeconf)) with Config(upgradeconf) as conf: conf.set("boot", "kernel", kernel) conf.set("boot", "initrd", initrd) return kernel, initrd