Beispiel #1
0
    def setup(self):
        util.mkdirChain(util.joinPaths(self.image_root, 'boot', 'grub'))
        # path to grub stage1/stage2 files in rPL/rLS
        util.copytree(
            util.joinPaths(self.image_root, 'usr', 'share', 'grub', '*', '*'),
            util.joinPaths(self.image_root, 'boot', 'grub'))
        # path to grub files in SLES
        if is_SUSE(self.image_root):
            util.copytree(
                util.joinPaths(self.image_root, 'usr', 'lib', 'grub', '*'),
                util.joinPaths(self.image_root, 'boot', 'grub'))
        if is_UBUNTU(self.image_root):
            # path to grub files in x86 Ubuntu
            util.copytree(
                util.joinPaths(self.image_root, 'usr', 'lib', 'grub', 'i386-pc', '*'),
                util.joinPaths(self.image_root, 'boot', 'grub'))
            # path to grub files in x86_64 Ubuntu
            util.copytree(
                util.joinPaths(self.image_root, 'usr', 'lib', 'grub', 'x86_64-pc', '*'),
                util.joinPaths(self.image_root, 'boot', 'grub'))
        util.mkdirChain(util.joinPaths(self.image_root, 'etc'))

        # Create a stub grub.conf
        self.writeConf()

        # Create the appropriate links
        if self._get_grub_conf() != 'menu.lst':
            os.symlink('grub.conf', util.joinPaths(
                self.image_root, 'boot', 'grub', 'menu.lst'))
            os.symlink('../boot/grub/grub.conf',
                       util.joinPaths(self.image_root, 'etc', 'grub.conf'))
        if is_SUSE(self.image_root):
            self._suse_grub_stub()
Beispiel #2
0
    def addScsiModules(self):
        # FIXME: this part of the code needs a rewrite, because any
        # bootable image type / distro combination may need different
        # drivers to be specified here.  It's not a simple True/False.
        # Also, 'Raw HD Image' means QEMU/KVM to me, but someone else
        # might be using it with another environment.
        filePath = self.filePath("etc/modprobe.conf")
        if self.jobData["buildType"] == buildtypes.AMI:
            moduleList = ["xenblk"]
        else:
            moduleList = ["mptbase", "mptspi"]

        if is_SUSE(self.root):
            filePath = filePath + ".local"
            if self.jobData["buildType"] == buildtypes.RAW_HD_IMAGE:
                self.scsiModules = True
                moduleList = ["piix"]

        if not self.scsiModules:
            return

        if not os.path.exists(filePath):
            log.warning("%s not found while adding scsi modules" % os.path.basename(filePath))

        util.mkdirChain(os.path.split(filePath)[0])
        f = open(filePath, "a")
        if os.stat(filePath)[6]:
            f.write("\n")
        for idx in range(0, len(moduleList)):
            f.write("alias scsi_hostadapter%s %s\n" % (idx and idx or "", moduleList[idx]))
        f.close()
Beispiel #3
0
 def _suse_sysconfig_bootloader(self):
     # write /etc/sysconfig/bootloader for SUSE systems
     contents = (
             'CYCLE_DETECTION="no"\n'
             'CYCLE_NEXT_ENTRY="1"\n'
             'LOADER_LOCATION=""\n'
             'LOADER_TYPE="grub"\n'
             )
     if is_SUSE(self.image_root, version=11):
         consoleArgs = ''
         if (self.jobData['buildType'] == buildtypes.validBuildTypes['XEN_OVA']):
             consoleArgs = ' console=ttyS0 xencons=ttyS'
         contents += (
             'DEFAULT_APPEND="root=LABEL=%s showopts%s"\n'
             'FAILSAFE_APPEND="root=LABEL=%s%s"\n' % (self.root_label,
                 consoleArgs, self.root_label, consoleArgs))
     self.createFile('etc/sysconfig/bootloader', contents)
