diff options
author | Martin Sivak <msivak@redhat.com> | 2012-08-10 16:03:15 +0200 |
---|---|---|
committer | Martin Sivak <msivak@redhat.com> | 2012-08-10 16:03:15 +0200 |
commit | 0afd1991954f61d3b0b5b5f57395ffa4f40a15df (patch) | |
tree | a7ab3e79e1f39af3ee64ae77eec10368a2d90226 | |
parent | c9bb72423159e122a099187f36f2a91e6c501732 (diff) | |
parent | d52a7424edaf79b5641f6645f2b446ba6691df4d (diff) | |
download | anaconda-0afd1991954f61d3b0b5b5f57395ffa4f40a15df.tar.gz anaconda-0afd1991954f61d3b0b5b5f57395ffa4f40a15df.tar.xz anaconda-0afd1991954f61d3b0b5b5f57395ffa4f40a15df.zip |
Merge remote-tracking branch 'origin/master' into newtui
32 files changed, 374 insertions, 674 deletions
diff --git a/.tx/config b/.tx/config index 6f70229f2..d42366d3e 100644 --- a/.tx/config +++ b/.tx/config @@ -1,4 +1,4 @@ -[anaconda.f17-branch] +[anaconda.master] file_filter = po/<lang>.po source_file = po/anaconda.pot source_lang = en @@ -221,6 +221,7 @@ def parseOptions(argv=None, cmdline=None): op.add_option("--kickstart", dest="ksfile") op.add_option("--rescue", dest="rescue", action="store_true", default=False) op.add_option("--targetarch", "rpmarch", dest="targetArch", type="string") + op.add_option("--armplatform", dest="armPlatform", type="string") op.add_option("-m", "--method", dest="method", default=None) op.add_option("--repo", dest="method", default=None) @@ -334,30 +335,6 @@ def expandFTPMethod(str): except: return None -def runVNC(vncS): - vncS.startServer() - - child = os.fork() - if child == 0: - for p in ('/tmp/updates/pyrc.py', \ - '/usr/share/anaconda/pyrc.py'): - if os.access(p, os.R_OK|os.X_OK): - os.environ['PYTHONSTARTUP'] = p - break - - while True: - # Not having a virtual terminal or otherwise free console - # are the only places we /really/ need a shell on tty1, - # and everywhere else this just gets in the way of pdb. But we - # don't want to return, because that'll return try to start X - # a second time. - if iutil.isConsoleOnVirtualTerminal() or iutil.isS390(): - time.sleep(10000) - else: - print _("Press <enter> for a shell") - sys.stdin.readline() - iutil.execConsole() - def gtk_warning(title, reason): import gtk dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR, @@ -581,7 +558,7 @@ def setupDisplay(anaconda, opts): # if they want us to use VNC do that now if anaconda.displayMode == 'g' and flags.usevnc: - runVNC(vncS) + vncS.startServer() doStartupX11Actions() # with X running we can initialize the UI interface @@ -714,6 +691,7 @@ if __name__ == "__main__": from pyanaconda import vnc from pyanaconda import kickstart from pyanaconda import ntp + from pyanaconda import keyboard verdesc = "%s for %s %s" % (getAnacondaVersion(), product.productName, product.productVersion) @@ -803,6 +781,9 @@ if __name__ == "__main__": if opts.targetArch: flags.targetarch = opts.targetArch + if opts.armPlatform: + flags.armPlatform = opts.armPlatform + # set flags flags.dmraid = opts.dmraid flags.mpath = opts.mpath @@ -864,6 +845,15 @@ if __name__ == "__main__": anaconda.ksdata = ksdata + # setup keyboard layout from the command line option and let + # it override from kickstart if/when X is initialized + if opts.keymap: + if not ksdata.keyboard.keyboard: + ksdata.keyboard.keyboard = opts.keymap + + if ksdata.keyboard.keyboard: + keyboard.activate_console_keymap(ksdata.keyboard.keyboard) + # Some post-install parts of anaconda are implemented as kickstart # scripts. Add those to the ksdata now. kickstart.appendPostScripts(ksdata) @@ -902,14 +892,6 @@ if __name__ == "__main__": ksdata.method.method = "url" ksdata.method.url = anaconda.methodstr - # setup keyboard layout from the command line option and let - # it override from kickstart if/when X is initialized - if opts.keymap: - if not ksdata.keyboard.keyboard: - ksdata.keyboard.keyboard = opts.keymap - anaconda.keyboard.set(opts.keymap) - anaconda.keyboard.activate() - # now start the interface setupDisplay(anaconda, opts) diff --git a/anaconda.spec.in b/anaconda.spec.in index 86fc57ea6..7deffe3ec 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -26,7 +26,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %define intltoolver 0.31.2-3 %define libnlver 1.0 %define libselinuxver 1.6 -%define pykickstartver 1.99.14 +%define pykickstartver 1.99.15 %define rpmpythonver 4.2-0.61 %define slangver 2.0.6-2 %define yumver 2.9.2 @@ -40,7 +40,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %define yumutilsver 1.1.11-3 %define iscsiver 6.2.0.870-3 %define pythoncryptsetupver 0.1.1 -%define mehver 0.13-1 +%define mehver 0.14-1 %define sckeyboardver 1.3.1 %define libblkidver 2.17.1-1 %define fcoeutilsver 1.0.12-3.20100323git @@ -89,7 +89,6 @@ BuildRequires: NetworkManager-devel >= %{nmver} BuildRequires: NetworkManager-glib-devel >= %{nmver} BuildRequires: dbus-devel >= %{dbusver} BuildRequires: dbus-python -BuildRequires: system-config-keyboard >= %{sckeyboardver} %ifarch %livearches BuildRequires: desktop-file-utils %endif @@ -130,7 +129,6 @@ Requires: python-cryptsetup >= %{pythoncryptsetupver} Requires: mdadm Requires: lvm2 Requires: util-linux >= 2.15.1 -Requires: system-config-keyboard >= %{sckeyboardver} Requires: dbus-python Requires: python-pwquality Requires: python-bugzilla diff --git a/data/interactive-defaults.ks b/data/interactive-defaults.ks index f692ccdc8..0046cc3f2 100644 --- a/data/interactive-defaults.ks +++ b/data/interactive-defaults.ks @@ -2,3 +2,4 @@ # This is not loaded if a kickstart file is provided on the command line. auth --enableshadow --passalgo=sha512 firstboot --enable +rootpw --lock diff --git a/data/tmux.conf b/data/tmux.conf index 3639fcbec..80620bad9 100644 --- a/data/tmux.conf +++ b/data/tmux.conf @@ -1,10 +1,10 @@ # tmux.conf for the anaconda environment set-option -s exit-unattached off set-option -g base-index 1 +set-option -g set-remain-on-exit on new-session -s anaconda -n main "anaconda" -set-option set-remain-on-exit on set-option status-right "" set-option status-right-length 0 diff --git a/pyanaconda/__init__.py b/pyanaconda/__init__.py index cf40ccd04..bcfcddc53 100644 --- a/pyanaconda/__init__.py +++ b/pyanaconda/__init__.py @@ -43,8 +43,7 @@ _ = lambda x: gettext.ldgettext("anaconda", x) class Anaconda(object): def __init__(self): - import desktop, firewall, security - import system_config_keyboard.keyboard as keyboard + import desktop, firewall from flags import flags self._backend = None @@ -60,7 +59,6 @@ class Anaconda(object): self._instLanguage = None self._intf = None self.isHeadless = False - self.keyboard = keyboard.Keyboard() self.ksdata = None self.mediaDevice = None self.methodstr = None @@ -75,7 +73,6 @@ class Anaconda(object): self.rescue = False self.rescue_mount = True self.rootParts = None - self.security = security.Security() self.simpleFilter = not iutil.isS390() self.stage2 = None self._storage = None @@ -274,5 +271,4 @@ class Anaconda(object): network.disableNMForStorageDevices(self.storage) network.autostartFCoEDevices(self.storage) self.desktop.write() - self.security.write() self.firewall.write() diff --git a/pyanaconda/flags.py b/pyanaconda/flags.py index f440c4b3b..e6d7a6747 100644 --- a/pyanaconda/flags.py +++ b/pyanaconda/flags.py @@ -58,6 +58,7 @@ class Flags(object): self.targetarch = None self.useIPv4 = True self.useIPv6 = True + self.armPlatform = None self.preexisting_x11 = False self.noverifyssl = False self.imageInstall = False diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 3ea3bd5ee..805a5c532 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -75,6 +75,7 @@ def doInstall(storage, payload, ksdata, instClass): # Now run the execute methods of ksdata that require an installed system # to be present first. ksdata.authconfig.execute(storage, ksdata, instClass) + ksdata.selinux.execute(storage, ksdata, instClass) ksdata.firstboot.execute(storage, ksdata, instClass) ksdata.services.execute(storage, ksdata, instClass) ksdata.keyboard.execute(storage, ksdata, instClass) diff --git a/pyanaconda/isys/__init__.py b/pyanaconda/isys/__init__.py index fc766fcf4..63edbf626 100755 --- a/pyanaconda/isys/__init__.py +++ b/pyanaconda/isys/__init__.py @@ -171,12 +171,6 @@ def swapoff (path): def swapon (path): return _isys.swapon (path) -## Load a keyboard layout for text mode installs. -# @param keymap The keyboard layout to load. This must be one of the values -# from rhpl.KeyboardModels. -def loadKeymap(keymap): - return _isys.loadKeymap (keymap) - def resetResolv(): return _isys.resetresolv() diff --git a/pyanaconda/isys/isys.c b/pyanaconda/isys/isys.c index 8c4eb4b9e..9b9046a17 100644 --- a/pyanaconda/isys/isys.c +++ b/pyanaconda/isys/isys.c @@ -92,7 +92,6 @@ static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args); static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args); static PyObject * doDevSpaceFree(PyObject * s, PyObject * args); static PyObject * doResetResolv(PyObject * s, PyObject * args); -static PyObject * doLoadKeymap(PyObject * s, PyObject * args); static PyObject * doExt2Dirty(PyObject * s, PyObject * args); static PyObject * doExt2HasJournal(PyObject * s, PyObject * args); static PyObject * doEjectCdrom(PyObject * s, PyObject * args); @@ -126,7 +125,6 @@ static PyMethodDef isysModuleMethods[] = { { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL }, { "swapon", (PyCFunction) doSwapon, METH_VARARGS, NULL }, { "swapoff", (PyCFunction) doSwapoff, METH_VARARGS, NULL }, - { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL }, { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL}, { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL}, { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL}, @@ -385,23 +383,6 @@ static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) { return PyLong_FromUnsignedLongLong(size>>20); } -static PyObject * doLoadKeymap (PyObject * s, PyObject * args) { - char * keymap; - int ret; - - if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL; - - ret = isysLoadKeymap (keymap); - if (ret) { - errno = -ret; - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - static PyObject * doExt2Dirty(PyObject * s, PyObject * args) { char * device; ext2_filsys fsys; diff --git a/pyanaconda/isys/lang.c b/pyanaconda/isys/lang.c index 07dee56ff..c38b1bb81 100644 --- a/pyanaconda/isys/lang.c +++ b/pyanaconda/isys/lang.c @@ -56,111 +56,3 @@ int isysSetUnicodeKeymap(void) { return 0; } -/* the file pointer must be at the beginning of the section already! */ -int loadKeymap(gzFile stream) { - int console; - int kmap, key; - struct kbentry entry; - int keymaps[MAX_NR_KEYMAPS]; - int count = 0; - unsigned int magic; - short keymap[NR_KEYS]; - struct stat sb; - -#if defined (__s390__) || defined (__s390x__) - return 0; -#endif - if (isVioConsole()) - return 0; - - /* assume that if we're already on a pty loading a keymap is silly */ - fstat(0, &sb); - if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) - return 0; - - if (gzread(stream, &magic, sizeof(magic)) != sizeof(magic)) - return -EIO; - - if (magic != KMAP_MAGIC) return -EINVAL; - - if (gzread(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) - return -EINVAL; - - console = open("/dev/tty0", O_RDWR); - if (console < 0) - return -EACCES; - - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - if (!keymaps[kmap]) continue; - - if (gzread(stream, keymap, sizeof(keymap)) != sizeof(keymap)) { - close(console); - return -EIO; - } - - count++; - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - entry.kb_value = keymap[key]; - if (KTYP(entry.kb_value) != KT_SPEC) { - if (ioctl(console, KDSKBENT, &entry)) { - int ret = errno; - close(console); - return ret; - } - } - } - } - close(console); - return 0; -} - -int isysLoadKeymap(char * keymap) { - int num = -1; - int rc; - gzFile f; - struct kmapHeader hdr; - struct kmapInfo * infoTable; - char buf[16384]; /* I hope this is big enough */ - int i; - - f = gzopen("/etc/keymaps.gz", "r"); - if (!f) return -EACCES; - - if (gzread(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { - gzclose(f); - return -EINVAL; - } - - i = hdr.numEntries * sizeof(*infoTable); - infoTable = alloca(i); - if (gzread(f, infoTable, i) != i) { - gzclose(f); - return -EIO; - } - - for (i = 0; i < hdr.numEntries; i++) - if (!strcmp(infoTable[i].name, keymap)) { - num = i; - break; - } - - if (num == -1) { - gzclose(f); - return -ENOENT; - } - - for (i = 0; i < num; i++) { - if (gzread(f, buf, infoTable[i].size) != infoTable[i].size) { - gzclose(f); - return -EIO; - } - } - - rc = loadKeymap(f); - - gzclose(f); - - return rc; -} diff --git a/pyanaconda/isys/lang.h b/pyanaconda/isys/lang.h index b5ff4da45..aac821aff 100644 --- a/pyanaconda/isys/lang.h +++ b/pyanaconda/isys/lang.h @@ -20,24 +20,6 @@ #ifndef ISYS_LANG_H #define ISYS_LANG_H -#include <zlib.h> - -/* define ask johnsonm@redhat.com where this came from */ -#define KMAP_MAGIC 0x8B39C07F -#define KMAP_NAMELEN 40 /* including '\0' */ - -struct kmapHeader { - int magic; - int numEntries; -}; - -struct kmapInfo { - int size; - char name[KMAP_NAMELEN]; -}; - -int loadKeymap(gzFile stream); -int isysLoadKeymap(char * keymap); int isysSetUnicodeKeymap(void); #endif diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py index 00fcb6ad7..fd0b98565 100644 --- a/pyanaconda/iutil.py +++ b/pyanaconda/iutil.py @@ -640,6 +640,23 @@ def getPPCMacBook(): return 1 return 0 +## Get the ARM processor variety. +# @return The ARM processor variety type, or 0 if not ARM. +def getARMMachine(): + if not isARM(): + return 0 + + if flags.armPlatform: + return flags.armPlatform + + armMachine = os.uname()[2].rpartition('.' )[2] + + if armMachine.startswith('arm'): + return None + else: + return armMachine + + cell = None ## Determine if the hardware is the Cell platform. # @return True if so, False otherwise. diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py index d0497d655..51f6d1b45 100755 --- a/pyanaconda/keyboard.py +++ b/pyanaconda/keyboard.py @@ -31,6 +31,11 @@ for listing and various modifications of keyboard layouts settings. """ import os +import re +from pyanaconda import iutil + +import logging +log = logging.getLogger("anaconda") class KeyboardConfigError(Exception): """Exception class for keyboard configuration related problems""" @@ -100,30 +105,80 @@ def get_layouts_xorg_conf(keyboard): def write_layouts_config(keyboard, root): """ - Function that writes a file with layouts configuration to - $root/etc/X11/xorg.conf.d/01-anaconda-layouts.conf + Function that writes files with layouts configuration to + $root/etc/X11/xorg.conf.d/01-anaconda-layouts.conf and + $root/etc/sysconfig/keyboard. @param keyboard: ksdata.keyboard object @param root: path to the root of the installed system """ - conf_dir = os.path.normpath(root + "/etc/X11/xorg.conf.d") - conf_file = "01-anaconda-keyboard.conf" + xconf_dir = os.path.normpath(root + "/etc/X11/xorg.conf.d") + xconf_file = "01-anaconda-keyboard.conf" + + sysconf_file = "/etc/sysconfig/keyboard" try: - if not os.path.isdir(conf_dir): - os.makedirs(conf_dir) + if not os.path.isdir(xconf_dir): + os.makedirs(xconf_dir) except OSError as oserr: raise KeyboardConfigError("Cannot create directory xorg.conf.d") try: - with open(os.path.join(conf_dir, conf_file), "w") as f: - f.write(get_layouts_xorg_conf(keyboard)) + with open(os.path.join(xconf_dir, xconf_file), "w") as fobj: + fobj.write(get_layouts_xorg_conf(keyboard)) + + with open(sysconf_file, "w") as fobj: + fobj.write('KEYTABLE="%s"\n' % keyboard.keyboard) except IOError as ioerr: - raise KeyboardConfigError("Cannot write keyboard configuration file") + raise KeyboardConfigError("Cannot write keyboard configuration files") + +def activate_console_keymap(keymap): + """ + Try to setup a given keymap as a console keymap. If there is no such + keymap, try to setup a basic variant (e.g. 'cz' instead of 'cz (qwerty)'). + + @param keymap: a keymap + @type keymap: string + @raise KeyboardConfigError: if loadkeys command is not available + @return: False if failed to activate both the given keymap and its basic + variant, True otherwise + + """ + + try: + #TODO: replace with calling systemd-localed methods once it can load + # X layouts + ret = iutil.execWithRedirect("loadkeys", [keymap], stdout="/dev/tty5", + stderr="/dev/tty5") + except OSError as oserr: + msg = "'loadkeys' command not available (%s)" % oserr.strerror + raise KeyboardConfigError(msg) + + if ret != 0: + log.error("Failed to activate keymap %s" % keymap) + + #failed to activate the given keymap, extract and try + #the basic keymap -- e.g. 'cz-cp1250' -> 'cz' + parts = re.split(r'[- _(]', keymap, 1) + if len(parts) == 0: + log.error("Failed to extract basic keymap from: %s" % keymap) + return False + + keymap = parts[0] + + ret = iutil.execWithRedirect("loadkeys", [keymap], stdout="/dev/tty5", + stderr="/dev/tty5") + + if ret != 0: + log.error("Failed to activate basic variant %s" % keymap) + else: + log.error("Activated basic variant %s, instead" % keymap) + + return ret == 0 def item_str(s): """Convert a zero-terminated byte array to a proper str""" diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index 7c3baa2c1..5c8c42c69 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -48,6 +48,7 @@ from storage.devices import * from scdate.core import zonetab from pyanaconda import keyboard from pyanaconda import ntp +from pyanaconda.simpleconfig import SimpleConfigFile from pykickstart.base import KickstartCommand from pykickstart.constants import * @@ -1212,11 +1213,29 @@ class RaidData(commands.raid.F15_RaidData): parents=request) storage.createDevice(luksdev) -class RootPw(commands.rootpw.F8_RootPw): +class RootPw(commands.rootpw.F18_RootPw): def execute(self, storage, ksdata, instClass, users): algo = users.getPassAlgo(ksdata.authconfig.authconfig) users.setRootPassword(self.password, self.isCrypted, self.lock, algo) +class SELinux(commands.selinux.FC3_SELinux): + def execute(self, *args): + selinux_states = { SELINUX_DISABLED: "disabled", + SELINUX_ENFORCING: "enforcing", + SELINUX_PERMISSIVE: "permissive" } + + if self.selinux not in selinux_states: + log.error("unknown selinux state: %s" % (self.selinux,)) + return + + try: + selinux_cfg = SimpleConfigFile(ROOT_PATH+"/etc/selinux/config") + selinux_cfg.read() + selinux_cfg.set(("SELINUX", selinux_states[self.selinux])) + selinux_cfg.write() + except IOError as msg: + log.error ("Error setting selinux mode: %s" % (msg,)) + class Services(commands.services.FC6_Services): def execute(self, storage, ksdata, instClass): disabled = map(lambda s: s + ".service", self.disabled) @@ -1362,6 +1381,7 @@ commandMap = { "partition": Partition, "raid": Raid, "rootpw": RootPw, + "selinux": SELinux, "services": Services, "timezone": Timezone, "user": User, diff --git a/pyanaconda/language.py b/pyanaconda/language.py index f1663d749..fb8d35e1c 100644 --- a/pyanaconda/language.py +++ b/pyanaconda/language.py @@ -28,7 +28,6 @@ import gettext from pyanaconda.constants import ROOT_PATH, DEFAULT_LANG import localeinfo from simpleconfig import SimpleConfigFile -import system_config_keyboard.keyboard as keyboard import logging log = logging.getLogger("anaconda") @@ -165,17 +164,6 @@ class Language(object): def getCurrentLangSearchList(self): return localeinfo.expandLangs(self.systemLang) + ['C'] - def getDefaultKeyboard(self): - try: - return self.localeInfo[self.systemLang][3] - except KeyError: - try: - kbd = keyboard.Keyboard() - kbd.read(ROOT_PATH) - return kbd.get() - except: - return self.localeInfo[self._default][3] - def getDefaultTimeZone(self): try: return self.localeInfo[self.systemLang][4] diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 22025ff51..0f38b5ee6 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -477,7 +477,7 @@ def waitForConnection(): # get a kernel cmdline string for dracut needed for access to storage host def dracutSetupArgs(networkStorageDevice): - if networkStorageDevice.nic == "default": + if networkStorageDevice.nic == "default" or ":" in networkStorageDevice.nic: nic = ifaceForHostIP(networkStorageDevice.host_address) if not nic: return "" @@ -885,7 +885,7 @@ def usedByRootOnISCSI(iface, storage): for d in storage.devices: if (isinstance(d, iScsiDiskDevice) and rootdev.dependsOn(d)): - if d.nic == "default": + if d.nic == "default" or ":" in d.nic: if iface == ifaceForHostIP(d.host_address): return True elif d.nic == iface: diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py index 8c5a5606c..4d56bfa31 100644 --- a/pyanaconda/packaging/__init__.py +++ b/pyanaconda/packaging/__init__.py @@ -600,9 +600,15 @@ class PackagePayload(Payload): def kernelPackages(self): from pyanaconda.isys import isPaeAvailable kernels = ["kernel"] + if isPaeAvailable(): kernels.insert(0, "kernel-PAE") + # most ARM systems use platform-specific kernels + if iutil.isARM(): + if anaconda.platform.armMachine is not None: + kernels = ["kernel-%s" % anaconda.platform.armMachine] + return kernels def payloadInitialize(storage, ksdata, payload): diff --git a/pyanaconda/platform.py b/pyanaconda/platform.py index 9abf0f57a..58cfa2dc4 100644 --- a/pyanaconda/platform.py +++ b/pyanaconda/platform.py @@ -337,6 +337,7 @@ class Sparc(Platform): return start+1 class ARM(Platform): + _armMachine = iutil.getARMMachine() _bootloaderClass = bootloader.GRUB2 _boot_stage1_device_types = ["disk"] _boot_mbr_description = N_("Master Boot Record") @@ -345,6 +346,10 @@ class ARM(Platform): _disklabel_types = ["msdos"] + @property + def armMachine(self): + return self._armMachine + def getPlatform(): """Check the architecture of the system and return an instance of a Platform subclass to match. If the architecture could not be determined, diff --git a/pyanaconda/security.py b/pyanaconda/security.py deleted file mode 100644 index 2e9532373..000000000 --- a/pyanaconda/security.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# security.py - security install data and installation -# -# Copyright (C) 2004 Red Hat, Inc. All rights reserved. -# -# 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. -# -# 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, see <http://www.gnu.org/licenses/>. -# -# Author(s): Jeremy Katz <katzj@redhat.com> -# - -import iutil -from flags import flags -from pyanaconda.constants import ROOT_PATH -from pykickstart.constants import * - -import logging -log = logging.getLogger("anaconda") - -selinux_states = { SELINUX_DISABLED: "disabled", - SELINUX_ENFORCING: "enforcing", - SELINUX_PERMISSIVE: "permissive" } - -class Security: - def __init__(self): - if flags.selinux == 1: - self.selinux = SELINUX_ENFORCING - else: - self.selinux = SELINUX_DISABLED - - def setSELinux(self, val): - if not selinux_states.has_key(val): - log.error("Tried to set to invalid SELinux state: %s" %(val,)) - val = SELINUX_DISABLED - - self.selinux = val - - def getSELinux(self): - return self.selinux - - def write(self): - args = [] - - if not selinux_states.has_key(self.selinux): - log.error("unknown selinux state: %s" %(self.selinux,)) - return - - try: - iutil.execWithRedirect("/usr/sbin/lokkit", args, - root=ROOT_PATH, stdout="/dev/null", - stderr="/dev/null") - except (RuntimeError, OSError) as msg: - log.error ("lokkit run failed: %s" %(msg,)) diff --git a/pyanaconda/simpleconfig.py b/pyanaconda/simpleconfig.py index 4bd665ac8..db0dea22a 100644 --- a/pyanaconda/simpleconfig.py +++ b/pyanaconda/simpleconfig.py @@ -3,8 +3,10 @@ # # Matt Wilson <msw@redhat.com> # Jeremy Katz <katzj@redhat.com> +# Will Woods <wwoods@redhat.com> +# Brian C. Lane <bcl@redhat.com> # -# Copyright 1999-2002 Red Hat, Inc. +# Copyright 1999-2012 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. @@ -13,81 +15,157 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # - -import string import os import shutil +import string +import shlex +from pipes import _safechars +import tempfile # use our own ASCII only uppercase function to avoid locale issues # not going to be fast but not important -def uppercase_ASCII_string(str): +def uppercase_ASCII_string(s): newstr = "" - for i in range(0,len(str)): - if str[i] in string.lowercase: - newstr += chr(ord(str[i])-32) - else: - newstr += str[i] - + for c in s: + if c in string.lowercase: + newstr += chr(ord(c)-32) + else: + newstr += c return newstr -class SimpleConfigFile: - def __str__ (self): - s = "" - keys = self.info.keys () - keys.sort () - for key in keys: - # FIXME - use proper escaping - if type (self.info[key]) == type(""): - s = s + key + "=\"" + self.info[key] + "\"\n" - return s +def unquote(s): + return ' '.join(shlex.split(s)) - def __init__ (self): +def quote(s, always=False): + """ If always is set it returns a quoted value + """ + if not always: + for c in s: + if c not in _safechars: + break + else: + return s + return '"'+s.replace('"', '\\"')+'"' + +class SimpleConfigFile(object): + """ Edit values in a configuration file without changing comments. + Supports KEY=VALUE lines and ignores everything else. + Supports adding new keys. + Supports deleting keys. + Preserves comment, blank lines and comments on KEY lines + Does not support duplicate key entries. + """ + def __init__(self, filename=None, read_unquote=True, write_quote=True, + always_quote=False): + self.filename = filename + self.read_unquote = read_unquote + self.write_quote = write_quote + self.always_quote = always_quote + self.reset() + + def reset(self): + self._lines = [] self.info = {} - def write(self, file): - f = open(file, "w") - f.write(self.__str__()) - f.close() - - def read(self, file): - if not os.access(file, os.R_OK): - return - - f = open(file, "r") - lines = f.readlines() - f.close() - - for line in lines: - fields = line[:-1].split('=', 2) - if len(fields) < 2: - # how am I supposed to know what to do here? - continue - key = uppercase_ASCII_string(fields[0]) - value = fields[1] - # XXX hack - value = value.replace('"', '') - value = value.replace("'", '') - self.info[key] = value - - def set (self, *args): - for (key, data) in args: - self.info[uppercase_ASCII_string(key)] = data - - def unset (self, *keys): - for key in keys: - key = uppercase_ASCII_string(key) - if self.info.has_key (key): + def read(self, filename=None): + """ passing filename will override the filename passed to init. + + save the lines into self._lines and the key/value pairs into + self.info + """ + filename = filename or self.filename + with open(filename) as f: + for line in f: + self._lines.append(line) + key, value = self._parseline(line) + if key: + self.info[key] = value + + def write(self, filename=None): + """ passing filename will override the filename passed to init. + """ + filename = filename or self.filename + if not filename: + return None + + tmpf = tempfile.NamedTemporaryFile(mode="w", delete=False) + tmpf.write(str(self)) + tmpf.close() + + # Move the temporary file (with 0600 permissions) over the top of the + # original and preserve the original's permissions + filename = os.path.realpath(filename) + m = os.stat(filename) + shutil.move(tmpf.name, filename) + os.chmod(filename, m.st_mode) + + def set(self, *args): + for key, value in args: + self.info[uppercase_ASCII_string(key)] = value + + def unset(self, *keys): + for key in [uppercase_ASCII_string(k) for k in keys]: + if key in self.info: del self.info[key] - def get (self, key): - key = uppercase_ASCII_string(key) - return self.info.get(key, "") + def get(self, key): + return self.info.get(uppercase_ASCII_string(key), "") + + def _parseline(self, line): + """ parse a line into a key, value pair + Handle comments and optionally unquote quoted strings + Returns (key, value) or (None, None) + key is always UPPERCASE + """ + s = line.strip() + if '#' in s: + s = s[:s.find('#')] # remove from comment to EOL + s = s.strip() # and any unnecessary whitespace + key, eq, val = s.partition('=') + if self.read_unquote: + val = unquote(val) + if key != '' and eq == '=': + return (uppercase_ASCII_string(key), val) + else: + return (None, None) + def _kvpair(self, key, comment=""): + value = self.info[key] + if self.write_quote or self.always_quote: + value = quote(value, self.always_quote) + return key + '=' + value + comment + "\n" + + def __str__(self): + """ Return the file that was read, replacing existing keys with new values + removing keys that have been deleted and adding new keys. + """ + oldkeys = [] + s = "" + for line in self._lines: + key, val = self._parseline(line) + if key is None: + s += line + else: + if key not in self.info: + continue + oldkeys.append(key) + if "#" in line: + comment = " " + line[line.find("#"):] + else: + comment = "" + s += self._kvpair(key, comment) + + # Add new keys + for key in self.info: + if key not in oldkeys: + s += self._kvpair(key) + + return s -class IfcfgFile(SimpleConfigFile): +class IfcfgFile(SimpleConfigFile): def __init__(self, dir, iface): - SimpleConfigFile.__init__(self) + SimpleConfigFile.__init__(self, always_quote=True) self.iface = iface self.dir = dir @@ -96,35 +174,21 @@ class IfcfgFile(SimpleConfigFile): return os.path.join(self.dir, "ifcfg-%s" % self.iface) def clear(self): - self.info = {} + SimpleConfigFile.reset(self) def read(self): - """Reads values from ifcfg file. + """ Reads values from ifcfg file. - returns: number of values read + returns: number of values read """ - f = open(self.path, "r") - lines = f.readlines() - f.close() - - for line in lines: - line = line.strip() - if line.startswith("#") or line == '': - continue - fields = line.split('=', 1) - key = uppercase_ASCII_string(fields[0]) - value = fields[1] - # XXX hack - value = value.replace('"', '') - value = value.replace("'", '') - self.info[key] = value - + SimpleConfigFile.read(self, self.path) return len(self.info) # ifcfg-rh is using inotify IN_CLOSE_WRITE event # so we don't use temporary file for new configuration. def write(self, dir=None): - """Writes values into ifcfg file.""" + """ Writes values into ifcfg file. + """ if not dir: path = self.path diff --git a/pyanaconda/ui/gui/TODO b/pyanaconda/ui/gui/TODO index f4170bf24..d0451443c 100644 --- a/pyanaconda/ui/gui/TODO +++ b/pyanaconda/ui/gui/TODO @@ -13,11 +13,6 @@ Fedora 18 where you go next. - The setting on the welcome screen does not get reflected on the language and keyboard spokes. - Something causes the up and down arrows to resize the anaconda window. -- Some interactive install defaults are different from kickstart (firstboot, ?). These need to - be loaded somewhere up front for an interactive install. -+ Update exception handling. This requires updating python-meh to use gtk3, - which also requires updating firstboot and s-c-ks to gtk3. I want to turn - s-c-ks into an anaconda wrapper first, though. - Wall of anaconda needs to be taken into account. - Why does the first hub jump left a little bit the first time you use the keyboard to navigate? - In custom storage, it'd be nice to be able to say something like "Use this diff --git a/pyanaconda/ui/gui/spokes/keyboard.glade b/pyanaconda/ui/gui/spokes/keyboard.glade index 1243e22fb..e0c08888f 100644 --- a/pyanaconda/ui/gui/spokes/keyboard.glade +++ b/pyanaconda/ui/gui/spokes/keyboard.glade @@ -25,6 +25,7 @@ <child> <object class="GtkButton" id="cancelButton"> <property name="label">gtk-cancel</property> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -41,6 +42,7 @@ <child> <object class="GtkButton" id="confirmAddButton"> <property name="label">gtk-add</property> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -192,8 +194,6 @@ <child internal-child="nav_area"> <object class="GtkGrid" id="AnacondaSpokeWindow-nav_area1"> <property name="can_focus">False</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> </object> <packing> <property name="expand">False</property> @@ -287,6 +287,7 @@ any layout to the top of the list to select it as the default.</property> <property name="layout_style">start</property> <child> <object class="GtkButton" id="addLayoutButton"> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -302,6 +303,7 @@ any layout to the top of the list to select it as the default.</property> </child> <child> <object class="GtkButton" id="removeLayoutButton"> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -317,6 +319,7 @@ any layout to the top of the list to select it as the default.</property> </child> <child> <object class="GtkButton" id="upButton"> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -332,6 +335,7 @@ any layout to the top of the list to select it as the default.</property> </child> <child> <object class="GtkButton" id="downButton"> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -347,6 +351,7 @@ any layout to the top of the list to select it as the default.</property> </child> <child> <object class="GtkButton" id="previewButton"> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -394,11 +399,18 @@ any layout to the top of the list to select it as the default.</property> </packing> </child> <child> - <object class="GtkEntry" id="layoutTestEntry"> + <object class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="height_request">100</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <property name="invisible_char_set">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTextView" id="layoutTextView"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="buffer">layoutTestBuffer</property> + </object> + </child> </object> <packing> <property name="expand">False</property> @@ -425,6 +437,7 @@ any layout to the top of the list to select it as the default.</property> <child> <object class="GtkButton" id="optionsButton"> <property name="label" translatable="yes">_Options...</property> + <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -465,6 +478,7 @@ any layout to the top of the list to select it as the default.</property> </object> </child> </object> + <object class="GtkTextBuffer" id="layoutTestBuffer"/> <object class="GtkListStore" id="newLayoutStore"> <columns> <!-- column-name name --> diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py index cbf340b91..0de562b02 100644 --- a/pyanaconda/ui/gui/spokes/keyboard.py +++ b/pyanaconda/ui/gui/spokes/keyboard.py @@ -138,6 +138,7 @@ class AddLayoutDialog(GUIObject): class KeyboardSpoke(NormalSpoke): builderObjects = ["addedLayoutStore", "keyboardWindow", + "layoutTestBuffer", "addImage", "removeImage", "upImage", "downImage", "previewImage"] mainWidgetName = "keyboardWindow" uiFile = "spokes/keyboard.glade" @@ -186,6 +187,11 @@ class KeyboardSpoke(NormalSpoke): def refresh(self): NormalSpoke.refresh(self) + # Clear out the layout testing box every time the spoke is loaded. It + # doesn't make sense to leave temporary data laying around. + buf = self.builder.get_object("layoutTestBuffer") + buf.set_text("") + # Clear and repopulate addedLayoutStore with values from self.data self._store.clear() self._add_data_layouts() diff --git a/pyanaconda/yuminstall.py b/pyanaconda/yuminstall.py index bb98b860c..ab4a469fb 100644 --- a/pyanaconda/yuminstall.py +++ b/pyanaconda/yuminstall.py @@ -1471,6 +1471,11 @@ reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anacon if selectKernel("kernel-PAE"): foundkernel = True + if not foundkernel and iutil.isARM(): + if anaconda.platform.armMachine is not None: + selectKernel("kernel-%s" % anaconda.platform.armMachine) + foundkernel = True + if not foundkernel: selectKernel("kernel") diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8ad951256..6204fd349 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -18,7 +18,7 @@ # Author: David Cantrell <dcantrell@redhat.com> scriptsdir = $(libexecdir)/$(PACKAGE_NAME) -dist_scripts_SCRIPTS = getkeymaps upd-updates +dist_scripts_SCRIPTS = upd-updates dist_scripts_DATA = pyrc.py dist_noinst_SCRIPTS = getlangnames.py upd-kernel makeupdates diff --git a/scripts/getkeymaps b/scripts/getkeymaps deleted file mode 100755 index 137ae5ee4..000000000 --- a/scripts/getkeymaps +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# -# getkeymaps -# -# Copyright (C) 2007 Red Hat, Inc. All rights reserved. -# -# 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. -# -# 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, see <http://www.gnu.org/licenses/>. -# - -ARCH=$1 -if [ -z "$ARCH" ]; then - echo "usage: $0 <arch>" - exit 1 -fi - -if [ "$ARCH" = "x86_64" -o "$ARCH" = "s390x" -o "$ARCH" = "ppc64" ]; then - LIBDIR=lib64 -else - LIBDIR=lib -fi - -TOPDIR=`pwd` -OUTPUT=$2 -if [ -z "$OUTPUT" ]; then - echo "No output specified, using ${TMPDIR:-/tmp}/keymaps-$ARCH.$$" - OUTPUT=${TMPDIR:-/tmp}/keymaps-$ARCH.$$ -fi - -UTILDIR=$3 -if [ -z "$UTILDIR" ]; then - READMAP=../utils/readmap - MAPSHDR=$TOPDIR/../utils/mapshdr -else - READMAP=$UTILDIR/usr/libexec/anaconda/readmap - MAPSHDR=$UTILDIR/usr/libexec/anaconda/mapshdr -fi - -TMP=${TMPDIR:-/tmp}/keymaps.$$ - -rm -rf $TMP -mkdir -p $TMP - -if [ $ARCH = "sparc" ]; then - PATTERN={i386,sun} -else - PATTERN=i386 -fi - -MAPS=$(python -c "import system_config_keyboard.keyboard_models ; system_config_keyboard.keyboard_models.get_supported_models()") - -for map in $MAPS ; do - eval find /lib/kbd/keymaps/$PATTERN -name "$map.map*.gz" | while read n; do - /bin/loadkeys `basename $n .gz` >/dev/null - $READMAP $TMP/`basename $n .map.gz`.map - done -done - -loadkeys us - -rm -f $TMP/defkeymap* $TMP/ANSI* $TMP/lt.map - -(cd $TMP; $MAPSHDR *.map) > $TMP/hdr -cat $TMP/hdr $TMP/*.map | gzip -9 > $OUTPUT -rm -rf $TMP diff --git a/tests/pyanaconda_test/language_test.py b/tests/pyanaconda_test/language_test.py index 5c895b298..2325a7340 100644 --- a/tests/pyanaconda_test/language_test.py +++ b/tests/pyanaconda_test/language_test.py @@ -142,26 +142,6 @@ class LanguageTest(mock.TestCase): ret = lang.getCurrentLangSearchList() self.assertEqual(set(ret), set(['cs_CZ.UTF-8', 'cs_CZ', 'cs', 'C'])) - def get_default_keyboard_default_test(self): - import pyanaconda.language - lang = pyanaconda.language.Language() - ret = lang.getDefaultKeyboard() - self.assertEqual(ret, 'us') - - def get_default_keyboard_after_set_test(self): - import pyanaconda.language - lang = pyanaconda.language.Language() - lang.systemLang = 'cs' - ret = lang.getDefaultKeyboard() - self.assertEqual(ret, 'cz-lat2') - - def get_default_keyboard_with_cs_CZ_locale_test(self): - import pyanaconda.language - pyanaconda.language.os.environ = {'LANG': 'cs'} - lang = pyanaconda.language.Language() - ret = lang.getDefaultKeyboard() - self.assertEqual(ret, 'cz-lat2') - def get_default_time_zone_default_test(self): import pyanaconda.language pyanaconda.language.os.path.exists = mock.Mock(return_value=False) diff --git a/tests/pyanaconda_test/simpleconfig_test.py b/tests/pyanaconda_test/simpleconfig_test.py index 467e993aa..265ed8879 100644 --- a/tests/pyanaconda_test/simpleconfig_test.py +++ b/tests/pyanaconda_test/simpleconfig_test.py @@ -6,26 +6,22 @@ import sys class SimpleconfigTest(mock.TestCase): def setUp(self): - self.setupModules(["_isys", "block", "ConfigParser"]) - self.fs = mock.DiskIO() + self.setupModules(["_isys", "block", "ConfigParser"]) import pyanaconda.simpleconfig - pyanaconda.simpleconfig.open = self.fs.open - pyanaconda.simpleconfig.os = mock.Mock() # Mock os module - pyanaconda.simpleconfig.os.path = os.path # except os.path part - + # Stuff for IfcfgFile class tests - self.DIR = '/etc/sysconfig/network-scripts/' + self.DIR = '/tmp/' self.IFACE = 'eth0' self.PATH = "%sifcfg-%s" % (self.DIR, self.IFACE) self.CONTENT = '# Broadcom Corporation NetXtreme BCM5761 Gigabit Ethernet\n' self.CONTENT += 'DEVICE=eth0\n' self.CONTENT += 'HWADDR=00:10:18:61:35:98\n' - self.CONTENT += 'ONBOOT=no\n' - self.fs.open(self.PATH, 'w').write(self.CONTENT) - + self.CONTENT += 'ONBOOT=no\n' + open(self.PATH, 'w').write(self.CONTENT) + def tearDown(self): self.tearDownModules() - + def uppercase_ascii_string_letters_test(self): """Converting to uppercase (letters)""" import pyanaconda.simpleconfig @@ -35,13 +31,13 @@ class SimpleconfigTest(mock.TestCase): self.assertEqual(ret, 'ABCD') ret = pyanaconda.simpleconfig.uppercase_ASCII_string('ABCD') self.assertEqual(ret, 'ABCD') - + def uppercase_ascii_string_numbers_test(self): """Converting to uppercase (numbers)""" import pyanaconda.simpleconfig ret = pyanaconda.simpleconfig.uppercase_ASCII_string('123') self.assertEqual(ret, '123') - + def uppercase_ascii_string_others_test(self): """Converting to uppercase (special chars)""" import pyanaconda.simpleconfig @@ -51,7 +47,19 @@ class SimpleconfigTest(mock.TestCase): self.assertEqual(ret, ' ') ret = pyanaconda.simpleconfig.uppercase_ASCII_string('') self.assertEqual(ret, '') - + + def unquote_test(self): + from pyanaconda.simpleconfig import unquote + self.assertEqual(unquote("plain string"), "plain string") + self.assertEqual(unquote('"double quote"'), "double quote") + self.assertEqual(unquote("'single quote'"), "single quote") + + def quote_test(self): + from pyanaconda.simpleconfig import quote + self.assertEqual(quote("nospaces"), "nospaces") + self.assertEqual(quote("plain string"), '"plain string"') + self.assertEqual(quote("alwaysquote", always=True), '"alwaysquote"') + def set_and_get_test(self): """Setting and getting values""" import pyanaconda.simpleconfig @@ -64,7 +72,7 @@ class SimpleconfigTest(mock.TestCase): self.assertEqual(scf.get('KEY3'), 'value3') scf.set(('key4', 'value4')) self.assertEqual(scf.get('KEY4'), 'value4') - + def unset_test(self): import pyanaconda.simpleconfig scf = pyanaconda.simpleconfig.SimpleConfigFile() @@ -77,23 +85,49 @@ class SimpleconfigTest(mock.TestCase): scf = pyanaconda.simpleconfig.SimpleConfigFile() scf.set(('key1', 'value1')) scf.write('/tmp/file') - self.assertEqual(self.fs['/tmp/file'], 'KEY1="value1"\n') - + self.assertEqual(open('/tmp/file').read(), 'KEY1=value1\n') + def read_test(self): import pyanaconda.simpleconfig scf = pyanaconda.simpleconfig.SimpleConfigFile() - self.fs.open('/tmp/file', 'w').write('KEY1="value1"\n') + open('/tmp/file', 'w').write('KEY1="value1"\n') scf.read('/tmp/file') self.assertEqual(scf.get('key1'), 'value1') - + + def read_write_test(self): + from pyanaconda.simpleconfig import SimpleConfigFile + scf = SimpleConfigFile() + scf.read(self.PATH) + scf.write("/tmp/file") + self.assertEqual(open("/tmp/file").read(), self.CONTENT) + + def write_new_keys_test(self): + from pyanaconda.simpleconfig import SimpleConfigFile + scf = SimpleConfigFile() + scf.read(self.PATH) + scf.set(("key1", "value1")) + scf.write("/tmp/file") + self.assertEqual(open("/tmp/file").read(), + self.CONTENT+"KEY1=value1\n") + + def remove_key_test(self): + from pyanaconda.simpleconfig import SimpleConfigFile + scf = SimpleConfigFile() + scf.read(self.PATH) + scf.unset("BOOT") + scf.write("/tmp/file") + scf.reset() + scf.read("/tmp/file") + self.assertEqual(scf.get("BOOT"), "") + def ifcfgfile_path_property_test(self): import pyanaconda.simpleconfig - scf = pyanaconda.simpleconfig.IfcfgFile(self.DIR, self.IFACE) - self.assertEqual(scf.path, self.PATH) - + scf = pyanaconda.simpleconfig.IfcfgFile(self.DIR, self.IFACE) + self.assertEqual(scf.path, self.PATH) + def ifcfgfile_read_test(self): - import pyanaconda.simpleconfig - scf = pyanaconda.simpleconfig.IfcfgFile(self.DIR, self.IFACE) + import pyanaconda.simpleconfig + scf = pyanaconda.simpleconfig.IfcfgFile(self.DIR, self.IFACE) scf.read() self.assertEqual(scf.get('device'), 'eth0') self.assertEqual(scf.get('hwaddr'), '00:10:18:61:35:98') @@ -107,7 +141,7 @@ class SimpleconfigTest(mock.TestCase): self.assertEqual(scf.get('device'), '') self.assertEqual(scf.get('hwaddr'), '') self.assertEqual(scf.get('onboot'), '') - + def ifcfgfile_write_test(self): import pyanaconda.simpleconfig scf = pyanaconda.simpleconfig.IfcfgFile(self.DIR, self.IFACE) @@ -115,6 +149,6 @@ class SimpleconfigTest(mock.TestCase): scf.set(('hwaddr', '00:11:22:33:44:55')) scf.set(('onboot', 'no')) scf.write() - self.assertEqual(self.fs[self.PATH], - 'DEVICE="eth0"\nHWADDR="00:11:22:33:44:55"\nONBOOT="no"\n') - + self.assertEqual(open(self.PATH).read(), + 'DEVICE="eth0"\nHWADDR="00:11:22:33:44:55"\nONBOOT="no"\n') + diff --git a/utils/Makefile.am b/utils/Makefile.am index 0a3a95366..9932a1580 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -22,6 +22,5 @@ SUBDIRS = log_picker utilsdir = $(libexecdir)/$(PACKAGE_NAME) dist_sbin_SCRIPTS = logpicker handle-sshpw -utils_PROGRAMS = mapshdr readmap MAINTAINERCLEANFILES = Makefile.in diff --git a/utils/mapshdr.c b/utils/mapshdr.c deleted file mode 100644 index ffba6b2f8..000000000 --- a/utils/mapshdr.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * mapshdr.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * 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. - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "../pyanaconda/isys/lang.h" - -int main(int argc, char ** argv) { - struct kmapHeader h; - struct kmapInfo info; - int i; - struct stat sb; - char * chptr; - - h.magic = KMAP_MAGIC; - h.numEntries = argc - 1; - write(1, &h, sizeof(h)); - - for (i = 1; i < argc; i++) { - if (stat(argv[i], &sb)) { - fprintf(stderr, "stat error for %s: %s\n", argv[i], - strerror(errno)); - exit(1); - } - - memset(info.name, 0, KMAP_NAMELEN); - strncpy(info.name, argv[i], KMAP_NAMELEN - 1); - - chptr = info.name + strlen(info.name) - 1; - while (*chptr != '.') *chptr-- = '\0'; - *chptr = '\0'; - - info.size = sb.st_size; - write(1, &info, sizeof(info)); - } - - return 0; -} diff --git a/utils/readmap.c b/utils/readmap.c deleted file mode 100644 index 035158cad..000000000 --- a/utils/readmap.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * readmap.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * 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. - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <errno.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/keyboard.h> -#ifdef NR_KEYS -#undef NR_KEYS -#define NR_KEYS 128 -#endif - -#include <linux/kd.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include "../pyanaconda/isys/lang.h" - -int main(int argc, char ** argv) { - int console; - int kmap, key; - struct kbentry entry; - int keymaps[MAX_NR_KEYMAPS]; - int count = 0; - int out; - short keymap[NR_KEYS]; - int magic = KMAP_MAGIC; - int verbose = 0; - - if (argc != 2) { - printf("bad usage\n"); - exit(1); - } - - if (getenv("DEBUG") != NULL) - verbose = 1; - - memset(keymaps, 0, sizeof(keymaps)); - - console = open("/dev/tty0", O_RDWR); - if (console < 0) { - perror("open VGA+KBD"); - exit(1); - } - - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - if (ioctl(console, KDGKBENT, &entry)) { - perror("ioctl failed"); - exit(1); - } else if (KTYP(entry.kb_value) != KT_SPEC) { - keymaps[kmap] = 1; - count++; - break; - } - } - } - - if (verbose) fprintf(stderr, "found %d valid keymaps\n", count); - - if (verbose) fprintf(stderr, "creating keymap file %s\n", argv[1]); - if ((out = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 1) { - perror("open keymap"); - exit(1); - } - - if (write(out, &magic, sizeof(magic)) != sizeof(magic)) { - perror("write magic"); - exit(1); - } - - if (write(out, keymaps, sizeof(keymaps)) != sizeof(keymaps)) { - perror("write header"); - exit(1); - } - - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - if (!keymaps[kmap]) continue; - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - if (ioctl(console, KDGKBENT, &entry)) { - perror("ioctl failed"); - exit(1); - } else { - keymap[key] = entry.kb_value; - } - } - - if (write(out, keymap, sizeof(keymap)) != sizeof(keymap)) { - perror("write keymap"); - exit(1); - } - } - - close(out); - - return 0; -} |