summaryrefslogtreecommitdiff
path: root/sys-boot/grub-handler
diff options
context:
space:
mode:
Diffstat (limited to 'sys-boot/grub-handler')
-rw-r--r--sys-boot/grub-handler/Manifest2
-rwxr-xr-xsys-boot/grub-handler/files/grub-handler318
-rw-r--r--sys-boot/grub-handler/grub-handler-0.2-r6.ebuild20
3 files changed, 340 insertions, 0 deletions
diff --git a/sys-boot/grub-handler/Manifest b/sys-boot/grub-handler/Manifest
new file mode 100644
index 00000000..4cff22db
--- /dev/null
+++ b/sys-boot/grub-handler/Manifest
@@ -0,0 +1,2 @@
+AUX grub-handler 10101 SHA256 f1290b49086310143cb36ec0a38bf8d43da18dcb9a3fab92947e299aafe677bb SHA512 55e2d5d8f1aa7459beb6349878f15632880c52ec60c82fd8f1c6e579203ed90da9af8de8d32c34a69eb58eb091428f8cbb9b74e61a07acf87102e8f5ecf829dc WHIRLPOOL 37d6ec7bdbc5f153101da651fa4a9dbaf8c998cb32cb3409092e323e35a97fa4973dc458e3243c39389964248c38191c9f52e7971d0037b49890be08bb0dc18d
+EBUILD grub-handler-0.2-r6.ebuild 356 SHA256 d941fc1113e2a685b9a9df4529ddade7945ec14e6f9b5750954697e64420c8b0 SHA512 30c95314c280a1e690f4a763b95559b7168cb7bef17fa9610def05686b080924d31975cad3562eebf1729b2a0d781bdaa9c537598f5903be9dd1733f18a94d0e WHIRLPOOL b789c86e87bd359def6da3e13ee6627ce55e96317219cdd65dd7169d0bd3ce3b20c336d8f16c186950e8bafa498a222854543c7fcf9770af59142139f0762e69
diff --git a/sys-boot/grub-handler/files/grub-handler b/sys-boot/grub-handler/files/grub-handler
new file mode 100755
index 00000000..4034ba1d
--- /dev/null
+++ b/sys-boot/grub-handler/files/grub-handler
@@ -0,0 +1,318 @@
+#!/usr/bin/python2
+# -*- coding: utf-8 -*-
+"""
+ Kernel grub.conf configuration script
+
+ Copyright (C) 2009 Fabio Erculiani
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+"""
+import os
+import sys
+import subprocess
+import shutil
+BOOT_MOUNT = False
+NO_SYS_ROOT_BOOT_DIR = "/boot"
+if os.path.ismount(NO_SYS_ROOT_BOOT_DIR):
+ BOOT_MOUNT = True
+SYS_ROOT = os.getenv("ROOT","")
+GRUB_CONF = SYS_ROOT+"/boot/grub/grub.conf"
+FSTAB_CONF = SYS_ROOT+"/etc/fstab"
+DISTRO_NAME = "Rogentos Linux"
+
+def getstatusoutput(cmd):
+ """Return (status, output) of executing cmd in a shell."""
+ pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
+ text = pipe.read()
+ sts = pipe.close()
+ if sts is None: sts = 0
+ if text[-1:] == '\n': text = text[:-1]
+ return sts, text
+
+def get_kernel_grub_line(kernel):
+ return "title=%s (%s)\n" % (DISTRO_NAME, os.path.basename(kernel),)
+
+def configure_boot_grub(kernel, initramfs):
+
+ grub_dir = os.path.dirname(GRUB_CONF)
+ if not os.path.isdir(grub_dir):
+ os.makedirs(grub_dir)
+
+ if os.access(GRUB_CONF, os.R_OK | os.F_OK):
+
+ # open in append
+ grub = open(GRUB_CONF,"aw")
+ shutil.copy2(GRUB_CONF, GRUB_CONF+".add")
+ # get boot dev
+ boot_dev = get_grub_boot_dev()
+ # test if entry has been already added
+ grubtest = open(GRUB_CONF,"r")
+ content = grubtest.readlines()
+ content = [unicode(x,'raw_unicode_escape') for x in content]
+ for line in content:
+
+ if line.find(get_kernel_grub_line(kernel)) != -1:
+ grubtest.close()
+ print "** Kernel already in configuration => ", line.strip()
+ return
+
+ # also check if we have the same kernel listed
+ if (line.find("kernel") != 1) and \
+ (line.find(os.path.basename(kernel)) != -1) and not \
+ line.strip().startswith("#") \
+ and (line.find("safe mode") == -1):
+
+ grubtest.close()
+ print "** Kernel already in configuration (2) => ", line.strip()
+ return
+ else:
+
+ # create
+ boot_dev = get_grub_boot_dev()
+ grub = open(GRUB_CONF,"w")
+ # write header - guess (hd0,0)... since it is weird
+ # having a running system without a bootloader, at least, grub.
+ grub.write("default=0\ntimeout=10\n")
+
+ cmdline = ''
+ if os.access("/proc/cmdline", os.R_OK):
+ cmdline_f = open("/proc/cmdline","r")
+ cmdline = " "+cmdline_f.readline().strip()
+ cmdline_f.close()
+
+ grub.write(get_kernel_grub_line(kernel))
+ grub.write("\troot "+boot_dev+"\n")
+ grub.write("\tkernel "+kernel+cmdline+"\n")
+ if initramfs:
+ grub.write("\tinitrd "+initramfs+"\n")
+ grub.write("\tsavedefault\n")
+ grub.write("\n")
+ grub.flush()
+ grub.close()
+
+def remove_boot_grub(kernel, initramfs):
+
+ grub_dir = os.path.dirname(GRUB_CONF)
+ if not os.path.isdir(grub_dir):
+ os.makedirs(grub_dir)
+
+ if os.path.isdir(grub_dir) and os.access(GRUB_CONF, os.R_OK | os.F_OK):
+
+ shutil.copy2(GRUB_CONF, GRUB_CONF+".remove")
+ grub_f = open(GRUB_CONF,"r")
+ grub_conf = grub_f.readlines()
+ grub_f.close()
+
+ content = [unicode(x,'raw_unicode_escape') for x in grub_conf]
+ if not isinstance(kernel, unicode):
+ kernel = unicode(kernel,'raw_unicode_escape')
+ if not isinstance(initramfs, unicode):
+ initramfs = unicode(initramfs,'raw_unicode_escape')
+
+ new_conf = []
+ skip = False
+ for line in content:
+
+ kernel_grub_line = get_kernel_grub_line(kernel)
+ if (line.find(kernel_grub_line) != -1):
+ skip = True
+ continue
+
+ if line.strip().startswith("title"):
+ skip = False
+
+ if not skip or line.strip().startswith("#"):
+ new_conf.append(line)
+
+ grub_tmp_f = open(GRUB_CONF+".tmp","w")
+ for line in new_conf:
+ try:
+ grub_tmp_f.write(line)
+ except UnicodeEncodeError:
+ grub_tmp_f.write(line.encode('utf-8'))
+ grub_tmp_f.flush()
+ grub_tmp_f.close()
+ os.rename(GRUB_CONF+".tmp", GRUB_CONF)
+
+def boot_device_translation(boot_dev):
+
+ # actually disabled due to buggy grub.conf entry
+ if os.access(GRUB_CONF, os.R_OK | os.F_OK) and 0:
+
+ f_grub = open(GRUB_CONF, "r")
+ stored_boot_dev = [x.strip() for x in f_grub.readlines() if \
+ x.strip().startswith("#boot=")]
+ f_grub.close()
+ if stored_boot_dev:
+ stored_boot_dev = stored_boot_dev[0]
+ boot_dev = "/dev/" + stored_boot_dev[len("#boot="):]
+
+ if boot_dev.startswith("/dev/md"):
+
+ boot_dev = os.path.realpath(boot_dev)
+ md_dev = os.path.basename(boot_dev)
+
+ if os.access("/proc/mdstat", os.R_OK | os.F_OK):
+
+ f_mdstat = open("/proc/mdstat","r")
+ stored_boot_dev = [x.split() for x in f_mdstat.readlines() if \
+ x.startswith(md_dev)]
+ f_mdstat.close()
+
+ if stored_boot_dev:
+ stored_boot_dev = stored_boot_dev[0]
+ for elem in stored_boot_dev:
+ if elem.endswith("[0]"):
+ boot_dev = "/dev/" + elem[:-len("[0]")]
+ break
+
+ return boot_dev
+
+def resolve_device(device):
+ if device.startswith("/dev/"):
+ return device
+ if device.startswith("UUID=") or device.startswith("LABEL="):
+ print "resolving UUID/LABEL to device", device
+ rc, outstring = getstatusoutput("blkid -lt %s" % (device,))
+ if rc != 0:
+ print "cannot resolve UUID/LABEL for", device
+ return None # argh!
+ device = outstring.split(":")[0]
+ print "UUID/LABEL resolved to", device
+ return device
+
+def get_grub_boot_dev():
+
+ grub_avail = subprocess.call("which grub &> /dev/null", shell = True)
+ if grub_avail != 0:
+ print "** Cannot find grub. Cannot properly configure kernel"
+ return "(hd0,0)"
+
+ # load currently mounted partitions
+ if not os.access(FSTAB_CONF, os.R_OK | os.F_OK):
+ print "** Cannot find %s. Cannot properly configure kernel" % (
+ FSTAB_CONF,)
+ return "(hd0,0)"
+
+ f_fstab = open(FSTAB_CONF, "r")
+ mount_data = [x.split() for x in f_fstab.readlines()]
+ f_fstab.close()
+ # filter out bogus devices
+ mount_data = [x for x in mount_data if x]
+ mount_data = [x for x in mount_data if x[0].startswith("/") or \
+ x[0].startswith("UUID=") or x[0].startswith('LABEL=')]
+
+ mount_hash = {}
+ for item in mount_data:
+ solved_dev = resolve_device(item[0])
+ if not solved_dev:
+ continue
+ mount_hash[item[1]] = solved_dev
+ boot_dev = mount_hash.get(NO_SYS_ROOT_BOOT_DIR, mount_hash.get("/"))
+ if boot_dev == None:
+ print "** Cannot determine boot device. Cannot properly configure" \
+ " kernel"
+ return "(hd0,0)"
+
+ # translate boot device, if needed
+ boot_dev = boot_device_translation(boot_dev)
+
+ # load grub map file
+ map_file = "grub.map"
+ subprocess.call('echo "quit" | grub --no-floppy --no-config-file ' \
+ '--no-curses --batch --device-map=grub.map &> /dev/null', shell = True)
+ if not os.access(map_file, os.R_OK | os.F_OK):
+ print "** Cannot find grub. Cannot properly configure kernel"
+ return "(hd0,0)"
+
+ f_map = open(map_file)
+ map_data = [x.split() for x in f_map.readlines()]
+ f_map.close()
+ os.remove(map_file)
+ map_data = dict(((y, x) for x, y in map_data))
+
+ map_data_devs = map_data.keys()
+ grub_dev = None
+ linux_dev = None
+ for dev in map_data_devs:
+ if boot_dev.startswith(dev):
+ grub_dev = map_data.get(dev)
+ linux_dev = dev
+ break
+
+ if grub_dev == None:
+ print "** Cannot match grub device. Cannot properly configure kernel"
+ return "(hd0,0)"
+
+ device_number = boot_dev.replace(linux_dev,'')
+ try:
+ device_number = int(device_number)
+ except ValueError:
+ print "** Cannot get device number for '%s' => '%s' | '%s'. Cannot properly configure kernel" % (
+ device_number, boot_dev, linux_dev,)
+ return "(hd0,0)"
+
+ device_number -= 1
+ grub_boot_dev = grub_dev.replace(')',',%s)' % (device_number,))
+ return grub_boot_dev
+
+def print_help():
+ print "%s %s %s %s" % (sys.argv[0], "[add/remove]",
+ "<kernel>", "<initramfs or 'none'>",)
+
+def add_kernel(kernel, initramfs):
+
+ boot_len = len(NO_SYS_ROOT_BOOT_DIR)
+ if BOOT_MOUNT:
+ kernel = kernel[boot_len:]
+ if initramfs:
+ initramfs = initramfs[boot_len:]
+
+ # configure GRUB
+ print "** Configuring GRUB bootloader. Adding the new kernel ..."
+ configure_boot_grub(kernel, initramfs)
+
+def remove_kernel(kernel, initramfs):
+
+ boot_len = len(NO_SYS_ROOT_BOOT_DIR)
+ if BOOT_MOUNT:
+ kernel = kernel[boot_len:]
+ if initramfs:
+ initramfs = initramfs[boot_len:]
+
+ # configure GRUB
+ print "** Configuring GRUB bootloader. Removing the selected kernel ..."
+ remove_boot_grub(kernel, initramfs)
+
+
+
+if __name__ == "__main__":
+
+ args = sys.argv[1:]
+ if len(args) < 3:
+ print_help()
+ raise SystemExit(1)
+
+ cmd = args[0]
+ if cmd not in ("add", "remove",):
+ print_help()
+ raise SystemExit(1)
+
+ kernel = args[1]
+ initramfs = args[2]
+
+ if initramfs == "none":
+ initramfs = ''
+
+ if cmd == "add":
+ print "** Adding kernel '%s' and initramfs '%s'" % (kernel, initramfs,)
+ add_kernel(kernel, initramfs)
+ elif cmd == "remove":
+ print "** Removing kernel '%s' and initramfs '%s'" % (kernel,
+ initramfs,)
+ remove_kernel(kernel, initramfs)
+ raise SystemExit(0)
diff --git a/sys-boot/grub-handler/grub-handler-0.2-r6.ebuild b/sys-boot/grub-handler/grub-handler-0.2-r6.ebuild
new file mode 100644
index 00000000..c2f4b31c
--- /dev/null
+++ b/sys-boot/grub-handler/grub-handler-0.2-r6.ebuild
@@ -0,0 +1,20 @@
+# Copyright 2009 Sabayon Linux
+# Distributed under the terms of the GNU General Public License v2
+
+inherit eutils
+
+DESCRIPTION="Rogentos Linux GRUB utilities"
+HOMEPAGE="http://www.rogentos.ro"
+SRC_URI=""
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86 amd64"
+IUSE=""
+
+RDEPEND=""
+DEPEND="${RDEPEND}"
+
+src_install () {
+ exeinto /usr/sbin
+ doexe "${FILESDIR}/${PN}"
+}