Beispiel #4
0
 def add_kernels(self):
     bootDirFiles = os.listdir(util.joinPaths(self.image_root, 'boot'))
     kernels = sorted(x[8:] for x in bootDirFiles
             if x.startswith('vmlinuz-2.6'))
     initrds = sorted([x for x in bootDirFiles
         if re.match('init(rd|ramfs)-.*.img', x)])
     if initrds:
         # initrds are called initramfs on e.g. RHEL 6, stay consistent.
         rdPrefix = initrds[0].split('-')[0]
     else:
         rdPrefix = 'initrd'
     kernels.reverse()
     if kernels:
         log.info("Manually populating grub.conf with installed kernels")
         if is_SUSE(self.image_root):
             self._mkinitrd_suse(kernels)
         else:
             self.writeConf(kernels)
             irg = rh_initrd.RedhatGenerator(self.image_root)
             irg.generate([
                 (kver, '/boot/%s-%s.img' % (rdPrefix, kver))
                 for kver in kernels])
     else:
         log.error("No kernels found; this image will not be bootable.")
Beispiel #5
0
    def postTagScripts(self):
        # misc. stuff that needs to run after tag handlers have finished
        dhcp = self.filePath("etc/sysconfig/network/dhcp")
        if os.path.isfile(dhcp):
            # tell SUSE to set the hostname via DHCP
            cmd = r"""/bin/sed -e 's/DHCLIENT_SET_HOSTNAME=.*/DHCLIENT_SET_HOSTNAME="yes"/g' -i %s""" % dhcp
            logCall(cmd)

        logCall("rm -rf %s/var/lib/conarydb/rollbacks/*" % self.root)

        # set up shadow passwords/md5 passwords
        authConfigCmd = "chroot %s %%s --kickstart --enablemd5 --enableshadow" " --disablecache" % self.root
        if self.fileExists("/usr/sbin/authconfig"):
            logCall(authConfigCmd % "/usr/sbin/authconfig")
        elif self.fileExists("/usr/bin/authconfig"):
            logCall(authConfigCmd % "/usr/bin/authconfig")
        elif self.fileExists("/usr/sbin/pwconv"):
            logCall("chroot %s /usr/sbin/pwconv" % self.root)

        # allow empty password to log in for virtual appliance
        fn = self.filePath("etc/pam.d/common-auth")
        if os.path.exists(fn):
            f = open(fn)
            lines = []
            for line in f:
                line = line.strip()
                if "pam_unix2.so" in line and "nullok" not in line:
                    line += " nullok"
                lines.append(line)
            lines.append("")
            f = open(fn, "w")
            f.write("\n".join(lines))
            f.close()

        # Unlock the root account by blanking its password, unless a valid
        # password is already set.
        if self.fileExists("usr/sbin/usermod") and not hasRootPassword(self.root):
            log.info("Blanking root password.")
            logCall("chroot %s /usr/sbin/usermod -p '' root" % self.root, ignoreErrors=True)
        else:
            log.info("Not changing root password.")

        # Set up selinux autorelabel if appropriate
        selinux = self.filePath("etc/selinux/config")
        if os.path.exists(selinux):
            selinuxLines = [x.strip() for x in file(selinux).readlines()]
            if not "SELINUX=disabled" in selinuxLines:
                self.createFile(".autorelabel")

        # write an appropriate SLES inittab for XenServer
        # and update /etc/securetty so that logins work.
        if is_SUSE(self.root):
            if self.jobData["buildType"] == buildtypes.XEN_OVA:
                cmd = r"/bin/sed -e 's/^#cons:/cons:/' -e 's/^\([1-6]\):/#\1:/' -i %s" % self.filePath("/etc/inittab")
                logCall(cmd)
                cmd = r"echo -e 'console\nxvc0' >> %s" % self.filePath("/etc/securetty")
                logCall(cmd)
            elif self.jobData["buildType"] == buildtypes.AMI:
                cmd = r"/bin/sed -i 's/^#\(l4\)/\1/g' %s" % self.filePath("/etc/inittab")
                logCall(cmd)
                # This returns a non-zero exit code
                try:
                    if is_SUSE(self.root, version=10):
                        cmd = r"chroot %s /sbin/chkconfig --levels 2345 network on" % self.root
                    else:
                        cmd = r"chroot %s /sbin/chkconfig -s network 2345" % self.root
                    logCall(cmd)
                except:
                    pass

        # RedHat needs a config to tell it it's okay to upgrade the kernel
        if is_RH(self.root) and not self.fileExists("etc/sysconfig/kernel"):
            self.createFile("etc/sysconfig/kernel", "UPDATEDEFAULT=yes\n" "DEFAULTKERNEL=kernel\n")

        # Finish installation of bootloader
        if not self.fileExists("boot/boot"):
            # So /boot/blah in grub conf still works if /boot is separate
            os.symlink(".", self.filePath("boot/boot"))
        self.bootloader.install()
Beispiel #6
0
    def preTagScripts(self):
        fakeRoot = self.root
        # create a swap file
        if self.swapSize:
            swapFile = util.joinPaths(fakeRoot, self.swapPath)
            util.mkdirChain(os.path.dirname(swapFile))
            # sparse files cannot work for swap space
            logCall("dd if=/dev/zero of=%s bs=4096 count=%d" % (swapFile, self.swapSize / 4096))
            logCall("/sbin/mkswap %s" % swapFile)
            os.chmod(swapFile, 0600)

        # Copy a skeleton config tree.
        # Exclude things that are not being installed.
        exceptFiles = []

        # GPM (mouse daemon for virtual terminals)
        if not os.path.isfile(os.path.join(fakeRoot, "usr", "sbin", "gpm")):
            exceptFiles.append(os.path.join(os.path.sep, "etc", "sysconfig", "mouse"))

        # X windows
        start_x = False
        for svc in ("xdm", "gdm", "kdm"):
            if not os.path.isfile(os.path.join(fakeRoot, "etc", "init.d", svc)):
                continue
            # make sure the binary exists too
            for path in (("usr", "X11R6", "bin"), ("usr", "bin")):
                if os.path.isfile(os.path.join(*(fakeRoot,) + path + (svc,))):
                    start_x = True

        if not start_x:
            exceptFiles.append(os.path.join(os.path.sep, "etc", "X11.*"))

        # use the appropriate skeleton files depending on the OS base
        if is_SUSE(fakeRoot):
            skelDir = os.path.join(constants.skelDir, "sle")
        elif is_UBUNTU(fakeRoot):
            skelDir = os.path.join(constants.skelDir, "ubuntu")
        else:
            skelDir = os.path.join(constants.skelDir, "rpl")

        copytree(skelDir, fakeRoot, exceptFiles)

        self.writeConaryRc(os.path.join(fakeRoot, "etc", "conaryrc"), self.cc)
        self.writeSystemModel(os.path.join(fakeRoot, "etc", "conary", "system-model"))

        # If X is available, use runlevel 5 by default, for graphical login
        if start_x:
            inittab = os.path.join(fakeRoot, "etc", "inittab")
            if os.path.isfile(inittab):
                cmd = r"/bin/sed -e 's/^\(id\):[0-6]:\(initdefault:\)$/\1:5:\2/' -i %s" % inittab
                logCall(cmd)
            else:
                log.warning("inittab does not appear to be present")

        # copy timezone data into /etc/localtime
        if os.path.exists(os.path.join(fakeRoot, "usr", "share", "zoneinfo", "UTC")):
            copyfile(
                os.path.join(fakeRoot, "usr", "share", "zoneinfo", "UTC"), os.path.join(fakeRoot, "etc", "localtime")
            )

        # Write the /etc/sysconfig/appliance-name for distro-release initscript.
        # Only overwrite if the file is non existent or empty. (RBL-3104)
        appliancePath = os.path.join(fakeRoot, "etc", "sysconfig")
        if not os.path.exists(appliancePath):
            util.mkdirChain(appliancePath)

        appNameFile = os.path.join(appliancePath, "appliance-name")
        if not os.path.exists(appNameFile) or not os.path.getsize(appNameFile):
            f = open(appNameFile, "w")
            name = self.jobData["project"]["name"]
            if isinstance(name, unicode):
                name = name.encode("utf8")
            f.write(name + "\n")
            f.close()

        # Disable selinux by default
        selinux = "etc/selinux/config"
        if self.fileExists(selinux):
            contents = self.readFile(selinux)
            contents = contents.replace(
                "SELINUX=enforcing\n",
                "# NOTE: This is overridden by rBuilder. To prevent this, "
                "change it back using a group post-install script.\n"
                "SELINUX=disabled\n",
            )
            self.createFile(selinux, contents)

        if is_SUSE(self.root):
            # SUSE needs /dev/fd for mkinitrd (RBL-5689)
            os.symlink("/proc/self/fd", self.filePath("dev/fd"))
        elif is_SUSE(self.root, version=11):
            self.createFile("etc/sysconfig/mkinitrd", 'OPTIONS="-A"\n')

        # Configure the bootloader (but don't install it yet).
        self.bootloader.setup()

        self.addScsiModules()
        self.writeDeviceMaps()
Beispiel #7
0
    def _mkinitrd_suse(self, kernels):
        # Extend mkinitrd config with modules for VM targets
        kconf = self.filePath('etc/sysconfig/kernel')
        out = open(kconf + '.tmp', 'w')
        for line in open(kconf):
            if line[:15] == 'INITRD_MODULES=':
                modules = set(shlex.split(line[15:])[0].split())
                # Fix for SUP-3634 -- EC2 images not booting
                # ec2 images do not need extra modules specifically sd_ 
                # TODO -- revisit after all kernels are updated
                if self.jobData['buildType'] == buildtypes.AMI and is_SUSE(self.image_root, version=11):
                    modules.add('xenblk')
                else:
                    modules.add('piix')
                    modules.add('megaraid')
                    modules.add('mptscsih')
                    modules.add('mptspi')
                    modules.add('sd_mod')
                    if is_SUSE(self.image_root, version=11):
                        modules.add('pata_oldpiix')
                        modules.add('pata_mpiix')
                        modules.add('ata_piix')
                        modules.add('virtio_net')
                        modules.add('virtio_blk')
                        modules.add('virtio_pci')
                out.write('INITRD_MODULES="%s"' % (' '.join(modules)))
            else:
                out.write(line)
        out.close()
        os.rename(kconf + '.tmp', kconf)

        # Order kernels so the desired one is added last and thus the default.
        kernels.sort()
        kernels_xen = [x for x in kernels if x.endswith('-xen')]
        kernels_not_xen = [x for x in kernels if not x.endswith('-xen')]
        if self.force_domU:
            kernels = kernels_not_xen + kernels_xen
        else:
            kernels = kernels_xen + kernels_not_xen

        log.info("Rebuilding initrd(s)")
        kpaths = ['vmlinuz-' + x for x in kernels]
        ipaths = ['initrd-' + x for x in kernels]

        mkinitrdCmd = ['/usr/sbin/chroot', self.image_root,
            '/sbin/mkinitrd',
            '-k', ' '.join(kpaths),
            '-i', ' '.join(ipaths),
            ]

        # More SLES 11 magic: make a temporary device node
        # for the root fs device, and remove it after mkinitrd runs.
        if is_SUSE(self.image_root, version=11):
            if self.jobData['buildType'] == buildtypes.APPLIANCE_ISO:
                tmpRootDev = os.path.join(self.image_root, 'dev', 'root')
                mkinitrdCmd.extend([ '-d', '/dev/root' ])
            else:
                # Patch for card 2258
                # Need to make sure we use the correct loop device for mkinitrd
                proc_mount = '/proc/mounts'
                loop = os.path.join('dev', 'root')
                if os.path.exists(proc_mount):
                    mounts = open(proc_mount).readlines()
                    loops = sorted([ x.split() for x in mounts if
                                         x.startswith('/dev/loop') ])
                    if loops:
                        for l in loops:
                            if l[1] == self.image_root:
                                loop = l[0][1:]
                tmpRootDev = os.path.join(self.image_root, loop)
                mkinitrdCmd.extend([ '-d', loop ])
            os.mknod(tmpRootDev, 0600 | stat.S_IFBLK,
                     os.stat(self.image_root).st_dev)

        logCall(mkinitrdCmd)

        if is_SUSE(self.image_root, version=11):
            os.unlink(tmpRootDev)

        # Build grub config
        log.info("Adding kernel entries")
        self.createFile('boot/grub/menu.lst', contents="""\
# GRUB configuration generated by rBuilder
timeout 8
##YaST - generic_mbr
##YaST - activate

""")
        self.createFile('boot/grub/device.map', '(hd0) /dev/sda\n')
        self._suse_sysconfig_bootloader()
        self._suse_grub_stub()
        # for SLES 11
        os.environ['PBL_SKIP_BOOT_TEST'] = '1'
        for kver, kpath, ipath in zip(kernels, kpaths, ipaths):
            flavor = kpath.split('-')[-1]
            if flavor == 'xen' and self.force_domU:
                flavor = 'default'
            logCall(['/usr/sbin/chroot', self.image_root,
                '/usr/lib/bootloader/bootloader_entry',
                'add', flavor, kver, kpath, ipath])
Beispiel #8
0
    def install(self):
        cfgfile = self._get_grub_conf()
        grub_conf = util.joinPaths(self.image_root, 'boot/grub', cfgfile)
        # TODO: clean up the various paths by which mkinitrd gets run, this
        # workflow doesn't necessarily make sense.
        mkinitrdWasRun = False
        # RPM-based images will not populate grub.conf, so do it here.
        for line in open(grub_conf):
            line = line.split()
            if len(line) < 2 or 'vmlinuz-' not in line[1]:
                continue
            kver = os.path.basename(line[1])[8:]
            if kver != 'template':
                break
        else:
            # No non-template kernel entry was found, so populate it by hand.
            self.add_kernels()
            mkinitrdWasRun = True

        # Now that grubby has had a chance to add the new kernel,
        # remove the template entry added in setup()
        if os.path.exists(util.joinPaths(self.image_root, 'sbin', 'grubby')):
            logCall('chroot %s /sbin/grubby '
                    '--remove-kernel=/boot/vmlinuz-template' % self.image_root,
                    ignoreErrors=True)

        # If bootman is present, configure it for grub and run it
        if os.path.exists(util.joinPaths(self.image_root, 'sbin', 'bootman')):
            bootman_config = open(util.joinPaths(self.image_root, 'etc',
                'bootman.conf'), 'w')
            print >> bootman_config, 'BOOTLOADER=grub'
            bootman_config.close()

            bootloader.writeBootmanConfigs(self)
            logCall('chroot "%s" /sbin/bootman' % self.image_root)

            irg = rh_initrd.RedhatGenerator(self.image_root)
            irg.generateFromBootman()
            mkinitrdWasRun = True
        elif not mkinitrdWasRun and not is_SUSE(self.image_root):
            irg = rh_initrd.RedhatGenerator(self.image_root)
            irg.generateFromGrub(cfgfile)
            mkinitrdWasRun = True

        # Workaround for RPL-2423
        if os.path.exists(grub_conf):
            contents = open(grub_conf).read()
            contents = re.compile('^default .*', re.M
                ).sub('default 0', contents)
            open(grub_conf, 'w').write(contents)

        if cfgfile == 'menu.lst' and os.path.exists(grub_conf):
            # workaround for bootloader management tools in SUSE writing
            # menu.lst wrong
            f = open(grub_conf)
            newLines = []
            rootdev_re = re.compile('root=/dev/.*? ')
            grubroot_re = re.compile('root \(.*\)')
            doubleboot_re = re.compile('/boot/boot')
            kernel_re = re.compile('^\s+kernel')
            for line in f:
                line = rootdev_re.sub('root=LABEL=%s ' % self.root_label, line)
                if (self.jobData['buildType'] == buildtypes.validBuildTypes['AMI']):
                    line = grubroot_re.sub('root (hd0)', line)
                else:
                    line = grubroot_re.sub('root (hd0,0)', line)
                line = doubleboot_re.sub('/boot', line)
                if (kernel_re.match(line) and
                    (self.jobData['buildType'] == buildtypes.validBuildTypes['XEN_OVA'])):
                    line = line.replace('\n', ' console=ttyS0 xencons=ttyS\n')
                newLines.append(line)
            contents = ''.join(newLines)
            f = open(grub_conf, 'w')
            f.write(contents)
            f.close()
Beispiel #9
0
    def writeConf(self, kernels=()):
        if os.path.exists(util.joinPaths(self.image_root, 'etc', 'issue')):
            f = open(util.joinPaths(self.image_root, 'etc', 'issue'))
            name = f.readline().strip()
            if not name:
                name = self.jobData['project']['name']
            f.close()
        else:
            name = self.jobData['project']['name']
        bootDirFiles = os.listdir(util.joinPaths(self.image_root, 'boot'))
        xen = bool([x for x in bootDirFiles
            if re.match('vmlinuz-.*xen.*', x)])
        dom0 = bool([x for x in bootDirFiles
            if re.match('xen.gz-.*', x)])
        initrds = sorted([x for x in bootDirFiles
            if re.match('init(rd|ramfs)-.*.img', x)])
        hasInitrd = bool(initrds)

        # RH-alikes ship a combo dom0/domU kernel so we have to use the image
        # flavor to determine whether to use the dom0 bootloader configuration.
        if self.force_domU:
           dom0 = False

        clock = ""
        if self.jobData['buildType'] == buildtypes.VMWARE_IMAGE:
            if self.arch == 'x86':
                clock = "clock=pit"
            elif self.arch == 'x86_64':
                clock = "notsc"

        if self.jobData['buildType'] == buildtypes.AMI:
            ami = True
        else:
            ami = False
        if initrds:
            # initrds are called initramfs on e.g. RHEL 6, stay consistent.
            rdPrefix = initrds[0].split('-')[0]
        else:
            rdPrefix = 'initrd'

        grubConfMacros = None
        grubConfMacroPath = util.joinPaths(self.image_root, 'etc',
                'sysconfig', 'grubconfmacros')
        if os.path.exists(grubConfMacroPath):
            grubConfMacros = loadMacros([grubConfMacroPath, ])

        conf = getGrubConf(name, hasInitrd, xen, dom0, clock,
                includeTemplate=not is_SUSE(self.image_root, version=11),
                kversions=kernels, ami=ami, rdPrefix=rdPrefix,
                root_label=self.root_label, grubConfMacros=grubConfMacros,
                )

        cfgfile = self._get_grub_conf()
        if cfgfile == 'menu.lst' and is_SUSE(self.image_root):
            self._suse_sysconfig_bootloader()

        f = open(util.joinPaths(self.image_root, 'boot', 'grub', cfgfile), 'w')
        f.write(conf)
        f.close()

        os.chmod(util.joinPaths(self.image_root, 'boot', 'grub', cfgfile), 0600)
Beispiel #10
0
 def _get_grub_conf(self):
     if is_SUSE(self.image_root) or is_UBUNTU(self.image_root):
         return 'menu.lst'
     return 'grub.conf'